/************************************************************************* * * $RCSfile: loader.cxx,v $ * * $Revision: 1.28.74.6 $ * * last change: $Author: vg $ $Date: 2004/01/15 14:07:23 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://www.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #include #define _LOADER_CXX #include "arch.hxx" #include "loader.h" #include "svunzip.h" #include #include #include #include #include #include #include #include #include #include #include #ifndef _RTL_USTRING_H_ #include #endif #ifndef _OSL_THREAD_H_ #include #endif #ifndef _OSL_FILE_H_ #include #endif ////////////////////////////////////////////////////////////////////////// // defines #define OS_ERROR 0 #define OS_WIN95 1 #define OS_WIN98 2 #define OS_NT35 3 #define OS_NT4 4 #define OS_NT5 5 #define APPQUIT_TIMER 1 #define MAX_LINE_BUF _MAX_PATH #define W16_MAX_WAIT 18000 // EnumWindows count #define WNT_MAX_WAIT 30000 // milisec. #define MAX_IDENTIFYER_LEN 30 #define MAX_LINE_BUF _MAX_PATH #define LPARAM_ENUMWINDOWS 100 #define CPY_BUF_SZ 32000 #define UNLOADER_FILENAME "uinst001.exe" #define PROGRESS_OFFSET 10 #define PROGRESS_WIDTH 200 #define PROGRESS_HEIGHT 12 #define ICON_OFFSET 5 #define ICON_SIZE 32 #define SALLIBNAME "sal3.dll" #define STRNCPY(dest,source,size) strncpy( dest, source, size-1 ); dest[size-1]='\0' #define STRNCAT(dest,source,size) strncat( dest, source, size-strlen(dest)-1 ) ////////////////////////////////////////////////////////////////////////// // globals HINSTANCE hInst; UINT hInstallInst; HWND hWnd; char szModuleFileName[MAX_PATH]; char szSourcePath[MAX_PATH]; char szTempPath[MAX_PATH]; char szEXE[MAX_PATH]; char szSetupINI[MAX_PATH]; char szUnoINI[MAX_PATH]; char szOldPath[MAX_PATH]; char szCommandLine[1024]; char szSetupEXE[ 2 * MAX_PATH + sizeof(szCommandLine) ]; char szOfficePath[MAX_PATH]; char szOfficeProgramPath[MAX_PATH]; BOOL bError = FALSE; BOOL bShow = TRUE; BOOL bOfficePathFound = FALSE; BOOL bDeleteTemp = TRUE; int nOldDrive, nCommand = 0; ULONG nMinTempSize = 0; ULONG nTotalSize = 0; ULONG nBigDataOffset = 0; ULONG nUnloaderOffset = 0; long nLastPercent = -1; ULONG nTotalBytesWritten = 0; long nLastBytesWritten = 0; BOOL bExtractBIG = FALSE; static char strExtractPath[MAX_PATH]; char strLoaderTemp[MAX_PATH]; char strWEBStartPath[_MAX_PATH]; HFILE hLoaderTemp; char strProcessIdentifyer[MAX_IDENTIFYER_LEN]; int nProcessIdentifyerLen; DWORD nProcessID = 0; static const char strUnloaderPatch[] = "UNLOAD:xxxxxxxxxxxxxxx"; static const char strExePatch[] = "BIGFILE:patchpatchpatch"; char strSALLIBName[MAX_PATH]; BOOL bSALLIBFound = FALSE; char strSALLIBName_In_ZIP[MAX_PATH]; char strUWINAPILIBName[MAX_PATH]; BOOL bUWINAPILIBFound = FALSE; char strUWINAPILIBName_In_ZIP[MAX_PATH]; char strMSVCRTLIBName[MAX_PATH]; BOOL bMSVCRTLIBFound = FALSE; char strMSVCRTLIBName_In_ZIP[MAX_PATH]; char strMSVCR70LIBName[MAX_PATH]; BOOL bMSVCR70LIBFound = FALSE; char strMSVCR70LIBName_In_ZIP[MAX_PATH]; char strSTLPORTLIBName[MAX_PATH]; BOOL bSTLPORTLIBFound = FALSE; char strSTLPORTLIBName_In_ZIP[MAX_PATH]; char strUNICOWSLIBName[MAX_PATH]; BOOL bUNICOWSLIBFound = FALSE; char strUNICOWSLIBName_In_ZIP[MAX_PATH]; void DrawProgress( long nProgress ); // BOOL bPatchMode = FALSE; char strInstPath[MAX_PATH]; enum CheckFileMagic { CFU_CheckFileSize_Magic, CFU_CopyFiles_Magic }; void UnpackOneFileFromBIG2Temp( ArchDirectory* pBigDir, char* strFilename); BOOL OpenPatchFile(char*, char*); void CopyFiles(char* _pSourcePath, char* _pDestPath, char *_pPattern); BOOL OpenSVersion(char* strName, char* strInstPath, char* strTempPath); BOOL CheckDirectory(char* strDir); void CopyFilesFromList(char* _pSourcePath, char* _pDestPath, char *_pStrPathList, char* _pStrListName); BOOL CheckForUpdate(ArchDirectory* pBigDir, CheckFileMagic); BOOL CheckFile(const char* _pFilePath); BOOL CheckForString(char* strSource, char* strSearch); BOOL BrowseForInstall( char* strPath ); void __EnumFilesCallBack( char *pFile, ULONG nSize, void *pObject ); void __UnzipCallback(long lBytesWritten); // ----------------------------------------------------------------------- // MoveFileEx // ----------------------------------------------------------------------- #define WIN32_LEAN_AND_MEAN #include #define WININIT_FILENAME "wininit.ini" #define RENAME_SECTION "rename" /* macro that calculates the count of elements of a static array */ #define elementsof(buf) (sizeof(buf) / sizeof((buf)[0])) // ----------------------------------------------------------------------- static BOOL WINAPI MoveFileExA_9x( LPCSTR lpExistingFileNameA, // file name LPCSTR lpNewFileNameA, // new file name DWORD dwFlags ) // move options { BOOL fSuccess = FALSE; // assume failure // Windows 9x has a special mechanism to move files after reboot if ( dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT ) { CHAR szExistingFileNameA[MAX_PATH]; CHAR szNewFileNameA[MAX_PATH] = "NUL"; // Path names in WININIT.INI must be in short path name form if ( GetShortPathNameA( lpExistingFileNameA, szExistingFileNameA, MAX_PATH ) && (!lpNewFileNameA || GetShortPathNameA( lpNewFileNameA, szNewFileNameA, MAX_PATH )) ) { CHAR szBuffer[32767]; // The buffer size must not exceed 32K DWORD dwBufLen = GetPrivateProfileSectionA( RENAME_SECTION, szBuffer, elementsof(szBuffer), WININIT_FILENAME ); CHAR szRename[MAX_PATH]; // This is enough for at most to times 67 chracters STRNCPY( szRename, szNewFileNameA, sizeof( szRename ) ); STRNCAT( szRename, "=", sizeof( szRename ) ); STRNCAT( szRename, szExistingFileNameA, sizeof( szRename ) ); size_t lnRename = strlen(szRename); if ( dwBufLen + lnRename + 2 <= elementsof(szBuffer) ) { CopyMemory( &szBuffer[dwBufLen], szRename, lnRename ); szBuffer[dwBufLen + lnRename ] = 0; szBuffer[dwBufLen + lnRename + 1 ] = 0; fSuccess = WritePrivateProfileSectionA( RENAME_SECTION, szBuffer, WININIT_FILENAME ); } else SetLastError( ERROR_BUFFER_OVERFLOW ); } } else { fSuccess = MoveFileA( lpExistingFileNameA, lpNewFileNameA ); if ( !fSuccess && 0 != (dwFlags & (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) ) { BOOL bFailIfExist = 0 == (dwFlags & MOVEFILE_REPLACE_EXISTING); fSuccess = CopyFileA( lpExistingFileNameA, lpNewFileNameA, bFailIfExist ); // In case of successfull copy do not return FALSE if delete fails. // Error detection is done by GetLastError() if ( fSuccess ) { SetLastError( NO_ERROR ); DeleteFileA( lpExistingFileNameA ); } } } return fSuccess; } // ----------------------------------------------------------------------- typedef BOOL (WINAPI *MoveFileExA_PROC)( LPCSTR lpExistingFileName, // file name LPCSTR lpNewFileName, // new file name DWORD dwFlags ); // move options static BOOL WINAPI MoveFileExA_NT( LPCSTR lpExistingFileName, // file name LPCSTR lpNewFileName, // new file name DWORD dwFlags ) // move options { static MoveFileExA_PROC lpfn = NULL; if ( !lpfn ) lpfn = (MoveFileExA_PROC) GetProcAddress( GetModuleHandleA("KERNEL32.DLL"), "MoveFileExA" ); if ( lpfn ) return lpfn( lpExistingFileName, lpNewFileName, dwFlags ); else { SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); return FALSE; } } // ----------------------------------------------------------------------- BOOL WINAPI MyPortable_MoveFileExA( LPCSTR lpExistingFileName, // file name LPCSTR lpNewFileName, // new file name DWORD dwFlags ) // move options { if ( (LONG)GetVersion() < 0 ) return MoveFileExA_9x( lpExistingFileName, lpNewFileName, dwFlags ); else return MoveFileExA_NT( lpExistingFileName, lpNewFileName, dwFlags ); } // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // GETDISKFREESPACE // // GETDISKFREESPACE returns the amount of free space in KByte ! #define GETDISKFREESPACE(nBytes,sRootName) \ { \ nBytes = 0; \ if ( GetFileAttributes(sRootName) != 0xFFFFFFFF ) { \ char cpDrive[4]; \ strncpy( cpDrive, sRootName, 3 ); \ cpDrive[3] = '\0'; \ DWORD nSecPerClu, nBytesPerSec, nFreeClu, nClu; \ if ( GetDiskFreeSpace( cpDrive, &nSecPerClu, \ &nBytesPerSec, &nFreeClu, &nClu ) ) \ { \ double nSize = nSecPerClu * nBytesPerSec; \ nSize *= nFreeClu; \ nSize /= 1024; \ nBytes = (DWORD) nSize; \ } \ } \ } #define GETTEXTEVENT( aHDC, cpText, nTxtLen, nWidth ) \ { \ SIZE aSize; \ GetTextExtentPoint32( aHDC, cpText, nTxtLen, &aSize ); \ nWidth = aSize.cx; \ } ////////////////////////////////////////////////////////////////////////// // BOOL CALLBACK _EnumCallBack( HWND hWnd, LPARAM lParam ) // BOOL _GetAppPID() // BOOL _WaitForObject( const char* pWinTitle ) BOOL CALLBACK _EnumCallBack( HWND hWnd, LPARAM lParam ) { char cWinTitle[MAX_IDENTIFYER_LEN]; char cClassName[MAX_IDENTIFYER_LEN]; memset( cWinTitle, 0, MAX_IDENTIFYER_LEN ); memset( cClassName, 0, MAX_IDENTIFYER_LEN ); GetWindowText( hWnd, cWinTitle, MAX_IDENTIFYER_LEN ); GetClassName( hWnd, cClassName, MAX_IDENTIFYER_LEN ); if( (strncmp(cWinTitle, strProcessIdentifyer, nProcessIdentifyerLen) == 0) && (strcmp(cClassName, "SALFRAME") == 0) ) { #ifdef WNT GetWindowThreadProcessId( hWnd, &nProcessID ); #else nProcessID = GetWindowTask( hWnd ); #endif return FALSE; } return TRUE; } BOOL _GetAppPID() { BOOL bResult = EnumWindows( (WNDENUMPROC)_EnumCallBack, LPARAM_ENUMWINDOWS ); return !bResult; } BOOL _WaitForObject( const char* pWinTitle ) { STRNCPY( strProcessIdentifyer, pWinTitle, sizeof( strProcessIdentifyer ) ); nProcessIdentifyerLen = strlen( strProcessIdentifyer ); BOOL bSuccess = TRUE; { if( _GetAppPID() ) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nProcessID); DWORD nResult = WaitForSingleObject(hProcess, WNT_MAX_WAIT); bSuccess = nResult == WAIT_TIMEOUT? FALSE : TRUE; } } return bSuccess; } ////////////////////////////////////////////////////////////////////////// // GetOSVersion() USHORT GetOSVersion() { USHORT nOS = OS_ERROR; WORD nGUIVersion = (WORD) GetVersion(); USHORT nVer = ((((USHORT)LOBYTE(nGUIVersion))*100)+HIBYTE(nGUIVersion)); if( nVer == 351 ) { nOS = OS_NT35; return nOS; } else if( nVer == 400 || nVer == 395 ) // win95 || w16 unter win95 nOS = OS_WIN95; else if( nVer == 410 ) nOS = OS_WIN98; #ifdef WNT OSVERSIONINFO aVerInfo; aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo ); if ( GetVersionEx( &aVerInfo ) ) { if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) if( aVerInfo.dwBuildNumber >= 1382 ) nOS = OS_NT5; else nOS = OS_NT4; } #endif return nOS; } ////////////////////////////////////////////////////////////////////////// // CopyZipFile() BOOL CopyZipFile( const char* pFrom, const char* pTo , CheckFileMagic aMagic) { HANDLE hSource, hDest; DWORD nRead; PBYTE pbBuf; int nCopyBufferSize = 128 * 1024; hSource = CreateFile( pFrom, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); if (hSource && aMagic == CFU_CheckFileSize_Magic) { FILE* pFile = fopen(pFrom, "rb"); // due to can't use of GetFileSize, use fopen ;-) if (pFile) { fseek( pFile, 0, SEEK_END ); DWORD nSize = ftell( pFile ); __EnumFilesCallBack(NULL, nSize, NULL); fclose(pFile); } CloseHandle( hSource ); return TRUE; } // check if file already exist, don't copy. // if (CheckFile(pTo)) // { // return TRUE; // } hDest = CreateFile( pTo, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); BOOL bOpen = TRUE; if ( INVALID_HANDLE_VALUE == hSource ) { char cErr[_MAX_PATH]; LoadString( hInst, IDS_NOOPEN, cErr, sizeof(cErr) ); STRNCAT( cErr, pFrom, sizeof(cErr) ); InfoBox( hWnd, cErr ); bOpen = FALSE; } if ( INVALID_HANDLE_VALUE == hDest ) { char cErr[_MAX_PATH]; LoadString( hInst, IDS_NOOPEN, cErr, sizeof(cErr) ); STRNCAT( cErr, pTo, sizeof(cErr) ); InfoBox( hWnd, cErr ); bOpen = FALSE; } if ( !bOpen ) return FALSE; /* allocate a buffer for file I/O */ pbBuf = (PBYTE)LocalAlloc( LMEM_FIXED, nCopyBufferSize ); /* copy the source file to the dest file */ BOOL bNoErr; do { bNoErr = ReadFile( hSource, pbBuf, nCopyBufferSize, &nRead, NULL ); if ( bNoErr ) bNoErr = WriteFile( hDest, pbBuf, nRead, &nRead, NULL ); __UnzipCallback(nRead); } while ( bNoErr && ( nRead != 0 ) ); /* free the buffer and close the files */ LocalFree( (HLOCAL)pbBuf ); CloseHandle( hSource ); CloseHandle( hDest ); return TRUE; } ////////////////////////////////////////////////////////////////////////// // trim() void trim(char *pTmpPath) { if (pTmpPath[0] == '\0') return; int i=0; while(pTmpPath[i] == ' ') i++; if (i != 0) strcpy(pTmpPath,pTmpPath+i); // #100211# - checked } ////////////////////////////////////////////////////////////////////////// // GetTempPath() const char* GetTempPath( char* pBuf, long nBufSize ) { char cpTmpPath[_MAX_PATH] = ""; DWORD dwSize = 0; BOOL bTempFound = FALSE; // Windows NT kennt kein GetDOSEnvironment if (GetEnvironmentVariable("TMP", cpTmpPath, _MAX_PATH) || GetEnvironmentVariable("TEMP", cpTmpPath, _MAX_PATH) || GetEnvironmentVariable("tmp", cpTmpPath, _MAX_PATH) || GetEnvironmentVariable("temp", cpTmpPath, _MAX_PATH)) { bTempFound = TRUE; } if( bTempFound ) { struct _stat aStat; trim(cpTmpPath); if (_stat(cpTmpPath, &aStat) != 0 // nicht vorhanden || (aStat.st_mode & S_IFDIR) == 0) // oder kein Verzeichnis { strcpy(&cpTmpPath[1], ":\\"); // "d:\falsch" -> "d:\" // #100211# - checked } if (_stat(cpTmpPath, &aStat) == 0 // vorhanden && (aStat.st_mode & S_IFDIR) != 0) // und ein Verzeichnis { STRNCPY( pBuf, cpTmpPath, nBufSize ); return pBuf; } } if (GetWindowsDirectory( pBuf, _MAX_PATH)) { return pBuf; } STRNCPY( pBuf, "c:\\", nBufSize ); return pBuf; } ////////////////////////////////////////////////////////////////////////// // GetTempFile() void GetTempFile( char* cpTemp, long nBufLen ) { // source stammt aus FSYS const char* dir; char* ret_val; size_t i; // dertermine Directory, Prefix and Extension char pfx[6]; char ext[5]; STRNCPY( pfx, "sv", sizeof( pfx ) ); STRNCPY( ext, ".tmp", sizeof( ext ) ); char sBuf[_MAX_PATH]; dir = GetTempPath( sBuf, sizeof( sBuf ) ); if ( !dir ) return; // ab hier leicht modifizierter Code von VB i = strlen(dir); ret_val = new char[i+2 /* '\0' & '\\' */ + 8 /*root*/ + 4 /*.ext*/]; if (ret_val) { unsigned u; strncpy( ret_val, dir, i+1 ); /* Make sure directory ends with a separator */ if ( i>0 && ret_val[i-1] != '\\' && ret_val[i-1] != '/' && ret_val[i-1] != ':') ret_val[i++] = '\\'; strncpy(ret_val + i, pfx, 5); ret_val[i + 5] = '\0'; /* strncpy doesn't put a 0 if more */ i = strlen(ret_val); /* than 'n' chars. */ /* Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576 */ for (u = 1; u < 26*26*26; u++) { itoa(u,ret_val + i,26); strncat( ret_val, ext, (i+14) - strlen(ret_val) - 1 ); struct stat aStat; if ( stat( ret_val, &aStat ) ) { STRNCPY( cpTemp, ret_val, nBufLen ); break; } } delete [] ret_val; ret_val = 0; } } ////////////////////////////////////////////////////////////////////////// // SpecialFontHandling() unsigned short __GetGUIVersion() { WORD nGUIVersion = (WORD) GetVersion(); USHORT nVer = ((((USHORT)LOBYTE(nGUIVersion))*100)+HIBYTE(nGUIVersion)); return nVer; } // ---------------------------------------------------------------------------- long Deregister( HKEY hMainKey, const char *sSubKey, const char *sName ) { if ( ! strlen( sSubKey ) ) return -2; HKEY hKey; LONG lErr; lErr = RegOpenKeyEx( hMainKey, sSubKey, 0, KEY_ALL_ACCESS, &hKey); if (lErr != ERROR_SUCCESS) return lErr; lErr = RegDeleteValue( hKey, sName ); RegCloseKey(hKey); return lErr; } // ---------------------------------------------------------------------------- long Register( HKEY hMainKey, const char *sSubKey, const char *sName, const char* sValue ) { if ( ! strlen( sSubKey ) ) return -2; CHAR szDummy[ 2 ]; memset( szDummy, 0, 2 ); HKEY hKey; LONG lErr; lErr = RegCreateKeyEx( hMainKey, sSubKey, 0, szDummy, 0, KEY_WRITE, NULL, &hKey, NULL ); if (lErr != ERROR_SUCCESS) return lErr; lErr = RegSetValueEx( hKey, sName, 0, REG_SZ, (LPBYTE) sValue, strlen( sValue ) + 1 ); RegCloseKey(hKey); return lErr; } // ---------------------------------------------------------------------------- BOOL HasAccessToSystemFontDir() { return FALSE; } // ---------------------------------------------------------------------------- void SpecialFontHandling( const char* pPath ) { char strFontPath[_MAX_PATH]; char strFontRegistryPath[_MAX_PATH]; char* pPattern = (char*)malloc(_MAX_PATH); if( __GetGUIVersion() >= 400 ) { GetWindowsDirectory(strFontPath, _MAX_PATH); STRNCAT( strFontPath, "\\", sizeof( strFontPath ) ); STRNCAT( strFontPath, "Fonts", sizeof( strFontPath ) ); STRNCPY( strFontRegistryPath, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\", sizeof(strFontRegistryPath) ); } else { GetSystemDirectory( strFontPath, _MAX_PATH ); STRNCPY( strFontRegistryPath, "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts\\", sizeof(strFontRegistryPath) ); } STRNCPY( pPattern, pPath, _MAX_PATH ); STRNCAT( pPattern, "\\*.ttf", _MAX_PATH ); WIN32_FIND_DATA aFind; HANDLE aHdl; aHdl = FindFirstFile( pPattern, &aFind ); if( aHdl == INVALID_HANDLE_VALUE ) { free( (char*)pPattern ); return; } do { BOOL bRet, bFontExists; char strAbsSrcFile[_MAX_PATH]; char strAbsDestFile[_MAX_PATH]; char strAbsDestBackupFile[_MAX_PATH]; char strFontName[_MAX_PATH]; /* (dv) special font handling for all fonts! */ if ( stricmp( aFind.cFileName, "soui.ttf" ) == 0 ) strncpy( strFontName, "Andale Sans UI (TrueType)", sizeof(strFontName) - 1 ); else strFontName[0] = '\0'; strFontName[ sizeof(strFontName) - 1] = '\0'; STRNCPY( strAbsSrcFile, pPath, sizeof(strAbsSrcFile) ); if ( strlen( strAbsSrcFile ) < sizeof(strAbsSrcFile) - 2 - strlen( aFind.cFileName ) ) { STRNCAT( strAbsSrcFile, "\\", sizeof(strAbsSrcFile) ); STRNCAT( strAbsSrcFile, aFind.cFileName, sizeof(strAbsSrcFile) ); } else return; STRNCPY( strAbsDestFile, strFontPath, sizeof(strAbsDestFile) ); STRNCAT( strAbsDestFile, "\\", sizeof(strAbsDestFile) ); STRNCAT( strAbsDestFile, aFind.cFileName, sizeof(strAbsDestFile) ); // move the font file up one directory for ( long i = strlen( strFontPath ) - 1; i>=0; i-- ) { if ( strFontPath[i] == '\\' ) { strFontPath[i] = '\0'; break; } } STRNCPY( strAbsDestBackupFile, strFontPath, sizeof( strAbsDestBackupFile ) ); STRNCAT( strAbsDestBackupFile, "\\", sizeof( strAbsDestBackupFile ) ); STRNCAT( strAbsDestBackupFile, aFind.cFileName, sizeof( strAbsDestBackupFile ) ); strncpy( strAbsDestBackupFile + ( strlen( strAbsDestBackupFile ) - 3 ), "old", 3 ); WIN32_FIND_DATA aFontFind; HANDLE aFontHdl; bFontExists = FALSE; bRet = TRUE; aFontHdl = FindFirstFile( strAbsDestFile, &aFontFind ); if ( aFontHdl != INVALID_HANDLE_VALUE ) { FindClose( aFontHdl ); bFontExists = TRUE; if ( ( aFontFind.nFileSizeHigh == aFind.nFileSizeHigh ) && ( aFontFind.nFileSizeLow == aFind.nFileSizeLow ) ) continue; if ( aFontFind.nFileSizeHigh && ( aFontFind.nFileSizeHigh % 2 > aFind.nFileSizeHigh ) ) continue; if ( ! aFind.nFileSizeHigh && ( aFontFind.nFileSizeLow % 2 > aFind.nFileSizeHigh ) ) continue; } if ( bFontExists ) { if ( strlen( strFontName ) ) { // remove font entries from registry Deregister( HKEY_LOCAL_MACHINE, strFontRegistryPath, strFontName ); } // remove font resource bRet = RemoveFontResource( strAbsDestFile ); // and finally move the fontfile out of the way bRet = MoveFile( strAbsDestFile, strAbsDestBackupFile ); if ( bRet ) bRet = MyPortable_MoveFileExA( strAbsDestBackupFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING ); } if ( bRet ) bRet = CopyFile( strAbsSrcFile, strAbsDestFile, TRUE ); if ( bRet ) { // add font resource bRet = AddFontResource( strAbsDestFile ); // add font entries from registry if ( strlen( strFontName ) ) { Register( HKEY_LOCAL_MACHINE, strFontRegistryPath, strFontName, aFind.cFileName ); } } else { // When we could not copy the font into the fonts folder, we will use the font in // the temp folder( with AddFontResource ) and schedule it for remove on the next boot // add font resource bRet = AddFontResource( strAbsSrcFile ); bRet = MyPortable_MoveFileExA( strAbsSrcFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING ); } } while( FindNextFile(aHdl, &aFind) ); FindClose( aHdl ); free( (char*)pPattern ); ::PostMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); } ////////////////////////////////////////////////////////////////////////// // KillTempPath() void KillTempPath( const char* pPath ) { if ( toupper( pPath[0] ) == 'A' || toupper( pPath[0] ) == 'B' ) return; // Existiert Pfad ueberhaupt if (_access(pPath,0) < 0) return; char aRootPath[4]; char* pPattern = (char*)malloc(256); STRNCPY( pPattern, pPath, 256 ); STRNCAT( pPattern, "\\*.*", 256 ); WIN32_FIND_DATA aFind; HANDLE aHdl; aHdl = FindFirstFile( pPattern, &aFind ); if ( aHdl == INVALID_HANDLE_VALUE ) { free( (char*)pPattern ); return; } do { // voller Pfad zusammenbauen char cFullFile[MAX_PATH]; STRNCPY( cFullFile, pPath, sizeof( cFullFile ) ); STRNCAT( cFullFile, "\\", sizeof( cFullFile ) ); STRNCAT( cFullFile, aFind.cFileName, sizeof( cFullFile ) ); remove( cFullFile ); } while ( FindNextFile( aHdl, &aFind ) ); FindClose( aHdl ); // Nach dem Inhalt ist die directory selbst faellig // voerher fluechten wir aber in die root, sonst ist nix mit loeschen int nError = 0; STRNCPY( aRootPath, pPath, 4); chdir( aRootPath ); nError = _rmdir( pPath ) != 0; #ifdef WNT if (nError) { WORD nVer = (WORD)GetVersion(); USHORT nWinVer = (((USHORT)LOBYTE(nVer)) * 100) + HIBYTE(nVer); if (nWinVer < 400) // == WNT351 { char buf[256]; STRNCPY(buf,"rmdir ", sizeof(buf) ); STRNCAT( buf, pPath, sizeof(buf) ); STRNCAT( buf," /s", sizeof(buf) ); system(buf); } } #endif free( (char*)pPattern ); } ////////////////////////////////////////////////////////////////////////// // WinMain() int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG message; // only one instance can run if ( hPrevInstance ) return FALSE; else if ( !InitApplication( hInstance ) ) return FALSE; if ( !InitInstance( hInstance, nCmdShow ) ) return FALSE; // get module filename GetModuleFileName( hInst, szModuleFileName, sizeof(szModuleFileName) ); // test, ob schon gestartet GetTempPath( strLoaderTemp, sizeof(strLoaderTemp) ); if ( strlen(strLoaderTemp) == 3 ) // z.B. c:\ -> c: strLoaderTemp[2] = '\0'; STRNCAT( strLoaderTemp, "\\__loader.tmp", sizeof(strLoaderTemp) ); // Testdatei anlegen OFSTRUCT OpenBuff; UINT fuMode = OF_CREATE; HFILE hFile = OpenFile( (LPCSTR)strLoaderTemp, &OpenBuff, fuMode ); // wenn nicht geklappt, gleich wieder beenden if ( hFile == HFILE_ERROR ) return FALSE; // sonst schlie/sen und gelockt "offnen _lclose( hFile ); fuMode = OF_READWRITE | OF_SHARE_DENY_NONE; hLoaderTemp = OpenFile( (LPCSTR)strLoaderTemp, &OpenBuff, fuMode ); if( hLoaderTemp == HFILE_ERROR ) return FALSE; // copy command line if( strncmp(lpCmdLine, "-extract", 8) == 0 ) { bExtractBIG = TRUE; char* ptr = strchr( &(lpCmdLine[3]), ' ' ); if( ptr ) { STRNCPY( strExtractPath, ptr + 1, sizeof(strExtractPath) ); } } STRNCPY( szCommandLine, lpCmdLine, sizeof(szCommandLine) ); // #99723# if (CheckForString(lpCmdLine, "-dontdeletetemp")) { bDeleteTemp = FALSE; } while ( GetMessage( &message, 0, 0, 0 ) ) { TranslateMessage( &message ); DispatchMessage( &message ); } CleanupSetupFile(); return message.wParam; } ////////////////////////////////////////////////////////////////////////// // InitApplication() BOOL InitApplication( HINSTANCE hInstance ) { WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = 0; wc.hCursor = LoadCursor( 0, IDC_ARROW ); wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1); wc.lpszMenuName = 0; wc.lpszClassName = "SetupWClass"; return RegisterClass( &wc ); } ////////////////////////////////////////////////////////////////////////// // InitInstance() BOOL InitInstance( HINSTANCE hInstance, int nCmdShow ) { // save instance handle hInst = hInstance; // calculate the size of the window: // - get the size of the bitmap and add the size of the progress bar ULONG nWidth = 0; ULONG nHeight = 0; HDC hDC = GetDC( NULL ); HICON hIcon = (HICON) LoadImage( hInst, MAKEINTRESOURCE(3), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR ); ICONINFO aInfo; if ( hIcon && GetIconInfo( hIcon, &aInfo ) ) { BITMAPINFO aBmpInfo; memset( &(aBmpInfo.bmiHeader), 0, sizeof( aBmpInfo.bmiHeader ) ); aBmpInfo.bmiHeader.biSize = sizeof( aBmpInfo.bmiHeader ); if ( aInfo.hbmColor && GetDIBits( hDC, aInfo.hbmColor, 0, 0, NULL, &aBmpInfo, DIB_RGB_COLORS ) ) { nWidth = aBmpInfo.bmiHeader.biWidth; nHeight = aBmpInfo.bmiHeader.biHeight; } if ( aInfo.hbmColor ) DeleteObject( aInfo.hbmColor ); if ( aInfo.hbmMask ) DeleteObject( aInfo.hbmMask ); } if ( nWidth == 0 ) nWidth = ICON_SIZE; if ( nHeight == 0 ) nHeight = ICON_SIZE; nWidth += ( 2 * ICON_OFFSET ); nHeight += ( 3 * ICON_OFFSET ); nWidth += PROGRESS_WIDTH + ( 2 * PROGRESS_OFFSET ); if ( nHeight < ( PROGRESS_HEIGHT + ( 2 * PROGRESS_OFFSET ) ) ) nHeight = PROGRESS_HEIGHT + ( 2 * PROGRESS_OFFSET ); #if (WINVER >= 0x0400) hWnd = CreateWindowEx( WS_EX_TOOLWINDOW, "SetupWClass", 0, WS_POPUP | WS_DLGFRAME, ( GetSystemMetrics( SM_CXSCREEN ) - nWidth ) / 2, ( GetSystemMetrics( SM_CYSCREEN ) - nHeight ) / 2, nWidth, nHeight, 0, 0, hInstance, 0 ); #else hWnd = CreateWindow( "SetupWClass", 0, WS_POPUP | WS_DLGFRAME, ( GetSystemMetrics( SM_CXSCREEN ) - nWidth ) / 2, ( GetSystemMetrics( SM_CYSCREEN ) - nHeight ) / 2, nWidth, nHeight, 0, 0, hInstance, 0 ); #endif DestroyIcon( hIcon ); ReleaseDC( NULL, hDC ); if ( hWnd ) { ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); return TRUE; } else return FALSE; } ////////////////////////////////////////////////////////////////////////// // MainWndProc() LONG FAR PASCAL MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch (message) { ////////////////////////////////////////////////////////////////// case WM_CREATE: { WORD nGUIVersion = (WORD) GetVersion(); USHORT nVer = ((((USHORT)LOBYTE(nGUIVersion))*100)+HIBYTE(nGUIVersion)); if( nVer == 351 ) { ErrorBox( hWnd, IDS_WRONGOS, NULL ); return 0; } char pULoad[50]; STRNCPY( pULoad, &(strUnloaderPatch[7]), sizeof(pULoad) ); if( pULoad[0] != 'x' ) { for( USHORT i = 0; i < strlen(pULoad); ++i ) if( pULoad[i] == 'x' ) { pULoad[i] = 0x00; break; } nUnloaderOffset = atol(pULoad); } nBigDataOffset = atol(&(strExePatch[8])); if( !nBigDataOffset ) PostMessage( hWnd, WM_COMMAND, ID_INSTALL, 0 ); else PostMessage( hWnd, WM_COMMAND, ID_INSTALL_BIG, 0 ); } break; ////////////////////////////////////////////////////////////////// case WM_COMMAND: { if ( wParam == ID_INSTALL ) { InstallSetupFile( hWnd ); return 0; } else if ( wParam == ID_INSTALL_BIG ) { InstallBigSetupFile( hWnd ); } else return DefWindowProc( hWnd, message, wParam, lParam ); } break; ////////////////////////////////////////////////////////////////// case WM_PAINT: { PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint( hWnd, &ps ); HICON hIcon = (HICON) LoadImage( hInst, MAKEINTRESOURCE(3), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR ); DrawIconEx( hdc, ICON_OFFSET, ICON_OFFSET, hIcon, 0, 0, 0, NULL, DI_NORMAL ); // draw the progress DrawProgress( nLastPercent ); DestroyIcon( hIcon ); EndPaint( hWnd, &ps ); return 0; } break; ////////////////////////////////////////////////////////////////// case WM_TIMER: { if( (wParam == APPQUIT_TIMER) && (!bDeleteTemp || !remove(szEXE) ) ) { BOOL bShutDown = FALSE; BOOL bLogoutOnly = FALSE; KillTimer( hWnd, APPQUIT_TIMER ); FILE* pFile = fopen( "shutdown.me", "r" ); if( pFile ) { bShutDown = TRUE; char cBuf[100]; memset( cBuf, 0, 100 ); fread( cBuf, 1, 100, pFile ); if( strcmp(cBuf,"logout") == 0 ) bLogoutOnly = TRUE; fclose( pFile ); } CleanupSetupFile(); if( bShutDown ) { USHORT nOS = GetOSVersion(); if( nOS == OS_NT35 || nOS == OS_NT4 || nOS == OS_NT5 ) { HANDLE hToken; if( OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) ) { TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid ); tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(tp), NULL, NULL ); if( bLogoutOnly ) ExitWindowsEx( EWX_LOGOFF, 0 ); else ExitWindowsEx( EWX_REBOOT, 0 ); CloseHandle( hToken ); } } else ExitWindowsEx( EWX_REBOOT, 0 ); } PostMessage( hWnd, WM_CLOSE, 0, 0 ); } } break; ////////////////////////////////////////////////////////////////// case WM_DESTROY: { PostQuitMessage(0); } break; ////////////////////////////////////////////////////////////////// default: { return DefWindowProc( hWnd, message, wParam, lParam ); } break; } return 0; } // ----------------------------------------------------------------------------- unsigned short WildcardMatch( const char *pWild, const char *pStr ) { int pos=0; int flag=0; while ( *pWild || flag ) { switch (*pWild) { case '?': if ( *pStr == '\0' ) return 0; break; default: if ( (*pWild == '\\') && ((*(pWild+1)=='?') || (*(pWild+1) == '*')) ) pWild++; if ( *pWild != *pStr ) if ( !pos ) return 0; else pWild += pos; else break; // ACHTUNG laeuft unter bestimmten // Umstaenden in den nachsten case rein!! case '*': while ( *pWild == '*' ) pWild++; if ( *pWild == '\0' ) return 1; flag = 1; pos = 0; if ( *pStr == '\0' ) return ( *pWild == '\0' ); while ( *pStr && *pStr != *pWild ) { if ( *pWild == '?' ) { pWild++; while ( *pWild == '*' ) pWild++; } pStr++; if ( *pStr == '\0' ) return ( *pWild == '\0' ); } break; } if ( *pWild != '\0' ) pWild++; if ( *pStr != '\0' ) pStr++; else flag = 0; if ( flag ) pos--; } return ( *pStr == '\0' ) && ( *pWild == '\0' ); } ////////////////////////////////////////////////////////////////////////// // InstallSetupFile() void __EnumFilesCallBack( char *pFile, ULONG nSize, void *pObject ) { nMinTempSize += ( nSize + 1023 ) / 1024; // we need the min temp size in KBytes nTotalSize += nSize; if ( pFile ) { if ( WildcardMatch("sal?.dll", pFile) ) { STRNCPY( strSALLIBName, pFile, sizeof(strSALLIBName) ); bSALLIBFound = TRUE; } else if ( WildcardMatch("uwinapi.dll", pFile) ) { STRNCPY( strUWINAPILIBName, pFile, sizeof(strUWINAPILIBName) ); bUWINAPILIBFound = TRUE; } else if ( WildcardMatch("msvcrt.dll", pFile) ) { STRNCPY( strMSVCRTLIBName, pFile, sizeof(strMSVCRTLIBName) ); bMSVCRTLIBFound = TRUE; } else if ( WildcardMatch("msvcr70.dll", pFile) ) { STRNCPY( strMSVCR70LIBName, pFile, sizeof(strMSVCR70LIBName) ); bMSVCR70LIBFound = TRUE; } else if ( WildcardMatch("stlport*.dll", pFile) ) { STRNCPY( strSTLPORTLIBName, pFile, sizeof(strSTLPORTLIBName) ); bSTLPORTLIBFound = TRUE; } else if ( WildcardMatch("unicows.dll", pFile) ) { STRNCPY( strUNICOWSLIBName, pFile, sizeof(strUNICOWSLIBName) ); bUNICOWSLIBFound = TRUE; } } } void __UnzipCallback(long lBytesWritten) { MSG message; if( PeekMessage(&message, 0, 0, 0, PM_REMOVE) ) { TranslateMessage( &message ); DispatchMessage( &message ); } if ( nTotalSize == 0 ) return; if ( lBytesWritten <= nLastBytesWritten ) nTotalBytesWritten += nLastBytesWritten; nLastBytesWritten = lBytesWritten; long nPercent = ( ( nTotalBytesWritten + lBytesWritten ) / ( nTotalSize / 100 ) ); DrawProgress( nPercent ); } char strFile2Unzip[16*1024]; void __EnumFilesCallBack_getname( char *pFile, ULONG nSize, void *pObject ) { STRNCPY( strFile2Unzip, pFile, sizeof(strFile2Unzip) ); if (strcmp(pFile, strSALLIBName) == 0) bSALLIBFound = TRUE; else bSALLIBFound = FALSE; if (strcmp(pFile, strUWINAPILIBName) == 0) bUWINAPILIBFound = TRUE; else bUWINAPILIBFound = FALSE; if (strcmp(pFile, strMSVCRTLIBName) == 0) bMSVCRTLIBFound = TRUE; else bMSVCRTLIBFound = FALSE; if (strcmp(pFile, strMSVCR70LIBName) == 0) bMSVCR70LIBFound = TRUE; else bMSVCR70LIBFound = FALSE; if (strcmp(pFile, strSTLPORTLIBName) == 0) bSTLPORTLIBFound = TRUE; else bSTLPORTLIBFound = FALSE; if (strcmp(pFile, strUNICOWSLIBName) == 0) bUNICOWSLIBFound = TRUE; else bUNICOWSLIBFound = FALSE; } void UnpackBIG2Temp( ArchDirectory* pBigDir, BOOL bSize ) { ULONG nCnt = pBigDir->GetCount(); ArchEntry** ppRaw = pBigDir->GetRawList(); for( ULONG i = 0; i < nCnt; ++i ) { ArchEntry* pEntry = (ArchEntry*)ppRaw[i]; if( strncmp(pEntry->pName, "f0_", 3) == 0 ) if( bSize ) { pBigDir->GetFile( pEntry->pName, szTempPath ); ::SVUnzipEnumFiles( pEntry->pName, "*", (UnzipEnumFilesCallBack*)__EnumFilesCallBack, NULL ); if (bSALLIBFound) { ::SVUnzip( pEntry->pName, "*.*", (const char*)"qq", NULL ); bSALLIBFound = FALSE; STRNCPY( strSALLIBName_In_ZIP, pEntry->pName, sizeof(strSALLIBName_In_ZIP) ); } if (bUWINAPILIBFound) { ::SVUnzip( pEntry->pName, "*.*", (const char*)"qq", NULL ); bUWINAPILIBFound = FALSE; STRNCPY( strUWINAPILIBName_In_ZIP, pEntry->pName, sizeof(strUWINAPILIBName_In_ZIP) ); } if (bMSVCRTLIBFound) { ::SVUnzip( pEntry->pName, "*.*", (const char*)"qq", NULL ); bMSVCRTLIBFound = FALSE; STRNCPY( strMSVCRTLIBName_In_ZIP, pEntry->pName, sizeof(strMSVCRTLIBName_In_ZIP) ); } if (bMSVCR70LIBFound) { ::SVUnzip( pEntry->pName, "*.*", (const char*)"qq", NULL ); bMSVCR70LIBFound = FALSE; STRNCPY( strMSVCR70LIBName_In_ZIP, pEntry->pName, sizeof(strMSVCR70LIBName_In_ZIP) ); } if (bSTLPORTLIBFound) { ::SVUnzip( pEntry->pName, "*.*", (const char*)"qq", NULL ); bSTLPORTLIBFound = FALSE; STRNCPY( strSTLPORTLIBName_In_ZIP, pEntry->pName, sizeof(strSTLPORTLIBName_In_ZIP) ); } if (bUNICOWSLIBFound) { ::SVUnzip( pEntry->pName, "*.*", (const char*)"qq", NULL ); bUNICOWSLIBFound = FALSE; STRNCPY( strUNICOWSLIBName_In_ZIP, pEntry->pName, sizeof(strUNICOWSLIBName_In_ZIP) ); } unlink( pEntry->pName ); } else { pBigDir->GetFile( pEntry->pName, szTempPath ); if ((strcmp(pEntry->pName, strSALLIBName_In_ZIP) == 0) || (strcmp(pEntry->pName, strUWINAPILIBName_In_ZIP) == 0) || (strcmp(pEntry->pName, strMSVCRTLIBName_In_ZIP) == 0) || (strcmp(pEntry->pName, strMSVCR70LIBName_In_ZIP) == 0) || (strcmp(pEntry->pName, strSTLPORTLIBName_In_ZIP) == 0) || (strcmp(pEntry->pName, strUNICOWSLIBName_In_ZIP) == 0)) { } else { // unpack to get the name only ::SVUnzipEnumFiles( pEntry->pName, "*", (UnzipEnumFilesCallBack*)__EnumFilesCallBack_getname, NULL ); if( strlen(strFile2Unzip) ) { // delete file. char delfile[16*1024]; STRNCPY( delfile, szTempPath, sizeof(delfile) ); STRNCAT( delfile, "\\", sizeof(delfile) ); STRNCAT( delfile, strFile2Unzip, sizeof(delfile) ); unlink( delfile ); } ::SVUnzip( pEntry->pName, "*.*", (const char*)"qq", (UnzipCallBack*) __UnzipCallback ); } unlink( pEntry->pName ); } } } void Unpack2Temp( BOOL bSize ) { char buf[MAX_PATH]; STRNCPY( buf, szSourcePath, sizeof(buf) ); STRNCAT( buf, "\\f0_*.*", sizeof(buf) ); WIN32_FIND_DATA wfData; HANDLE hfnd = FindFirstFile( buf, &wfData ); int nNextFile = 1; while( hfnd != INVALID_HANDLE_VALUE && nNextFile != 0 ) { char file[16*1024]; STRNCPY( file, szSourcePath, sizeof(file) ); STRNCAT( file, "\\", sizeof(file) ); STRNCAT( file, wfData.cFileName, sizeof(file) ); if( bSize ) { ::SVUnzipEnumFiles( file, "*", (UnzipEnumFilesCallBack*)__EnumFilesCallBack, NULL ); if (bSALLIBFound) { ::SVUnzip( file, "*.*", (const char*)"qq", NULL ); bSALLIBFound = FALSE; } if (bUWINAPILIBFound) { ::SVUnzip( file, "*.*", (const char*)"qq", NULL ); bUWINAPILIBFound = FALSE; } if (bMSVCRTLIBFound) { ::SVUnzip( file, "*.*", (const char*)"qq", NULL ); bMSVCRTLIBFound = FALSE; } if (bMSVCR70LIBFound) { ::SVUnzip( file, "*.*", (const char*)"qq", NULL ); bMSVCR70LIBFound = FALSE; } if (bSTLPORTLIBFound) { ::SVUnzip( file, "*.*", (const char*)"qq", NULL ); bSTLPORTLIBFound = FALSE; } if (bUNICOWSLIBFound) { ::SVUnzip( file, "*.*", (const char*)"qq", NULL ); bUNICOWSLIBFound = FALSE; } } else { ::SVUnzipEnumFiles( file, "*", (UnzipEnumFilesCallBack*)__EnumFilesCallBack_getname, NULL ); if ( bSALLIBFound || bUWINAPILIBFound || bMSVCRTLIBFound || bMSVCR70LIBFound || bSTLPORTLIBFound || bUNICOWSLIBFound ) {} else { if( strlen(strFile2Unzip) ) { char delfile[16*1024]; STRNCPY( delfile, szTempPath, sizeof(delfile) ); STRNCAT( delfile, "\\", sizeof(delfile) ); STRNCAT( delfile, strFile2Unzip, sizeof(delfile) ); unlink( delfile ); } ::SVUnzip( file, "*.*", (const char*)"qq", (UnzipCallBack*) __UnzipCallback ); } } nNextFile = FindNextFile( hfnd, &wfData ); } FindClose( hfnd ); } void InstallSetupFile( HWND hWnd, ArchDirectory* pBigDir ) { int nErr, nIndex; DWORD dwFreeSize = 0; FILE* pFile; char cError[250]; // create source path nIndex = lstrlen( szModuleFileName ); while ( szModuleFileName[nIndex] != '\\' ) nIndex--; if ( nIndex > sizeof( szSourcePath ) - 1 ) nIndex = sizeof( szSourcePath ) - 1; STRNCPY( szSourcePath, szModuleFileName, nIndex+1 ); // get temp path GetTempFile( szTempPath, sizeof( szTempPath ) ); if ( szTempPath[0] != '\0' ) nErr = mkdir( szTempPath ); else { ErrorBox( hWnd, IDS_NOTEMPDIR, NULL ); return; } if( nErr == -1 ) { char szTmp[100]; LoadString( hInst, IDS_TEMPDIR, szTmp, sizeof(szTmp) ); STRNCPY( cError, szTmp, sizeof(cError) ); STRNCAT( cError, szTempPath, sizeof(cError) ); LoadString( hInst, IDS_MAKEDIR, szTmp, sizeof(szTmp) ); STRNCAT( cError, szTmp, sizeof(cError) ); ErrorBox( hWnd, 0, cError ); return; } nOldDrive = _getdrive(); getcwd( szOldPath, 256 ); // Ins Zielverzeichnis wechseln _chdrive( toupper( szTempPath[0] ) - 'A' + 1 ); if( chdir( szTempPath ) == -1 ) { char szTmp[100]; LoadString( hInst, IDS_TEMPDIR, szTmp, sizeof(szTmp) ); STRNCPY( cError, szTmp, sizeof(cError) ); STRNCAT( cError, szTempPath, sizeof(cError) ); LoadString( hInst, IDS_SETCWD, szTmp, sizeof(szTmp) ); STRNCAT( cError, szTmp, sizeof(cError) ); ErrorBox( hWnd, 0, cError ); return; } ExtractUnloader(); // LLA: we need the sal?.dll for function CheckForUpdate, therefor the // Unpack2Temp function checks the size and at the same time, unpack the sal?.dll into // the temp directory if( !pBigDir ) Unpack2Temp( TRUE ); else UnpackBIG2Temp( pBigDir, TRUE ); nMinTempSize += 1024 /* * 1024*/; // Due to some differences between clustersizes, little bit more BOOL bError = CheckForUpdate(pBigDir, CFU_CheckFileSize_Magic); GETDISKFREESPACE(dwFreeSize, szTempPath); if( dwFreeSize < nMinTempSize ) { ErrorBox( hWnd, IDS_NOTEMPSPACE, NULL ); return; } bError = CheckForUpdate(pBigDir, CFU_CopyFiles_Magic); if (bError) { return; } if( !pBigDir ) Unpack2Temp( FALSE ); else UnpackBIG2Temp( pBigDir, FALSE ); if ( nErr > 1 && nErr != 50 ) { char szErr[250]; char cErrCode[10]; ltoa( nErr, cErrCode, 10 ); LoadString( hInst, IDS_NOUNZIP, szErr, sizeof(szErr) ); STRNCAT( szErr, "\nErrorcode: ", sizeof(szErr) ); STRNCAT( szErr, cErrCode, sizeof(szErr) ); ErrorBox( hWnd, 0, szErr ); return; } // --------------------------------- setup.ini --------------------------------- STRNCPY( szSetupINI, szTempPath, sizeof(szSetupINI) ); STRNCAT( szSetupINI, "\\setup.ini", sizeof(szSetupINI) ); pFile = fopen( szSetupINI, "a+" ); if ( pFile ) { fprintf( pFile, "[source]\n" ); if( pBigDir ) { fprintf( pFile, "path=%s\n", szModuleFileName ); fprintf( pFile, "big=1\n" ); fprintf( pFile, "offset=%ld\n", nBigDataOffset ); } else if ( strlen(szSourcePath) == 2 ) { char szTmp[4]; strncpy( szTmp, szSourcePath, 2 ); szTmp[2] = '\\'; szTmp[3] = 0; fprintf( pFile, "path=%s\n", szTmp ); } else if( strlen(strWEBStartPath) ) fprintf( pFile, "path=%s\n", strWEBStartPath ); else fprintf( pFile, "path=%s\n", szSourcePath ); fprintf( pFile, "[share]\n" ); fprintf( pFile, "load=0\n" ); fclose( pFile ); } // ---------------------------------- Uno.ini ---------------------------------- // #91782# STRNCPY( szUnoINI, szTempPath, sizeof(szUnoINI) ); STRNCAT( szUnoINI, "\\uno.ini", sizeof(szUnoINI) ); pFile = fopen( szUnoINI, "a+" ); if ( pFile ) { fprintf( pFile, "[bootstrap]\n"); fprintf( pFile, "UNO_TYPES = types.rdb\n"); fprintf( pFile, "UNO_SERVICES = setup_services.rdb" ); fclose( pFile ); } // -------------------------------------- SpecialFontHandling( szTempPath ); // Das eigentliche Setup Programm starten STRNCPY( szSetupEXE, szTempPath, sizeof(szSetupEXE) ); STRNCAT( szSetupEXE, "\\setup.exe", sizeof(szSetupEXE) ); STRNCPY( szEXE, szSetupEXE, sizeof(szEXE) ); STRNCAT( szSetupEXE, " ", sizeof(szSetupEXE) ); STRNCAT( szSetupEXE, szCommandLine, sizeof(szSetupEXE) ); if ( bPatchMode ) { STRNCAT( szSetupEXE, " \"-patch:", sizeof(szSetupEXE) ); STRNCAT( szSetupEXE, szOfficePath, sizeof(szSetupEXE) ); STRNCAT( szSetupEXE, "\"", sizeof(szSetupEXE) ); } // set command nCommand = 1 + szSourcePath[0] - 'A'; // vorher mein Fenster schliessen ShowWindow( hWnd, SW_HIDE ); UpdateWindow( hWnd ); hInstallInst = WinExec( szSetupEXE, SW_SHOW ); if( hInstallInst < 32 ) { // Error occured PostMessage( hWnd, WM_CLOSE, 0, 0 ); return; } SetTimer( hWnd, APPQUIT_TIMER, 100, NULL ); } ////////////////////////////////////////////////////////////////////////// // ExtractUnloader() void ExtractUnloader() { if( !nUnloaderOffset ) return; FILE* pThisFile = fopen( szModuleFileName, "rb" ); if( !pThisFile ) return; fseek( pThisFile, 0, SEEK_END ); DWORD nSz = ftell( pThisFile ); DWORD nUnloaderSz = nBigDataOffset? nBigDataOffset - nUnloaderOffset : nSz - nUnloaderOffset; char cFilename[_MAX_PATH]; GetWindowsDirectory( cFilename, _MAX_PATH ); STRNCAT( cFilename, "\\", sizeof(cFilename) ); STRNCAT( cFilename, UNLOADER_FILENAME, sizeof(cFilename) ); FILE* pUnloaderFile = fopen(cFilename, "r"); if( pUnloaderFile ) { fclose( pUnloaderFile ); DeleteFile( cFilename ); } pUnloaderFile = fopen(cFilename, "wb"); if( !pUnloaderFile ) { fclose( pThisFile ); return; } char cBuf[CPY_BUF_SZ]; fseek( pThisFile, nUnloaderOffset, SEEK_SET ); while( nUnloaderSz ) { DWORD nToRead = nUnloaderSz > CPY_BUF_SZ? CPY_BUF_SZ : nUnloaderSz; DWORD nRead = fread( cBuf, 1, nToRead, pThisFile ); fwrite( cBuf, nToRead, 1, pUnloaderFile ); nUnloaderSz -= nToRead; } fclose( pThisFile ); fclose( pUnloaderFile ); } ////////////////////////////////////////////////////////////////////////// // InstallBigSetupFile() void InstallBigSetupFile( HWND hWnd ) { ArchDirectory aDir; if( !aDir.SetArchFile(szModuleFileName) ) { ErrorBox( hWnd, 0, aDir.GetErrorMsg() ); exit( -1 ); } if( bExtractBIG ) { USHORT nLen = strlen(strExtractPath); if( nLen ) { if( chdir(strExtractPath) == -1 ) { char cError[MAX_PATH * 2]; if ( nLen >= MAX_PATH ) strExtractPath[ MAX_PATH-1 ] = '\0'; sprintf( cError, "ERROR: could not change directory (%s)", strExtractPath ); // #100211# - checked ErrorBox( hWnd, 0, cError ); exit( -1 ); } } else { STRNCPY( strExtractPath, ".", sizeof(strExtractPath) ); } aDir.ExtractAll( strExtractPath ); exit( 0 ); } else InstallSetupFile( hWnd, &aDir ); } ////////////////////////////////////////////////////////////////////////// // CleanupSetupFile() void CleanupSetupFile() { if ( szTempPath[0] == '\0' ) return; // Testdatei schliesen und loeschen if ( hLoaderTemp ) { _lclose( hLoaderTemp ); remove( strLoaderTemp ); hLoaderTemp = NULL; } // Temp-Verzeichnis loeschen if (bDeleteTemp) { KillTempPath( szTempPath ); } // Vorheriges Arbeitsverzeichnis wiederherstellen chdir( szOldPath ); _chdrive( nOldDrive ); } ////////////////////////////////////////////////////////////////////////// // ErrorBox() void ErrorBox( HWND hWnd, UINT nErrorID, LPSTR pError ) { char szTitle[50]; char szMessage[250]; LoadString( hInst, IDS_TITLE, szTitle, sizeof(szTitle) ); if ( !pError ) { LoadString( hInst, nErrorID, szMessage, sizeof(szMessage) ); MessageBox( hWnd, szMessage, szTitle, MB_OK | MB_ICONSTOP ); } else MessageBox( hWnd, pError, szTitle, MB_OK | MB_ICONSTOP ); bError = TRUE; PostMessage( hWnd, WM_CLOSE, 0, 0 ); } ////////////////////////////////////////////////////////////////////////// // InfoBox() void InfoBox( HWND hWnd, LPSTR pInfo ) { char szTitle[50]; LoadString( hInst, IDS_TITLE, szTitle, sizeof(szTitle) ); MessageBox( hWnd, pInfo, szTitle, MB_OK | MB_ICONINFORMATION ); } ////////////////////////////////////////////////////////////////////////// // InfoBox() BOOL InfoBox( HWND hWnd, UINT nInfo, UINT nTitle ) { char cInfo[255]; char cTitle[255]; LoadString( hInst, nInfo, cInfo, sizeof(cInfo) ); LoadString( hInst, nTitle, cTitle, sizeof(cTitle) ); int i=0; while ( cInfo[i] != 0 ) { if ( ( cInfo[i] == '\\' ) && ( cInfo[i+1] == 'n' ) ) { cInfo[i] = 0x0d; cInfo[i+1] = 0x0a; i+=2; } else i+=1; } int nRet = MessageBox( hWnd, cInfo, cTitle, MB_OKCANCEL | MB_ICONINFORMATION ); if ( nRet == IDOK ) return TRUE; else return FALSE; } ////////////////////////////////////////////////////////////////////////// // draw rect void DrawProgress( long nPercent ) { if ( nPercent > 100 ) nPercent = 100; else if ( nPercent < 0 ) nPercent = 0; if ( nPercent <= nLastPercent ) return; else nLastPercent = nPercent; HDC hdc = GetDC( hWnd ); // draw the progress RECT aRect; HBRUSH hBrush = CreateSolidBrush( RGB( 0, 0, 0 ) ); GetClientRect( hWnd, &aRect ); aRect.right -= PROGRESS_OFFSET; aRect.left = aRect.right - PROGRESS_WIDTH - 2; aRect.top += ( aRect.bottom - aRect.top - PROGRESS_HEIGHT - 2 ) / 2; aRect.bottom = aRect.top + PROGRESS_HEIGHT + 2; FrameRect( hdc, &aRect, hBrush ); DeleteObject(hBrush); hBrush = CreateSolidBrush( RGB( 0, 0, 128 ) ); aRect.right -= ( 1 + PROGRESS_WIDTH ); aRect.left = aRect.right + ( PROGRESS_WIDTH * nLastPercent / 100 ); aRect.top += 1; aRect.bottom -= 1; FillRect( hdc, &aRect, hBrush ); DeleteObject(hBrush); ReleaseDC( hWnd, hdc ); } // ----------------------------------------------------------------------------- // #99028# Update functions // LLA: WINDOWS SPECIFIC CODE BOOL CheckFile(const char* _pFilePath) { struct _stat aStat; if (_stat(_pFilePath, &aStat) != 0) // does not exist { return FALSE; } return TRUE; } // ----------------------------------------------------------------------------- BOOL CheckDirectory(char* strDir) { struct _stat aStat; if (_stat(strDir, &aStat) == 0 // vorhanden && (aStat.st_mode & S_IFDIR) != 0) // und ein Verzeichnis { return TRUE; } return FALSE; } // ----------------------------------------------------------------------------- // copied from nwinos.cxx // ----------------------------------------------------------------------------- void _SHFree( void *pv ) { IMalloc *pMalloc; if( NOERROR == SHGetMalloc(&pMalloc) ) { pMalloc->Free( pv ); pMalloc->Release(); } } BOOL __SHGetSpecialFolder( int nFolderID, char* buf, long nBufSize ) { //returns true if no error occured LPITEMIDLIST pidl; HRESULT hHdl = SHGetSpecialFolderLocation( NULL, nFolderID, &pidl ); if( hHdl == NOERROR ) { char pszPath[_MAX_PATH]; SHGetPathFromIDList( pidl, pszPath ); STRNCPY( buf, pszPath, nBufSize ); _SHFree( pidl ); return true; } return false; } void _SHGetSpecialFolder( int nFolderID, char* buf, long nBufSize ) { if( !__SHGetSpecialFolder( nFolderID, buf, nBufSize ) ) GetWindowsDirectory( buf, MAX_PATH ); } void getHomeDir( char *buf, long nBufSize ) { _SHGetSpecialFolder( CSIDL_APPDATA, buf, nBufSize ); } // ----------------------------------------------------------------------------- void CopyFiles(char* _pSourcePath, char* _pDestPath, char *_pPattern, CheckFileMagic aMagic) { WIN32_FIND_DATA aFind; HANDLE aHdl; char strPath[_MAX_PATH]; STRNCPY( strPath, _pSourcePath, sizeof(strPath) ); char strPathPattern[_MAX_PATH]; STRNCPY( strPathPattern, strPath, sizeof(strPathPattern) ); STRNCAT( strPathPattern, "\\", sizeof(strPathPattern) ); STRNCAT( strPathPattern, _pPattern, sizeof(strPathPattern) ); aHdl = FindFirstFile( strPathPattern, &aFind ); if ( aHdl == INVALID_HANDLE_VALUE ) { return; } do { char cFullFile[MAX_PATH]; STRNCPY( cFullFile, strPath, sizeof(cFullFile) ); STRNCAT( cFullFile, "\\", sizeof(cFullFile) ); STRNCAT( cFullFile, aFind.cFileName, sizeof(cFullFile) ); char cDestFile[_MAX_PATH]; STRNCPY( cDestFile, _pDestPath, sizeof(cDestFile) ); STRNCAT( cDestFile, "\\", sizeof(cDestFile) ); STRNCAT( cDestFile, aFind.cFileName, sizeof(cDestFile) ); CopyZipFile(cFullFile, cDestFile, aMagic); } while ( FindNextFile( aHdl, &aFind ) ); FindClose( aHdl ); } // ----------------------------------------------------------------------------- void UnpackOneFileFromBIG2Temp( ArchDirectory* pBigDir, char* strFilename ) { ULONG nCnt = pBigDir->GetCount(); ArchEntry** ppRaw = pBigDir->GetRawList(); for( ULONG i = 0; i < nCnt; ++i ) { ArchEntry* pEntry = (ArchEntry*)ppRaw[i]; if( strcmp(pEntry->pName, strFilename) == 0 ) { pBigDir->GetFile( pEntry->pName, szTempPath ); } } } // ----------------------------------------------------------------------------- int readline(FILE* _pFile, char* _pBuffer, int _nMaxValues) { int i = 0; if (_pFile) { --_nMaxValues; while( !feof(_pFile) && _nMaxValues) { char c = fgetc(_pFile); if( c == (char)0xFF ) continue; if( c == 0x0a || c == 0x0d ) { // because, dos/windows use 2 bytes for lineending c = fgetc(_pFile); if( c != 0x0a && c != 0x0d ) { ungetc(c, _pFile); } // ok, found a line, lets check values. break; } _pBuffer[i++] = c; _nMaxValues --; } } _pBuffer[i] = '\0'; return i; } // ----------------------------------------------------------------------------- int CheckForSlash(char* _pStr) { int i = 0; char c; while(c = _pStr[i++]) { if (c == '\\' || c == '/') { return i - 1; } } return 0; } // ----------------------------------------------------------------------------- void CopyFilesFromList(char* _pSourcePath, char* _pDestPath, char *_pStrPathList, char* _pStrListName, CheckFileMagic aMagic) { char strListPath[_MAX_PATH]; STRNCPY( strListPath, _pStrPathList, sizeof(strListPath) ); STRNCAT( strListPath, "\\", sizeof(strListPath) ); STRNCAT( strListPath, _pStrListName, sizeof(strListPath) ); char cLineBuf[_MAX_PATH]; FILE* pFile = fopen(strListPath, "r"); if (pFile) { readline(pFile, cLineBuf, _MAX_PATH); // ProductName ProductNumber while( !feof(pFile) ) { int nLen = readline(pFile, cLineBuf, _MAX_PATH ); if ( nLen ) { __EnumFilesCallBack_getname( cLineBuf, 0, NULL ); if ( bSALLIBFound || bUWINAPILIBFound || bMSVCRTLIBFound || bMSVCR70LIBFound || bSTLPORTLIBFound || bUNICOWSLIBFound ) nLen = 0; } if (nLen > 0) { char strSourcePath[_MAX_PATH]; STRNCPY(strSourcePath, _pSourcePath, sizeof(strSourcePath) ); if (nLen = CheckForSlash(cLineBuf)) { STRNCAT( strSourcePath, "\\", sizeof(strSourcePath) ); if ( nLen > (int) (sizeof(strSourcePath) - strlen(strSourcePath) - 1) ) nLen = sizeof(strSourcePath) - strlen(strSourcePath) - 1; strncat(strSourcePath, cLineBuf, nLen); char strTemp[_MAX_PATH]; STRNCPY( strTemp, cLineBuf + nLen + 1, sizeof(strTemp) ); STRNCPY( cLineBuf, strTemp, sizeof(cLineBuf) ); } CopyFiles(strSourcePath, _pDestPath, cLineBuf, aMagic); } } fclose(pFile); } } // ----------------------------------------------------------------------------- BOOL OpenPatchFile(char* _pStrSourcePath, char* strName) { char strPatchPath[MAX_PATH]; STRNCPY( strPatchPath, _pStrSourcePath, sizeof(strPatchPath) ); STRNCAT( strPatchPath, "\\", sizeof(strPatchPath) ); STRNCAT( strPatchPath, "patch.inf", sizeof(strPatchPath) ); FILE* pFile = fopen(strPatchPath, "r"); if (!pFile) { return FALSE; } /* allocate a buffer for file I/O */ int nLen = readline( pFile, strName, MAX_PATH); fclose(pFile); return TRUE; } #define MAXLINEBUF 1024 // ----------------------------------------------------------------------------- BOOL ReadStringFromProfile( char* _pStrProfile, char* _pSection, char* _pStrName, char* _pStrValue, long _nBufSize ) { BOOL bValue = FALSE; BOOL bSectionFound = FALSE; char strSection[MAX_PATH]; strncpy( strSection, "[", 2 ); STRNCAT( strSection, _pSection, sizeof(strSection) ); STRNCAT( strSection, "]", sizeof(strSection) ); FILE* pFile = fopen( _pStrProfile, "r" ); if (pFile) { char cLineBuf[MAXLINEBUF]; while( !feof(pFile) ) { int nLen = readline(pFile, cLineBuf, MAXLINEBUF ); // ok, found a line, lets check values. if (cLineBuf[0] == '[') { if (strncmp(strSection, cLineBuf, strlen(strSection)) == 0) { bSectionFound = TRUE; } else { bSectionFound = FALSE; } } if (bSectionFound && strncmp(cLineBuf, _pStrName, strlen(_pStrName)) == 0) { // Searched Value found, search for '=' skiping whitespaces int i = strlen(_pStrName); while (iswspace(cLineBuf[i]) && (i < nLen)) ++ i; if ( ( i < nLen ) && ( cLineBuf[i] == '=' ) ) { // stop more searching, because found value. STRNCPY( _pStrValue, cLineBuf + i + 1, _nBufSize ); bValue = TRUE; break; } } } fclose(pFile); } return bValue; } // ----------------------------------------------------------------------------- void unEscapeStr(char *_pStrURL, char* _pStr) { int nLen = strlen(_pStrURL); int i = 0; int j = 0; int nEscapeValue = 0; while (_pStrURL[i] == ' ') // remove leading spaces { ++i; } if (strncmp(_pStrURL + i, "file:///", 8) == 0) // remove file:/// { i += 8; } while (i < nLen) // change escaped characters { char c = _pStrURL[i++]; if (c == '%') { nEscapeValue = ((_pStrURL[i] - '0') << 4) | (_pStrURL[i + 1] - '0'); c = (char)nEscapeValue; i += 2; } else if (c == '/') // '/' to '\' { c = '\\'; } else if (c == 0x0d || c == 0x0a) { continue; } _pStr[j++] = c; } _pStr[j] = '\0'; } // ----------------------------------------------------------------------------- typedef oslFileError (SAL_CALL * osl_getSystemPathFromFileURL_Func)( rtl_uString *ustrURL, rtl_uString **pustrPath); typedef void (SAL_CALL * rtl_uString_newFromAscii_Func)( rtl_uString ** newStr, const sal_Char * value ) SAL_THROW_EXTERN_C(); BOOL getSystemPathFromFileURL(char* strTempPath, char* strURL, char* strSystemPath) { // Load library char strSALInTemp[MAX_PATH]; STRNCPY( strSALInTemp, strTempPath, sizeof(strSALInTemp) ); STRNCAT( strSALInTemp, "\\", sizeof(strSALInTemp) ); STRNCAT( strSALInTemp, strSALLIBName, sizeof(strSALInTemp) ); HMODULE hModule = LoadLibrary(strSALInTemp); if (hModule) { FARPROC pProc = GetProcAddress(hModule, "rtl_uString_newFromAscii"); if (pProc == NULL) { return FALSE; } rtl_uString_newFromAscii_Func rtl_uString_newFromAscii2 = reinterpret_cast(pProc); rtl_uString* psuURL = 0; rtl_uString_newFromAscii2( &psuURL, strURL ); FARPROC pProc2 = GetProcAddress(hModule, "osl_getSystemPathFromFileURL"); if (pProc2 == NULL) { return FALSE; } osl_getSystemPathFromFileURL_Func osl_getSystemPathFromFileURL2 = reinterpret_cast(pProc2); rtl_uString* psuSystemPath = 0L; osl_getSystemPathFromFileURL2(psuURL, &psuSystemPath); // Windows code, to convert WideChar to char* (Multibyte) int needed = WideCharToMultiByte(CP_ACP,0, psuSystemPath->buffer, -1, NULL, 0, NULL, NULL); // char pSubKey[260]; WideCharToMultiByte(CP_ACP,0, psuSystemPath->buffer, -1, strSystemPath, needed, NULL, NULL); FreeLibrary(hModule); return TRUE; } return FALSE; } // ----------------------------------------------------------------------------- BOOL OpenSVersion(char* strNames, char* strInstPath, char* strTempPath) { char strPath[_MAX_PATH]; getHomeDir( strPath, sizeof( strPath ) ); STRNCAT( strPath, "\\", sizeof(strPath) ); #ifdef WIN32 STRNCAT( strPath, "sversion.ini", sizeof(strPath) ); #else STRNCAT( strPath, ".sversionrc", sizeof(strPath) ); #endif char strURLFile[_MAX_PATH]; char* strName = strtok(strNames, ";"); do { if (ReadStringFromProfile(strPath, "Versions", strName, strURLFile, sizeof(strURLFile))) { return getSystemPathFromFileURL(strTempPath, strURLFile, strInstPath); } strName = strtok(NULL, ";"); } while (strName); return FALSE; } // ----------------------------------------------------------------------------- BOOL CheckForString(char* strSource, char* strSearch) { char* sFound = strchr(strSource, strSearch[0]); if (sFound) { if (strncmp(sFound, strSearch, strlen(strSearch)) == 0) { return TRUE; } } return FALSE; } // ----------------------------------------------------------------------------- BOOL ReadInstDBInf(char* _strInstDBInfFilePath, char* strOfficeProgramPath) { char cLineBuf[_MAX_PATH]; memset( cLineBuf, 0, _MAX_PATH ); BOOL bError = TRUE; FILE* pFile = fopen(_strInstDBInfFilePath, "r"); if (pFile) { while(!feof(pFile) ) { readline(pFile, cLineBuf, _MAX_PATH); // ProductName ProductNumber if (CheckForString(cLineBuf, "SourcePath")) { break; } } if (!feof(pFile)) { char* sDoubleQuote = strchr(cLineBuf, '\"'); sDoubleQuote++; int i = 0; while (sDoubleQuote[0] != '\0') { strOfficeProgramPath[i++] = *sDoubleQuote++; if (sDoubleQuote[0] == '\"') { strOfficeProgramPath[i] = '\0'; getSystemPathFromFileURL( szTempPath, strOfficeProgramPath, strOfficeProgramPath ); bError = FALSE; break; } } } } return bError; } // ----------------------------------------------------------------------------- BOOL CheckForUpdate(ArchDirectory* pBigDir, CheckFileMagic aMagic) { // !!!! Copy all files from Product to temp dir char strNames[_MAX_PATH]; if (pBigDir) { UnpackOneFileFromBIG2Temp(pBigDir, "patch.inf"); } else { CopyFiles(szSourcePath, szTempPath, "patch.inf", CFU_CopyFiles_Magic); // always copy, because we need the patch.inf to know what files we want to open } BOOL bError = FALSE; if (OpenPatchFile(szTempPath, strNames)) { char strInstPath[_MAX_PATH]; // First, try to find installed office via sverion.ini if ( !bOfficePathFound && !OpenSVersion( strNames, strInstPath, szTempPath ) ) { // When there is only a network installation without a workstation installation, // there is no entry in the sversion.ini and we have to ask the user for // the path to the office if ( InfoBox( hWnd, IDS_CHOOSEPATH, IDS_TITLECHOOSEPATH ) ) bError = ! BrowseForInstall( strInstPath ); else bError = TRUE; } while ( !bOfficePathFound && !bError ) { // We first check for instdb.inf in the given path ( strInstPath ). // When we find a instdb.inf here, we got a path to a workstation installation // and have to look for the corresponding network installation char strOfficeInstDBInfPath[_MAX_PATH]; STRNCPY( strOfficeInstDBInfPath, strInstPath, sizeof(strOfficeInstDBInfPath) ); STRNCAT( strOfficeInstDBInfPath, "\\instdb.inf", sizeof(strOfficeInstDBInfPath) ); if (CheckFile(strOfficeInstDBInfPath)) { // ok, we need to read instdb.inf and search to source="" bError = ReadInstDBInf(strOfficeInstDBInfPath, szOfficeProgramPath); if (!bError) { STRNCPY( szOfficePath, szOfficeProgramPath, sizeof(szOfficePath) ); STRNCAT( szOfficeProgramPath, "\\program", sizeof(szOfficeProgramPath) ); } } else { // When there is no instdb.inf file, it has to be inside the folder 'program' STRNCPY( szOfficePath, strInstPath, sizeof(szOfficePath) ); STRNCAT( szOfficeProgramPath, strInstPath, sizeof(szOfficeProgramPath) ); STRNCAT( szOfficeProgramPath, "\\program", sizeof(szOfficeProgramPath) ); STRNCPY( strOfficeInstDBInfPath, strInstPath, sizeof(strOfficeInstDBInfPath) ); STRNCAT( strOfficeInstDBInfPath, "\\program", sizeof(strOfficeInstDBInfPath) ); STRNCAT( strOfficeInstDBInfPath, "\\instdb.inf", sizeof(strOfficeInstDBInfPath) ); if ( ! CheckDirectory( szOfficeProgramPath ) ) bError = TRUE; else if ( !CheckFile( strOfficeInstDBInfPath ) ) bError = TRUE; } if ( bError ) { // ERROR, the path found in the sversion.ini or chosen by the user // doesn't contain a valid office installation, let the user choose // another path if ( InfoBox( hWnd, IDS_NOSOFFICE, IDS_TITLENOOFFICE ) ) bError = ! BrowseForInstall( strInstPath ); else bError = TRUE; } else { bOfficePathFound = TRUE; } } if ( bOfficePathFound && !bError ) { bPatchMode = TRUE; CopyFilesFromList( szOfficeProgramPath, szTempPath, szTempPath, "patch.inf", aMagic ); } else if ( bError ) { PostMessage( hWnd, WM_CLOSE, 0, 0 ); } } return bError; } // ------------------------------------------------------------------------------------- // // Code for choosing folder to office network installation // // ------------------------------------------------------------------------------------- BOOL BrowseForInstall( char* strPath ) { BOOL bRet = FALSE; LPITEMIDLIST pidlRoot = NULL; LPITEMIDLIST pidlSelected = NULL; BROWSEINFO bi = {0}; LPMALLOC pMalloc = NULL; char cName[_MAX_PATH]; char cTxt[255]; LoadString( hInst, IDS_CHOOSETITLE, cTxt, sizeof(cTxt) ); SHGetMalloc(&pMalloc); bi.hwndOwner = hWnd; bi.pidlRoot = pidlRoot; bi.pszDisplayName = cName; bi.lpszTitle = cTxt; bi.ulFlags = 0; bi.lpfn = NULL; bi.lParam = 0; pidlSelected = SHBrowseForFolder(&bi); if( pidlRoot ) { pMalloc->Free(pidlRoot); } pMalloc->Release(); if ( pidlSelected ) { SHGetPathFromIDList( pidlSelected, strPath ); // Make sure it is a path bRet = TRUE; } return bRet; } #if 0 static BOOL getFileURLFromSystemPath( const char * szPath, char * szUrl) { BOOL ret= FALSE; HINSTANCE moduleSal= LoadLibrary( SALLIBNAME); if( ! moduleSal) return FALSE; typedef rtl_TextEncoding ( SAL_CALL * osl_getThreadTextEncodingType)(); typedef void ( SAL_CALL * rtl_string2UStringType) (rtl_uString ** newStr,const sal_Char * str, sal_Int32 len, rtl_TextEncoding encoding, sal_uInt32 convertFlags ); typedef oslFileError ( SAL_CALL * osl_getFileURLFromSystemPathType)( rtl_uString *ustrSystemPath, rtl_uString **pustrFileURL); typedef void ( SAL_CALL * rtl_uString2StringType)( rtl_String ** newStr, const sal_Unicode * str, sal_Int32 len, rtl_TextEncoding encoding, sal_uInt32 convertFlags ); typedef void (SAL_CALL * rtl_string_releaseType)( rtl_String * str ); typedef void (SAL_CALL * rtl_uString_releaseType)( rtl_uString * str ); osl_getThreadTextEncodingType p_osl_getThreadTextEncoding= (osl_getThreadTextEncodingType) GetProcAddress( moduleSal, "osl_getThreadTextEncoding"); osl_getFileURLFromSystemPathType p_osl_getFileURLFromSystemPath= (osl_getFileURLFromSystemPathType) GetProcAddress( moduleSal, "osl_getFileURLFromSystemPath"); rtl_string2UStringType p_rtl_string2UString= (rtl_string2UStringType) GetProcAddress( moduleSal, "rtl_string2UString"); rtl_uString2StringType p_rtl_uString2String= (rtl_uString2StringType) GetProcAddress( moduleSal, "rtl_uString2String"); rtl_string_releaseType p_rtl_string_release= (rtl_string_releaseType) GetProcAddress( moduleSal, "rtl_string_release"); rtl_uString_releaseType p_rtl_uString_release= (rtl_uString_releaseType) GetProcAddress( moduleSal, "rtl_uString_release"); rtl_uString * usTempPath= NULL; rtl_TextEncoding enc= p_osl_getThreadTextEncoding(); p_rtl_string2UString( &usTempPath, szPath, strlen(szTempPath), enc, OSTRING_TO_OUSTRING_CVTFLAGS ); rtl_uString * usFileUrl= NULL; rtl_String * sFileUrl= NULL; if( p_osl_getFileURLFromSystemPath( usTempPath, &usFileUrl) == 0) { p_rtl_uString2String( &sFileUrl, usFileUrl->buffer, usFileUrl->length, enc, OUSTRING_TO_OSTRING_CVTFLAGS); ret= TRUE; } strcpy( szUrl, sFileUrl->buffer); // #100211# - checked (unused code!) p_rtl_string_release( sFileUrl); p_rtl_uString_release( usFileUrl); p_rtl_uString_release( usTempPath); FreeLibrary( moduleSal); return ret; } #endif