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