1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 #include "quickstarter.hxx" 23 #ifdef _MSC_VER 24 #pragma warning(push, 1) /* disable warnings within system headers */ 25 #endif 26 #include <psapi.h> 27 #ifdef _MSC_VER 28 #pragma warning(pop) 29 #endif 30 #include <tlhelp32.h> 31 #include <malloc.h> 32 33 std::string GetOfficeInstallationPath(MSIHANDLE handle) 34 { 35 std::string progpath; 36 DWORD sz = 0; 37 LPTSTR dummy = TEXT(""); 38 39 if (MsiGetProperty(handle, TEXT("INSTALLLOCATION"), dummy, &sz) == ERROR_MORE_DATA) 40 { 41 sz++; // space for the final '\0' 42 DWORD nbytes = sz * sizeof(TCHAR); 43 LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes)); 44 ZeroMemory(buff, nbytes); 45 MsiGetProperty(handle, TEXT("INSTALLLOCATION"), buff, &sz); 46 progpath = buff; 47 } 48 return progpath; 49 } 50 51 std::string GetOfficeProductName(MSIHANDLE handle) 52 { 53 std::string productname; 54 DWORD sz = 0; 55 LPTSTR dummy = TEXT(""); 56 57 if (MsiGetProperty(handle, TEXT("ProductName"), dummy, &sz) == ERROR_MORE_DATA) 58 { 59 sz++; // space for the final '\0' 60 DWORD nbytes = sz * sizeof(TCHAR); 61 LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes)); 62 ZeroMemory(buff, nbytes); 63 MsiGetProperty(handle, TEXT("ProductName"), buff, &sz); 64 productname = buff; 65 } 66 return productname; 67 } 68 69 std::string GetQuickstarterLinkName(MSIHANDLE handle) 70 { 71 std::string quickstarterlinkname; 72 DWORD sz = 0; 73 LPTSTR dummy = TEXT(""); 74 75 if (MsiGetProperty(handle, TEXT("Quickstarterlinkname"), dummy, &sz) == ERROR_MORE_DATA) 76 { 77 sz++; // space for the final '\0' 78 DWORD nbytes = sz * sizeof(TCHAR); 79 LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes)); 80 ZeroMemory(buff, nbytes); 81 MsiGetProperty(handle, TEXT("Quickstarterlinkname"), buff, &sz); 82 quickstarterlinkname = buff; 83 } 84 else if (MsiGetProperty(handle, TEXT("ProductName"), dummy, &sz) == ERROR_MORE_DATA) 85 { 86 sz++; // space for the final '\0' 87 DWORD nbytes = sz * sizeof(TCHAR); 88 LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes)); 89 ZeroMemory(buff, nbytes); 90 MsiGetProperty(handle, TEXT("ProductName"), buff, &sz); 91 quickstarterlinkname = buff; 92 } 93 return quickstarterlinkname; 94 } 95 96 inline bool IsValidHandle( HANDLE handle ) 97 { 98 return NULL != handle && INVALID_HANDLE_VALUE != handle; 99 } 100 101 102 static HANDLE WINAPI _CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID ) 103 { 104 typedef HANDLE (WINAPI *FN_PROC)( DWORD dwFlags, DWORD th32ProcessID ); 105 static FN_PROC lpProc = NULL; 106 107 HANDLE hSnapshot = NULL; 108 109 if ( !lpProc ) 110 { 111 HMODULE hLibrary = GetModuleHandle("KERNEL32.DLL"); 112 113 if ( hLibrary ) 114 lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "CreateToolhelp32Snapshot" )); 115 } 116 117 if ( lpProc ) 118 hSnapshot = lpProc( dwFlags, th32ProcessID ); 119 120 return hSnapshot; 121 } 122 123 static BOOL WINAPI _Process32First( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 ) 124 { 125 typedef BOOL (WINAPI *FN_PROC)( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 ); 126 static FN_PROC lpProc = NULL; 127 128 BOOL fSuccess = FALSE; 129 130 if ( !lpProc ) 131 { 132 HMODULE hLibrary = GetModuleHandle("KERNEL32.DLL"); 133 134 if ( hLibrary ) 135 lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "Process32First" )); 136 } 137 138 if ( lpProc ) 139 fSuccess = lpProc( hSnapshot, lppe32 ); 140 141 return fSuccess; 142 } 143 144 static BOOL WINAPI _Process32Next( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 ) 145 { 146 typedef BOOL (WINAPI *FN_PROC)( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 ); 147 static FN_PROC lpProc = NULL; 148 149 BOOL fSuccess = FALSE; 150 151 if ( !lpProc ) 152 { 153 HMODULE hLibrary = GetModuleHandle("KERNEL32.DLL"); 154 155 if ( hLibrary ) 156 lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "Process32Next" )); 157 } 158 159 if ( lpProc ) 160 fSuccess = lpProc( hSnapshot, lppe32 ); 161 162 return fSuccess; 163 } 164 165 static std::string GetProcessImagePath_9x( DWORD dwProcessId ) 166 { 167 std::string sImagePath; 168 169 HANDLE hSnapshot = _CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); 170 171 if ( IsValidHandle( hSnapshot ) ) 172 { 173 PROCESSENTRY32 pe32 = { 0 }; 174 175 pe32.dwSize = sizeof(PROCESSENTRY32); 176 177 BOOL fSuccess = _Process32First( hSnapshot, &pe32 ); 178 bool found = false; 179 180 while ( !found && fSuccess ) 181 { 182 if ( pe32.th32ProcessID == dwProcessId ) 183 { 184 found = true; 185 sImagePath = pe32.szExeFile; 186 } 187 188 if ( !found ) 189 fSuccess = _Process32Next( hSnapshot, &pe32 ); 190 } 191 192 CloseHandle( hSnapshot ); 193 } 194 195 return sImagePath; 196 } 197 198 static DWORD WINAPI _GetModuleFileNameExA( HANDLE hProcess, HMODULE hModule, LPSTR lpFileName, DWORD nSize ) 199 { 200 typedef DWORD (WINAPI *FN_PROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpFileName, DWORD nSize ); 201 202 static FN_PROC lpProc = NULL; 203 204 if ( !lpProc ) 205 { 206 HMODULE hLibrary = LoadLibrary("PSAPI.DLL"); 207 208 if ( hLibrary ) 209 lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "GetModuleFileNameExA" )); 210 } 211 212 if ( lpProc ) 213 return lpProc( hProcess, hModule, lpFileName, nSize ); 214 215 return 0; 216 217 } 218 219 static std::string GetProcessImagePath_NT( DWORD dwProcessId ) 220 { 221 std::string sImagePath; 222 223 HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId ); 224 225 if ( IsValidHandle( hProcess ) ) 226 { 227 CHAR szPathBuffer[MAX_PATH] = ""; 228 229 if ( _GetModuleFileNameExA( hProcess, NULL, szPathBuffer, sizeof(szPathBuffer) ) ) 230 sImagePath = szPathBuffer; 231 232 CloseHandle( hProcess ); 233 } 234 235 return sImagePath; 236 } 237 238 std::string GetProcessImagePath( DWORD dwProcessId ) 239 { 240 return (LONG)GetVersion() < 0 ? GetProcessImagePath_9x( dwProcessId ) : GetProcessImagePath_NT( dwProcessId ); 241 } 242 243