xref: /trunk/main/setup_native/source/win32/customactions/quickstarter/quickstarter.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 #include "quickstarter.hxx"
2 #ifdef _MSC_VER
3 #pragma warning(push, 1) /* disable warnings within system headers */
4 #endif
5 #include <psapi.h>
6 #ifdef _MSC_VER
7 #pragma warning(pop)
8 #endif
9 #include <tlhelp32.h>
10 #include <malloc.h>
11 
12 std::string GetOfficeInstallationPath(MSIHANDLE handle)
13 {
14     std::string progpath;
15     DWORD sz = 0;
16     LPTSTR dummy = TEXT("");
17 
18     if (MsiGetProperty(handle, TEXT("INSTALLLOCATION"), dummy, &sz) == ERROR_MORE_DATA)
19     {
20         sz++; // space for the final '\0'
21         DWORD nbytes = sz * sizeof(TCHAR);
22         LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
23         ZeroMemory(buff, nbytes);
24         MsiGetProperty(handle, TEXT("INSTALLLOCATION"), buff, &sz);
25         progpath = buff;
26     }
27     return progpath;
28 }
29 
30 std::string GetOfficeProductName(MSIHANDLE handle)
31 {
32     std::string productname;
33     DWORD sz = 0;
34     LPTSTR dummy = TEXT("");
35 
36     if (MsiGetProperty(handle, TEXT("ProductName"), dummy, &sz) == ERROR_MORE_DATA)
37     {
38         sz++; // space for the final '\0'
39         DWORD nbytes = sz * sizeof(TCHAR);
40         LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
41         ZeroMemory(buff, nbytes);
42         MsiGetProperty(handle, TEXT("ProductName"), buff, &sz);
43         productname = buff;
44     }
45     return productname;
46 }
47 
48 std::string GetQuickstarterLinkName(MSIHANDLE handle)
49 {
50     std::string quickstarterlinkname;
51     DWORD sz = 0;
52     LPTSTR dummy = TEXT("");
53 
54     if (MsiGetProperty(handle, TEXT("Quickstarterlinkname"), dummy, &sz) == ERROR_MORE_DATA)
55     {
56         sz++; // space for the final '\0'
57         DWORD nbytes = sz * sizeof(TCHAR);
58         LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
59         ZeroMemory(buff, nbytes);
60         MsiGetProperty(handle, TEXT("Quickstarterlinkname"), buff, &sz);
61         quickstarterlinkname = buff;
62     }
63     else if (MsiGetProperty(handle, TEXT("ProductName"), dummy, &sz) == ERROR_MORE_DATA)
64     {
65         sz++; // space for the final '\0'
66         DWORD nbytes = sz * sizeof(TCHAR);
67         LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
68         ZeroMemory(buff, nbytes);
69         MsiGetProperty(handle, TEXT("ProductName"), buff, &sz);
70         quickstarterlinkname = buff;
71     }
72     return quickstarterlinkname;
73 }
74 
75 inline bool IsValidHandle( HANDLE handle )
76 {
77     return NULL != handle && INVALID_HANDLE_VALUE != handle;
78 }
79 
80 
81 static HANDLE WINAPI _CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID )
82 {
83     typedef HANDLE (WINAPI *FN_PROC)( DWORD dwFlags, DWORD th32ProcessID );
84     static FN_PROC  lpProc = NULL;
85 
86     HANDLE  hSnapshot = NULL;
87 
88     if ( !lpProc )
89     {
90         HMODULE hLibrary = GetModuleHandle("KERNEL32.DLL");
91 
92         if ( hLibrary )
93             lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "CreateToolhelp32Snapshot" ));
94     }
95 
96     if ( lpProc )
97         hSnapshot = lpProc( dwFlags, th32ProcessID );
98 
99     return hSnapshot;
100 }
101 
102 static BOOL WINAPI _Process32First( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 )
103 {
104     typedef BOOL (WINAPI *FN_PROC)( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 );
105     static FN_PROC  lpProc = NULL;
106 
107     BOOL    fSuccess = FALSE;
108 
109     if ( !lpProc )
110     {
111         HMODULE hLibrary = GetModuleHandle("KERNEL32.DLL");
112 
113         if ( hLibrary )
114             lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "Process32First" ));
115     }
116 
117     if ( lpProc )
118         fSuccess = lpProc( hSnapshot, lppe32 );
119 
120     return fSuccess;
121 }
122 
123 static BOOL WINAPI _Process32Next( 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, "Process32Next" ));
136     }
137 
138     if ( lpProc )
139         fSuccess = lpProc( hSnapshot, lppe32 );
140 
141     return fSuccess;
142 }
143 
144 static std::string GetProcessImagePath_9x( DWORD dwProcessId )
145 {
146     std::string sImagePath;
147 
148     HANDLE  hSnapshot = _CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
149 
150     if ( IsValidHandle( hSnapshot ) )
151     {
152         PROCESSENTRY32  pe32 = { 0 };
153 
154         pe32.dwSize = sizeof(PROCESSENTRY32);
155 
156         BOOL    fSuccess = _Process32First( hSnapshot, &pe32 );
157         bool    found = false;
158 
159         while ( !found && fSuccess )
160         {
161             if ( pe32.th32ProcessID == dwProcessId )
162             {
163                 found = true;
164                 sImagePath = pe32.szExeFile;
165             }
166 
167             if ( !found )
168                 fSuccess = _Process32Next( hSnapshot, &pe32 );
169         }
170 
171         CloseHandle( hSnapshot );
172     }
173 
174     return sImagePath;
175 }
176 
177 static DWORD WINAPI _GetModuleFileNameExA( HANDLE hProcess, HMODULE hModule, LPSTR lpFileName, DWORD nSize )
178 {
179     typedef DWORD (WINAPI *FN_PROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpFileName, DWORD nSize );
180 
181     static FN_PROC  lpProc = NULL;
182 
183     if ( !lpProc )
184     {
185         HMODULE hLibrary = LoadLibrary("PSAPI.DLL");
186 
187         if ( hLibrary )
188             lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "GetModuleFileNameExA" ));
189     }
190 
191     if ( lpProc )
192         return lpProc( hProcess, hModule, lpFileName, nSize );
193 
194     return 0;
195 
196 }
197 
198 static std::string GetProcessImagePath_NT( DWORD dwProcessId )
199 {
200     std::string sImagePath;
201 
202     HANDLE  hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId );
203 
204     if ( IsValidHandle( hProcess ) )
205     {
206         CHAR    szPathBuffer[MAX_PATH] = "";
207 
208         if ( _GetModuleFileNameExA( hProcess, NULL, szPathBuffer, sizeof(szPathBuffer) ) )
209             sImagePath = szPathBuffer;
210 
211         CloseHandle( hProcess );
212     }
213 
214     return sImagePath;
215 }
216 
217 std::string GetProcessImagePath( DWORD dwProcessId )
218 {
219     return (LONG)GetVersion() < 0 ? GetProcessImagePath_9x( dwProcessId ) : GetProcessImagePath_NT( dwProcessId );
220 }
221 
222