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_WINNT 0x0401 25 26 #ifdef _MSC_VER 27 #pragma warning(push, 1) /* disable warnings within system headers */ 28 #endif 29 #define WIN32_LEAN_AND_MEAN 30 #include <windows.h> 31 #include <msiquery.h> 32 #ifdef _MSC_VER 33 #pragma warning(pop) 34 #endif 35 36 #include <malloc.h> 37 #include <assert.h> 38 39 #ifdef UNICODE 40 #define _UNICODE 41 #define _tstring wstring 42 #else 43 #define _tstring string 44 #endif 45 #include <tchar.h> 46 #include <string> 47 #include <queue> 48 #include <stdio.h> 49 #include <strsafe.h> 50 51 #include <systools/win32/uwinapi.h> 52 #include <../tools/seterror.hxx> 53 54 //---------------------------------------------------------- 55 #ifdef DEBUG 56 inline void OutputDebugStringFormat( LPCSTR pFormat, ... ) 57 { 58 CHAR buffer[1024]; 59 va_list args; 60 61 va_start( args, pFormat ); 62 StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args ); 63 OutputDebugStringA( buffer ); 64 } 65 #else 66 static inline void OutputDebugStringFormat( LPCSTR, ... ) 67 { 68 } 69 #endif 70 71 72 static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty ) 73 { 74 std::_tstring result; 75 TCHAR szDummy[1] = TEXT(""); 76 DWORD nChars = 0; 77 78 if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA ) 79 { 80 DWORD nBytes = ++nChars * sizeof(TCHAR); 81 LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes)); 82 ZeroMemory( buffer, nBytes ); 83 MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars); 84 result = buffer; 85 } 86 87 return result; 88 } 89 90 static BOOL RemoveCompleteDirectory( std::_tstring sPath ) 91 { 92 bool bDirectoryRemoved = true; 93 94 std::_tstring mystr; 95 std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*"); 96 WIN32_FIND_DATA aFindData; 97 98 // Finding all content in sPath 99 100 HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData ); 101 102 if ( hFindContent != INVALID_HANDLE_VALUE ) 103 { 104 bool fNextFile = false; 105 std::_tstring sCurrentDir = TEXT("."); 106 std::_tstring sParentDir = TEXT(".."); 107 108 do 109 { 110 std::_tstring sFileName = aFindData.cFileName; 111 112 mystr = "Current short file: " + sFileName; 113 // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK); 114 115 if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) && 116 ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 )) 117 { 118 std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName; 119 120 if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY ) 121 { 122 bool fSuccess = RemoveCompleteDirectory(sCompleteFileName); 123 if ( fSuccess ) 124 { 125 mystr = "Successfully removed content of dir " + sCompleteFileName; 126 // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK); 127 } 128 else 129 { 130 mystr = "An error occured during removing content of " + sCompleteFileName; 131 // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK); 132 } 133 } 134 else 135 { 136 bool fSuccess = DeleteFile( sCompleteFileName.c_str() ); 137 if ( fSuccess ) 138 { 139 mystr = "Successfully removed file " + sCompleteFileName; 140 // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK); 141 } 142 else 143 { 144 mystr = "An error occured during removal of file " + sCompleteFileName; 145 // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK); 146 } 147 } 148 } 149 150 fNextFile = FindNextFile( hFindContent, &aFindData ); 151 152 } while ( fNextFile ); 153 154 FindClose( hFindContent ); 155 156 // empty directory can be removed now 157 // RemoveDirectory is only successful, if the last handle to the directory is closed 158 // -> first removing content -> closing handle -> remove empty directory 159 160 bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str()); 161 162 if ( fRemoveDirSuccess ) 163 { 164 mystr = "Successfully removed dir " + sPath; 165 // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK); 166 } 167 else 168 { 169 mystr = "An error occured during removal of empty directory " + sPath; 170 // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK); 171 bDirectoryRemoved = false; 172 } 173 } 174 175 return bDirectoryRemoved; 176 } 177 178 179 180 extern "C" UINT __stdcall RenamePrgFolder( MSIHANDLE handle ) 181 { 182 std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION")); 183 184 std::_tstring sRenameSrc = sOfficeInstallPath + TEXT("program"); 185 std::_tstring sRenameDst = sOfficeInstallPath + TEXT("program_old"); 186 187 // MessageBox(NULL, sRenameSrc.c_str(), "INSTALLLOCATION", MB_OK); 188 189 bool bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() ); 190 if ( !bSuccess ) 191 { 192 TCHAR sAppend[2] = TEXT("0"); 193 for ( int i = 0; i < 10; i++ ) 194 { 195 sRenameDst = sOfficeInstallPath + TEXT("program_old") + sAppend; 196 bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() ); 197 if ( bSuccess ) 198 break; 199 sAppend[0] += 1; 200 } 201 } 202 203 #if 0 204 if ( !bSuccess ) 205 MessageBox(NULL, "Renaming folder failed", "RenamePrgFolder", MB_OK); 206 else 207 MessageBox(NULL, "Renaming folder successful", "RenamePrgFolder", MB_OK); 208 #endif 209 210 return ERROR_SUCCESS; 211 } 212 213 extern "C" UINT __stdcall RemovePrgFolder( MSIHANDLE handle ) 214 { 215 std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION")); 216 std::_tstring sRemoveDir = sOfficeInstallPath + TEXT("program_old"); 217 218 // MessageBox(NULL, sRemoveDir.c_str(), "REMOVING OLD DIR", MB_OK); 219 220 bool bSuccess = RemoveCompleteDirectory( sRemoveDir ); 221 222 TCHAR sAppend[2] = TEXT("0"); 223 for ( int i = 0; i < 10; i++ ) 224 { 225 sRemoveDir = sOfficeInstallPath + TEXT("program_old") + sAppend; 226 bSuccess = RemoveCompleteDirectory( sRemoveDir ); 227 sAppend[0] += 1; 228 } 229 230 #if 0 231 if ( bSuccess ) 232 MessageBox(NULL, "Removing folder successful", "RemovePrgFolder", MB_OK); 233 else 234 MessageBox(NULL, "Removing folder failed", "RemovePrgFolder", MB_OK); 235 #endif 236 237 return ERROR_SUCCESS; 238 } 239