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