/************************************************************** * * 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 #include #include #include #if defined _MSC_VER #pragma warning(pop) #endif #include #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; }