xref: /AOO41X/main/setup_native/source/win32/customactions/quickstarter/quickstarter.cxx (revision 32b1fd08cf0851da51c0ed68f50bc63c4ee660e0)
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