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 #include "precompiled_desktop.hxx" 29 #define UNICODE 30 #define _UNICODE 31 32 #define WIN32_LEAN_AND_MEAN 33 #if defined _MSC_VER 34 #pragma warning(push, 1) 35 #endif 36 #include <windows.h> 37 #include <shellapi.h> 38 #include <imagehlp.h> 39 #include <wchar.h> 40 #if defined _MSC_VER 41 #pragma warning(pop) 42 #endif 43 44 #include <time.h> 45 #include "sal/config.h" 46 #include "tools/pathutils.hxx" 47 48 #define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1) 49 #define MY_STRING(s) (s), MY_LENGTH(s) 50 51 const int FORMAT_MESSAGE_SIZE = 4096; 52 const DWORD PE_Signature = 0x00004550; 53 const DWORD BASEVIRTUALADDRESS = 0x10000000; 54 55 namespace 56 { 57 58 bool IsValidHandle( HANDLE handle ) 59 { 60 return ((NULL != handle) && (INVALID_HANDLE_VALUE != handle)); 61 } 62 63 void fail() 64 { 65 LPWSTR buf = NULL; 66 FormatMessageW( 67 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, 68 GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL); 69 MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR); 70 LocalFree(buf); 71 TerminateProcess(GetCurrentProcess(), 255); 72 } 73 74 bool rebaseImage( wchar_t* pszFilePath, ULONG nNewImageBase) 75 { 76 ULONG ulOldImageSize; 77 ULONG_PTR lpOldImageBase; 78 ULONG ulNewImageSize; 79 ULONG_PTR lpNewImageBase = nNewImageBase; 80 ULONG ulDateTimeStamp = 0; 81 bool bResult(false); 82 83 char cszFilePath[_MAX_PATH+1] = {0}; 84 int nResult = WideCharToMultiByte(CP_ACP, 0, pszFilePath, -1, cszFilePath, _MAX_PATH, NULL, NULL); 85 86 if (nResult != 0) 87 { 88 BOOL bResult = ReBaseImage( 89 cszFilePath, 90 "", 91 TRUE, 92 FALSE, 93 FALSE, 94 0, 95 &ulOldImageSize, 96 &lpOldImageBase, 97 &ulNewImageSize, 98 &lpNewImageBase, 99 ulDateTimeStamp ); 100 } 101 102 return bResult; 103 } 104 105 wchar_t* getBrandPath(wchar_t * path) 106 { 107 DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH); 108 if (n == 0 || n >= MAX_PATH) { 109 exit(EXIT_FAILURE); 110 } 111 return tools::filename(path); 112 } 113 114 void rebaseImagesInFolder( wchar_t* pszFolder, DWORD nNewImageBase ) 115 { 116 wchar_t szPattern[MAX_PATH]; 117 wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' ); 118 if ( lpLastSlash ) 119 { 120 size_t len = lpLastSlash - pszFolder + 1; 121 wcsncpy( szPattern, pszFolder, len ); 122 wcsncpy( szPattern + len, TEXT("*.dll"), sizeof(szPattern)/sizeof(szPattern[0]) - len ); 123 } 124 125 WIN32_FIND_DATA aFindFileData; 126 HANDLE hFind = FindFirstFile( szPattern, &aFindFileData ); 127 128 if ( IsValidHandle(hFind) ) 129 { 130 BOOL fSuccess = false; 131 132 do 133 { 134 wchar_t szLibFilePath[MAX_PATH]; 135 wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' ); 136 if ( lpLastSlash ) 137 { 138 size_t len = lpLastSlash - pszFolder + 1; 139 wcsncpy( szLibFilePath, pszFolder, len ); 140 wcsncpy( szLibFilePath + len, aFindFileData.cFileName, sizeof(szLibFilePath)/sizeof(szLibFilePath[0]) - len ); 141 } 142 143 rebaseImage( szLibFilePath, nNewImageBase ); 144 fSuccess = FindNextFile( hFind, &aFindFileData ); 145 } 146 while ( fSuccess ); 147 148 FindClose( hFind ); 149 } 150 } 151 152 } 153 154 extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) 155 { 156 wchar_t path[MAX_PATH]; 157 158 wchar_t * pathEnd = getBrandPath(path); 159 160 if (tools::buildPath(path, path, pathEnd, MY_STRING(L"")) == NULL) 161 fail(); 162 rebaseImagesInFolder(path, BASEVIRTUALADDRESS); 163 164 if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL) 165 fail(); 166 pathEnd = tools::resolveLink(path); 167 168 if ( pathEnd == NULL ) 169 return 0; 170 171 if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\")) == NULL) 172 fail(); 173 rebaseImagesInFolder(path, BASEVIRTUALADDRESS); 174 175 if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL) 176 fail(); 177 pathEnd = tools::resolveLink(path); 178 179 if ( pathEnd == NULL ) 180 return 0; 181 182 if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\")) == NULL) 183 fail(); 184 rebaseImagesInFolder(path, BASEVIRTUALADDRESS); 185 186 return 0; 187 } 188