| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "precompiled_desktop.hxx" |
| #define UNICODE |
| #define _UNICODE |
| |
| #define WIN32_LEAN_AND_MEAN |
| #if defined _MSC_VER |
| #pragma warning(push, 1) |
| #endif |
| #include <windows.h> |
| #include <shellapi.h> |
| #include <imagehlp.h> |
| #include <wchar.h> |
| #if defined _MSC_VER |
| #pragma warning(pop) |
| #endif |
| |
| #include <time.h> |
| #include "sal/config.h" |
| #include "tools/pathutils.hxx" |
| |
| #define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1) |
| #define MY_STRING(s) (s), MY_LENGTH(s) |
| |
| const int FORMAT_MESSAGE_SIZE = 4096; |
| const DWORD PE_Signature = 0x00004550; |
| const DWORD BASEVIRTUALADDRESS = 0x10000000; |
| |
| namespace |
| { |
| |
| bool IsValidHandle( HANDLE handle ) |
| { |
| return ((NULL != handle) && (INVALID_HANDLE_VALUE != handle)); |
| } |
| |
| void fail() |
| { |
| LPWSTR buf = NULL; |
| FormatMessageW( |
| FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, |
| GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL); |
| MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR); |
| LocalFree(buf); |
| TerminateProcess(GetCurrentProcess(), 255); |
| } |
| |
| bool rebaseImage( wchar_t* pszFilePath, ULONG nNewImageBase) |
| { |
| ULONG ulOldImageSize; |
| ULONG_PTR lpOldImageBase; |
| ULONG ulNewImageSize; |
| ULONG_PTR lpNewImageBase = nNewImageBase; |
| ULONG ulDateTimeStamp = 0; |
| bool bResult(false); |
| |
| char cszFilePath[_MAX_PATH+1] = {0}; |
| int nResult = WideCharToMultiByte(CP_ACP, 0, pszFilePath, -1, cszFilePath, _MAX_PATH, NULL, NULL); |
| |
| if (nResult != 0) |
| { |
| BOOL bResult = ReBaseImage( |
| cszFilePath, |
| "", |
| TRUE, |
| FALSE, |
| FALSE, |
| 0, |
| &ulOldImageSize, |
| &lpOldImageBase, |
| &ulNewImageSize, |
| &lpNewImageBase, |
| ulDateTimeStamp ); |
| } |
| |
| return bResult; |
| } |
| |
| wchar_t* getBrandPath(wchar_t * path) |
| { |
| DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH); |
| if (n == 0 || n >= MAX_PATH) { |
| exit(EXIT_FAILURE); |
| } |
| return tools::filename(path); |
| } |
| |
| void rebaseImagesInFolder( wchar_t* pszFolder, DWORD nNewImageBase ) |
| { |
| wchar_t szPattern[MAX_PATH]; |
| wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' ); |
| if ( lpLastSlash ) |
| { |
| size_t len = lpLastSlash - pszFolder + 1; |
| wcsncpy( szPattern, pszFolder, len ); |
| wcsncpy( szPattern + len, TEXT("*.dll"), sizeof(szPattern)/sizeof(szPattern[0]) - len ); |
| } |
| |
| WIN32_FIND_DATA aFindFileData; |
| HANDLE hFind = FindFirstFile( szPattern, &aFindFileData ); |
| |
| if ( IsValidHandle(hFind) ) |
| { |
| BOOL fSuccess = false; |
| |
| do |
| { |
| wchar_t szLibFilePath[MAX_PATH]; |
| wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' ); |
| if ( lpLastSlash ) |
| { |
| size_t len = lpLastSlash - pszFolder + 1; |
| wcsncpy( szLibFilePath, pszFolder, len ); |
| wcsncpy( szLibFilePath + len, aFindFileData.cFileName, sizeof(szLibFilePath)/sizeof(szLibFilePath[0]) - len ); |
| } |
| |
| rebaseImage( szLibFilePath, nNewImageBase ); |
| fSuccess = FindNextFile( hFind, &aFindFileData ); |
| } |
| while ( fSuccess ); |
| |
| FindClose( hFind ); |
| } |
| } |
| |
| } |
| |
| extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) |
| { |
| wchar_t path[MAX_PATH]; |
| |
| wchar_t * pathEnd = getBrandPath(path); |
| |
| if (tools::buildPath(path, path, pathEnd, MY_STRING(L"")) == NULL) |
| fail(); |
| rebaseImagesInFolder(path, BASEVIRTUALADDRESS); |
| |
| if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL) |
| fail(); |
| pathEnd = tools::resolveLink(path); |
| |
| if ( pathEnd == NULL ) |
| return 0; |
| |
| if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\")) == NULL) |
| fail(); |
| rebaseImagesInFolder(path, BASEVIRTUALADDRESS); |
| |
| if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL) |
| fail(); |
| pathEnd = tools::resolveLink(path); |
| |
| if ( pathEnd == NULL ) |
| return 0; |
| |
| if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\")) == NULL) |
| fail(); |
| rebaseImagesInFolder(path, BASEVIRTUALADDRESS); |
| |
| return 0; |
| } |