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
23
24 #define _WIN32_WINDOWS 0x0410
25 #ifdef _MSC_VER
26 #pragma warning(push, 1) /* disable warnings within system headers */
27 #endif
28 #define WIN32_LEAN_AND_MEAN
29 #include <windows.h>
30 #include <msiquery.h>
31 #ifdef _MSC_VER
32 #pragma warning(pop)
33 #endif
34
35 #include <malloc.h>
36
37 #ifdef UNICODE
38 #define _UNICODE
39 #define _tstring wstring
40 #else
41 #define _tstring string
42 #endif
43 #include <tchar.h>
44 #include <string>
45
46 #include <io.h>
47
GetMsiProperty(MSIHANDLE handle,const std::_tstring & sProperty)48 static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
49 {
50 std::_tstring result;
51 TCHAR szDummy[1] = TEXT("");
52 DWORD nChars = 0;
53
54 if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
55 {
56 DWORD nBytes = ++nChars * sizeof(TCHAR);
57 LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
58 ZeroMemory( buffer, nBytes );
59 MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
60 result = buffer;
61 }
62
63 return result;
64 }
65
66
ExecuteCommand(LPCTSTR lpCommand,BOOL bSync)67 static BOOL ExecuteCommand( LPCTSTR lpCommand, BOOL bSync )
68 {
69 BOOL fSuccess = FALSE;
70 STARTUPINFO si;
71 PROCESS_INFORMATION pi;
72
73 ZeroMemory( &si, sizeof(si) );
74 si.cb = sizeof(si);
75
76 fSuccess = CreateProcess(
77 NULL,
78 (LPTSTR)lpCommand,
79 NULL,
80 NULL,
81 FALSE,
82 0,
83 NULL,
84 NULL,
85 &si,
86 &pi
87 );
88
89 if ( fSuccess )
90 {
91 if ( bSync )
92 WaitForSingleObject( pi.hProcess, INFINITE );
93
94 CloseHandle( pi.hProcess );
95 CloseHandle( pi.hThread );
96 }
97
98 return fSuccess;
99 }
100
ExecutePostUninstallScript(MSIHANDLE handle)101 extern "C" UINT __stdcall ExecutePostUninstallScript( MSIHANDLE handle )
102 {
103 TCHAR szValue[8192];
104 DWORD nValueSize = sizeof(szValue);
105 HKEY hKey;
106 std::_tstring sInstDir;
107
108 std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
109
110 // MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK );
111
112 if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
113 {
114 if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
115 {
116 sInstDir = szValue;
117 }
118 RegCloseKey( hKey );
119 }
120 else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
121 {
122 if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
123 {
124 sInstDir = szValue;
125 }
126 RegCloseKey( hKey );
127 }
128 else
129 return ERROR_SUCCESS;
130
131 std::_tstring sInfFile = sInstDir + TEXT("program\\postuninstall.inf");
132 std::_tstring sCommand = _T("RUNDLL32.EXE ");
133
134 // MessageBox( NULL, sInfFile.c_str(), "Titel", MB_OK );
135
136 if ( (LONG)GetVersion() < 0 )
137 sCommand += _T("setupx.dll");
138 else
139 sCommand += _T("setupapi.dll");
140
141 sCommand += _T(",InstallHinfSection PostUninstall 132 ");
142 sCommand += sInfFile;
143
144 if ( 0 == _taccess( sInfFile.c_str(), 2 ) )
145 ExecuteCommand( sCommand.c_str(), TRUE );
146
147 DeleteFile( sInfFile.c_str() );
148
149 return ERROR_SUCCESS;
150 }
151
152