| OLD | NEW |
| (Empty) |
| 1 // Copyright 2003-2010 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 #include "omaha/base/app_util.h" | |
| 17 #include <shlwapi.h> | |
| 18 #include <atlsecurity.h> | |
| 19 #include <vector> | |
| 20 #include "omaha/base/cgi.h" | |
| 21 #include "omaha/base/constants.h" | |
| 22 #include "omaha/base/debug.h" | |
| 23 #include "omaha/base/error.h" | |
| 24 #include "omaha/base/file.h" | |
| 25 #include "omaha/base/file_ver.h" | |
| 26 #include "omaha/base/logging.h" | |
| 27 #include "omaha/base/path.h" | |
| 28 #include "omaha/base/reg_key.h" | |
| 29 #include "omaha/base/string.h" | |
| 30 #include "omaha/base/utils.h" | |
| 31 | |
| 32 namespace omaha { | |
| 33 | |
| 34 namespace app_util { | |
| 35 | |
| 36 HMODULE GetModuleHandleFromAddress(void* address) { | |
| 37 MEMORY_BASIC_INFORMATION mbi = {0}; | |
| 38 DWORD result = ::VirtualQuery(address, &mbi, sizeof(mbi)); | |
| 39 ASSERT1(result == sizeof(mbi)); | |
| 40 return static_cast<HMODULE>(mbi.AllocationBase); | |
| 41 } | |
| 42 | |
| 43 HMODULE GetCurrentModuleHandle() { | |
| 44 return GetModuleHandleFromAddress(GetCurrentModuleHandle); | |
| 45 } | |
| 46 | |
| 47 | |
| 48 CString GetModulePath(HMODULE module_handle) { | |
| 49 ASSERT1(IsModuleHandleValid(module_handle)); | |
| 50 CString mod_path; | |
| 51 | |
| 52 DWORD result = ::GetModuleFileName(module_handle, | |
| 53 mod_path.GetBufferSetLength(MAX_PATH), | |
| 54 MAX_PATH); | |
| 55 mod_path.ReleaseBuffer(); | |
| 56 ASSERT1(result == static_cast<DWORD>(mod_path.GetLength())); | |
| 57 | |
| 58 return mod_path; | |
| 59 } | |
| 60 | |
| 61 CString GetModuleDirectory(HMODULE module_handle) { | |
| 62 ASSERT1(IsModuleHandleValid(module_handle)); | |
| 63 return GetDirectoryFromPath(GetModulePath(module_handle)); | |
| 64 } | |
| 65 | |
| 66 CString GetModuleName(HMODULE module_handle) { | |
| 67 ASSERT1(IsModuleHandleValid(module_handle)); | |
| 68 CString app_name(GetFileFromPath(GetModulePath(module_handle))); | |
| 69 | |
| 70 UTIL_LOG(L5, (_T("[GetModuleName][module 0x%08x][path '%s'][name '%s']"), | |
| 71 module_handle, GetModulePath(module_handle), app_name)); | |
| 72 | |
| 73 return app_name; | |
| 74 } | |
| 75 | |
| 76 CString GetModuleNameWithoutExtension(HMODULE module_handle) { | |
| 77 ASSERT1(IsModuleHandleValid(module_handle)); | |
| 78 CString module_name(GetPathRemoveExtension(GetModuleName(module_handle))); | |
| 79 | |
| 80 UTIL_LOG(L5, (_T("[GetModuleNameWithoutExtension]") | |
| 81 _T("[module 0x%08x][module '%s'][name '%s']"), | |
| 82 module_handle, GetModulePath(module_handle), module_name)); | |
| 83 | |
| 84 return module_name; | |
| 85 } | |
| 86 | |
| 87 CString GetCurrentModulePath() { | |
| 88 return GetModulePath(GetCurrentModuleHandle()); | |
| 89 } | |
| 90 | |
| 91 CString GetCurrentModuleDirectory() { | |
| 92 return GetModuleDirectory(GetCurrentModuleHandle()); | |
| 93 } | |
| 94 | |
| 95 CString GetCurrentModuleName() { | |
| 96 return GetModuleName(GetCurrentModuleHandle()); | |
| 97 } | |
| 98 | |
| 99 CString GetCurrentModuleNameWithoutExtension() { | |
| 100 return GetModuleNameWithoutExtension(GetCurrentModuleHandle()); | |
| 101 } | |
| 102 | |
| 103 bool IsAddressInCurrentModule(void* address) { | |
| 104 return GetCurrentModuleHandle() == GetModuleHandleFromAddress(address); | |
| 105 } | |
| 106 | |
| 107 CString GetHostName() { | |
| 108 CString hostName; | |
| 109 DWORD name_len = MAX_COMPUTERNAME_LENGTH + 1; | |
| 110 bool result = !!::GetComputerName(hostName.GetBufferSetLength(name_len), | |
| 111 &name_len); | |
| 112 ASSERT1(result); | |
| 113 hostName.ReleaseBuffer(); | |
| 114 ASSERT1(name_len == static_cast<DWORD>(hostName.GetLength())); | |
| 115 | |
| 116 return hostName; | |
| 117 } | |
| 118 | |
| 119 CString GetWindowsDir() { | |
| 120 CString windows_path; | |
| 121 | |
| 122 DWORD result = ::GetWindowsDirectory( | |
| 123 windows_path.GetBufferSetLength(MAX_PATH), MAX_PATH); | |
| 124 windows_path.ReleaseBuffer(); | |
| 125 ASSERT1(result == static_cast<DWORD>(windows_path.GetLength())); | |
| 126 | |
| 127 return windows_path; | |
| 128 } | |
| 129 | |
| 130 CString GetSystemDir() { | |
| 131 CString systemPath; | |
| 132 | |
| 133 DWORD result = ::GetSystemDirectory(systemPath.GetBufferSetLength(MAX_PATH), | |
| 134 MAX_PATH); | |
| 135 systemPath.ReleaseBuffer(); | |
| 136 ASSERT1(result == static_cast<DWORD>(systemPath.GetLength())); | |
| 137 | |
| 138 return systemPath; | |
| 139 } | |
| 140 | |
| 141 CString GetTempDir() { | |
| 142 CString tempPath; | |
| 143 | |
| 144 DWORD result = ::GetTempPath(MAX_PATH, tempPath.GetBufferSetLength(MAX_PATH)); | |
| 145 tempPath.ReleaseBuffer(); | |
| 146 ASSERT1(result == static_cast<DWORD>(tempPath.GetLength())); | |
| 147 | |
| 148 return tempPath; | |
| 149 } | |
| 150 | |
| 151 bool IsModuleHandleValid(HMODULE module_handle) { | |
| 152 if (!module_handle) { | |
| 153 return true; | |
| 154 } | |
| 155 return module_handle == GetModuleHandleFromAddress(module_handle); | |
| 156 } | |
| 157 | |
| 158 DWORD DllGetVersion(const CString& dll_path) { | |
| 159 HINSTANCE hInst = ::GetModuleHandle(dll_path); | |
| 160 ASSERT(hInst, | |
| 161 (_T("[GetModuleHandle failed][%s][%d]"), dll_path, ::GetLastError())); | |
| 162 DWORD dwVersion = 0; | |
| 163 DLLGETVERSIONPROC pfn = reinterpret_cast<DLLGETVERSIONPROC>( | |
| 164 ::GetProcAddress(hInst, "DllGetVersion")); | |
| 165 if (pfn != NULL) { | |
| 166 DLLVERSIONINFO dvi = {0}; | |
| 167 dvi.cbSize = sizeof(dvi); | |
| 168 HRESULT hr = (*pfn)(&dvi); | |
| 169 if (SUCCEEDED(hr)) { | |
| 170 // Since we're fitting both the major and minor versions into a DWORD, | |
| 171 // let's sanity check that we're not in an overflow situation here | |
| 172 ASSERT1(dvi.dwMajorVersion <= 0xFFFF); | |
| 173 ASSERT1(dvi.dwMinorVersion <= 0xFFFF); | |
| 174 dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); | |
| 175 } | |
| 176 } | |
| 177 return dwVersion; | |
| 178 } | |
| 179 | |
| 180 DWORD SystemDllGetVersion(const TCHAR* dll_name) { | |
| 181 ASSERT1(dll_name); | |
| 182 CString full_dll_path(String_MakeEndWith(GetSystemDir(), _T("\\"), false) + | |
| 183 dll_name); | |
| 184 ASSERT1(File::Exists(full_dll_path)); | |
| 185 return DllGetVersion(full_dll_path); | |
| 186 } | |
| 187 | |
| 188 ULONGLONG GetVersionFromModule(HMODULE instance) { | |
| 189 TCHAR module_path[MAX_PATH] = {0}; | |
| 190 if (!::GetModuleFileName(instance, module_path, MAX_PATH) != 0) { | |
| 191 return 0; | |
| 192 } | |
| 193 | |
| 194 return GetVersionFromFile(module_path); | |
| 195 } | |
| 196 | |
| 197 ULONGLONG GetVersionFromFile(const CString& file_path) { | |
| 198 FileVer existing_file_ver; | |
| 199 if (!existing_file_ver.Open(file_path)) { | |
| 200 return 0; | |
| 201 } | |
| 202 | |
| 203 return existing_file_ver.GetFileVersionAsULONGLONG(); | |
| 204 } | |
| 205 | |
| 206 // Returns a temporary dir for the impersonated user and an empty string if | |
| 207 // the user is not impersonated or an error occurs. | |
| 208 CString GetTempDirForImpersonatedUser() { | |
| 209 CAccessToken access_token; | |
| 210 if (!access_token.GetThreadToken(TOKEN_READ)) { | |
| 211 return NULL; | |
| 212 } | |
| 213 | |
| 214 CString temp_dir; | |
| 215 if (::ExpandEnvironmentStringsForUser(access_token.GetHandle(), | |
| 216 _T("%TMP%"), | |
| 217 CStrBuf(temp_dir, MAX_PATH), | |
| 218 MAX_PATH)) { | |
| 219 return temp_dir; | |
| 220 } | |
| 221 if (::ExpandEnvironmentStringsForUser(access_token.GetHandle(), | |
| 222 _T("%TEMP%"), | |
| 223 CStrBuf(temp_dir, MAX_PATH), | |
| 224 MAX_PATH)) { | |
| 225 return temp_dir; | |
| 226 } | |
| 227 | |
| 228 const int kCsIdl = CSIDL_LOCAL_APPDATA | CSIDL_FLAG_DONT_VERIFY; | |
| 229 if (SUCCEEDED(GetFolderPath(kCsIdl, &temp_dir)) && | |
| 230 ::PathAppend(CStrBuf(temp_dir, MAX_PATH), LOCAL_APPDATA_REL_TEMP_DIR)) { | |
| 231 return temp_dir; | |
| 232 } | |
| 233 | |
| 234 return NULL; | |
| 235 } | |
| 236 | |
| 237 | |
| 238 CString GetTempDirForImpersonatedOrCurrentUser() { | |
| 239 CString temp_dir_for_impersonated_user(GetTempDirForImpersonatedUser()); | |
| 240 if (!temp_dir_for_impersonated_user.IsEmpty()) { | |
| 241 CStrBuf string_buffer(temp_dir_for_impersonated_user, MAX_PATH); | |
| 242 if (::PathAddBackslash(string_buffer)) { | |
| 243 return temp_dir_for_impersonated_user; | |
| 244 } | |
| 245 } | |
| 246 return app_util::GetTempDir(); | |
| 247 } | |
| 248 | |
| 249 } // namespace app_util | |
| 250 | |
| 251 } // namespace omaha | |
| 252 | |
| OLD | NEW |