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