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
GetOfficeInstallationPath(MSIHANDLE handle)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
GetOfficeProductName(MSIHANDLE handle)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
GetQuickstarterLinkName(MSIHANDLE handle)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
IsValidHandle(HANDLE handle)96 inline bool IsValidHandle( HANDLE handle )
97 {
98 return NULL != handle && INVALID_HANDLE_VALUE != handle;
99 }
100
101
_CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID)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
_Process32First(HANDLE hSnapshot,PROCESSENTRY32 * lppe32)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
_Process32Next(HANDLE hSnapshot,PROCESSENTRY32 * lppe32)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
GetProcessImagePath_9x(DWORD dwProcessId)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
_GetModuleFileNameExA(HANDLE hProcess,HMODULE hModule,LPSTR lpFileName,DWORD nSize)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
GetProcessImagePath_NT(DWORD dwProcessId)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
GetProcessImagePath(DWORD dwProcessId)238 std::string GetProcessImagePath( DWORD dwProcessId )
239 {
240 return (LONG)GetVersion() < 0 ? GetProcessImagePath_9x( dwProcessId ) : GetProcessImagePath_NT( dwProcessId );
241 }
242
243