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 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 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 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