1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #undef UNICODE 29 #undef _UNICODE 30 31 #define _WIN32_WINDOWS 0x0410 32 33 #ifdef _MSC_VER 34 #pragma warning(push, 1) /* disable warnings within system headers */ 35 #define WIN32_LEAN_AND_MEAN 36 #endif 37 #include <windows.h> 38 #include <msiquery.h> 39 #include <shellapi.h> 40 #ifdef _MSC_VER 41 #pragma warning(pop) 42 #endif 43 44 #include <malloc.h> 45 #include <assert.h> 46 #include <string.h> 47 48 #ifdef UNICODE 49 #define _UNICODE 50 #define _tstring wstring 51 #else 52 #define _tstring string 53 #endif 54 #include <tchar.h> 55 #include <string> 56 57 /** creates a temporary folder with a unique name. 58 59 The returned string is a file URL. 60 */ 61 // static std::_tstring createTempFolder() 62 // { 63 // BOOL bExist = FALSE; 64 // TCHAR szTempName[MAX_PATH]; 65 // do 66 // { 67 // bExist = FALSE; 68 // // Get the temp path. 69 // TCHAR lpPathBuffer[MAX_PATH]; 70 // DWORD dwRetVal = GetTempPath(MAX_PATH, lpPathBuffer); 71 // if (dwRetVal > MAX_PATH || (dwRetVal == 0)) 72 // { 73 // //fprintf (stderr, "GetTempPath failed with error %d.\n", GetLastError()); 74 // return TEXT(""); 75 // } 76 // // Create a temporary file. 77 // UINT uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files 78 // "upg", // temp file name prefix 79 // 0, // create unique name 80 // szTempName); // buffer for name 81 // if (uRetVal == 0) 82 // { 83 // //fprintf (stderr, "GetTempFileName failed with error %d.\n", GetLastError()); 84 // return TEXT(""); 85 // } 86 // //Delete the file 87 // BOOL bDel = DeleteFile(szTempName); 88 // if (FALSE == bDel) 89 // { 90 // //fprintf(stderr, "Could not delete temp file. Error %d.\n", GetLastError()); 91 // return TEXT(""); 92 // } 93 // // Create the directory 94 // BOOL bDir = CreateDirectory(szTempName, NULL); 95 // if (FALSE == bDir) 96 // { 97 // DWORD error =GetLastError(); 98 // if (ERROR_ALREADY_EXISTS == error) 99 // { 100 // bExist = TRUE; 101 // } 102 // else 103 // { 104 // //fprintf(stderr, "CreateDirectory failed with error %d.\n", error); 105 // return TEXT(""); 106 // } 107 // } 108 // } while(bExist); 109 110 // std::_tstring cur(szTempName); 111 // //make a file URL from the path 112 // std::_tstring ret(TEXT("file:///")); 113 // for (std::_tstring::iterator i = cur.begin(); i != cur.end(); i++) 114 // { 115 // if (*i == '\\') 116 // ret.append(TEXT("/")); 117 // else 118 // ret.push_back(*i); 119 // } 120 // // MessageBox(NULL, ret.c_str(), "createTempFolder", MB_OK); 121 // return ret.c_str(); 122 // } 123 124 /** deletes the temporary folder. 125 The argument must be a file URL. 126 */ 127 // static void deleteTempFolder(const std::_tstring& sTempFolder) 128 // { 129 // if (sTempFolder.size() == 0) 130 // return; 131 // //convert the file URL to a path 132 // const std::_tstring path(sTempFolder.substr(8)); 133 // std::_tstring path2; 134 // // MessageBox(NULL, path.c_str(), "del1", MB_OK); 135 // for (std::_tstring::const_iterator i = path.begin(); i != path.end(); i++) 136 // { 137 // if (*i == '/') 138 // path2.append(TEXT("\\")); 139 // else 140 // path2.push_back(*i); 141 // } 142 143 // //We need a null terminated string with two nulls in the end 144 // //for the SHFILEOPSTRUCT 145 // const TCHAR * szTemp = path2.c_str(); 146 // size_t size = path2.size(); 147 // TCHAR * szTemp2 = new TCHAR[size + 2]; 148 // ZeroMemory(szTemp2, (size + 2) * sizeof(TCHAR)); 149 // memcpy(szTemp2, szTemp, size * sizeof(TCHAR)); 150 151 // // MessageBox(NULL, szTemp2, "del3", MB_OK); 152 // SHFILEOPSTRUCT operation = 153 // { 154 // NULL, 155 // FO_DELETE, 156 // szTemp2, 157 // NULL, 158 // FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR, 159 // FALSE, 160 // NULL, 161 // NULL 162 // }; 163 164 // SHFileOperation( &operation); 165 // delete [] szTemp2; 166 // } 167 168 169 170 static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty ) 171 { 172 std::_tstring result; 173 TCHAR szDummy[1] = TEXT(""); 174 DWORD nChars = 0; 175 176 if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA ) 177 { 178 DWORD nBytes = ++nChars * sizeof(TCHAR); 179 LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes)); 180 ZeroMemory( buffer, nBytes ); 181 MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars); 182 result = buffer; 183 } 184 185 return result; 186 } 187 188 /* creates a child process which is specified in lpCommand. 189 190 out_exitCode is the exit code of the child process 191 192 193 **/ 194 static BOOL ExecuteCommand( LPCTSTR lpCommand, DWORD * out_exitCode) 195 { 196 BOOL fSuccess = FALSE; 197 STARTUPINFO si; 198 PROCESS_INFORMATION pi; 199 200 ZeroMemory( &si, sizeof(si) ); 201 si.cb = sizeof(si); 202 203 fSuccess = CreateProcess( 204 NULL, 205 (LPTSTR)lpCommand, 206 NULL, 207 NULL, 208 FALSE, 209 0, 210 NULL, 211 NULL, 212 &si, 213 &pi 214 ); 215 216 if ( fSuccess ) 217 { 218 WaitForSingleObject( pi.hProcess, INFINITE ); 219 220 if (!GetExitCodeProcess( pi.hProcess, out_exitCode)) 221 fSuccess = FALSE; 222 223 CloseHandle( pi.hProcess ); 224 CloseHandle( pi.hThread ); 225 } 226 227 return fSuccess; 228 } 229 230 static BOOL RemoveCompleteDirectory( std::_tstring sPath ) 231 { 232 bool bDirectoryRemoved = true; 233 234 std::_tstring mystr; 235 std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*"); 236 WIN32_FIND_DATA aFindData; 237 238 // Finding all content in sPath 239 240 HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData ); 241 242 if ( hFindContent != INVALID_HANDLE_VALUE ) 243 { 244 bool fNextFile = false; 245 246 do 247 { 248 std::_tstring sFileName = aFindData.cFileName; 249 std::_tstring sCurrentDir = TEXT("."); 250 std::_tstring sParentDir = TEXT(".."); 251 252 mystr = "Current short file: " + sFileName; 253 // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK); 254 255 if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) && 256 ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 )) 257 { 258 std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName; 259 260 if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY ) 261 { 262 bool fSuccess = RemoveCompleteDirectory(sCompleteFileName); 263 if ( fSuccess ) 264 { 265 mystr = "Successfully removed content of dir " + sCompleteFileName; 266 // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK); 267 } 268 else 269 { 270 mystr = "An error occured during removing content of " + sCompleteFileName; 271 // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK); 272 } 273 } 274 else 275 { 276 bool fSuccess = DeleteFile( sCompleteFileName.c_str() ); 277 if ( fSuccess ) 278 { 279 mystr = "Successfully removed file " + sCompleteFileName; 280 // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK); 281 } 282 else 283 { 284 mystr = "An error occured during removal of file " + sCompleteFileName; 285 // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK); 286 } 287 } 288 } 289 290 fNextFile = FindNextFile( hFindContent, &aFindData ); 291 292 } while ( fNextFile ); 293 294 FindClose( hFindContent ); 295 296 // empty directory can be removed now 297 // RemoveDirectory is only successful, if the last handle to the directory is closed 298 // -> first removing content -> closing handle -> remove empty directory 299 300 bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str()); 301 302 if ( fRemoveDirSuccess ) 303 { 304 mystr = "Successfully removed dir " + sPath; 305 // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK); 306 } 307 else 308 { 309 mystr = "An error occured during removal of empty directory " + sPath; 310 // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK); 311 bDirectoryRemoved = false; 312 } 313 } 314 315 return bDirectoryRemoved; 316 } 317 318 extern "C" UINT __stdcall RegisterExtensions(MSIHANDLE handle) 319 { 320 // std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") ); 321 std::_tstring sInstDir = GetMsiProperty( handle, TEXT("CustomActionData") ); 322 std::_tstring sUnoPkgFile = sInstDir + TEXT("program\\unopkg.exe"); 323 std::_tstring mystr; 324 325 WIN32_FIND_DATA aFindFileData; 326 bool registrationError = false; 327 328 // Find unopkg.exe 329 HANDLE hFindUnopkg = FindFirstFile( sUnoPkgFile.c_str(), &aFindFileData ); 330 331 if ( hFindUnopkg != INVALID_HANDLE_VALUE ) 332 { 333 // unopkg.exe exists in program directory 334 std::_tstring sCommand = sUnoPkgFile + " sync"; 335 336 DWORD exitCode = 0; 337 bool fSuccess = ExecuteCommand( sCommand.c_str(), & exitCode); 338 339 // if ( fSuccess ) 340 // { 341 // mystr = "Executed successfully!"; 342 // MessageBox(NULL, mystr.c_str(), "Command", MB_OK); 343 // } 344 // else 345 // { 346 // mystr = "An error occured during execution!"; 347 // MessageBox(NULL, mystr.c_str(), "Command", MB_OK); 348 // } 349 350 if ( ! fSuccess ) 351 { 352 mystr = "ERROR: An error occured during registration of extensions!"; 353 MessageBox(NULL, mystr.c_str(), "ERROR", MB_OK); 354 registrationError = true; 355 } 356 357 FindClose( hFindUnopkg ); 358 } 359 // else 360 // { 361 // mystr = "Error: Did not find " + sUnoPkgFile; 362 // MessageBox(NULL, mystr.c_str(), "Command", MB_OK); 363 // } 364 365 if ( registrationError ) 366 { 367 return 1; 368 } 369 else 370 { 371 return ERROR_SUCCESS; 372 } 373 } 374 375 376 extern "C" UINT __stdcall RemoveExtensions(MSIHANDLE handle) 377 { 378 std::_tstring mystr; 379 380 // Finding the product with the help of the propery FINDPRODUCT, 381 // that contains a Windows Registry key, that points to the install location. 382 383 TCHAR szValue[8192]; 384 DWORD nValueSize = sizeof(szValue); 385 HKEY hKey; 386 std::_tstring sInstDir; 387 388 std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") ); 389 //MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK ); 390 391 if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) ) 392 { 393 if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) ) 394 { 395 sInstDir = szValue; 396 } 397 RegCloseKey( hKey ); 398 } 399 else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) ) 400 { 401 if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) ) 402 { 403 sInstDir = szValue; 404 } 405 RegCloseKey( hKey ); 406 } 407 else 408 { 409 return ERROR_SUCCESS; 410 } 411 412 // Removing complete directory "Basis\presets\bundled" 413 414 std::_tstring sCacheDir = sInstDir + TEXT("share\\prereg\\bundled"); 415 416 bool fSuccess = RemoveCompleteDirectory( sCacheDir ); 417 418 // if ( fSuccess ) 419 // { 420 // mystr = "Executed successfully!"; 421 // MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK); 422 // } 423 // else 424 // { 425 // mystr = "An error occured during execution!"; 426 // MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK); 427 // } 428 429 return ERROR_SUCCESS; 430 } 431