xref: /AOO41X/main/desktop/win32/source/rebase/rebase.cxx (revision 2722ceddc26af33ca9ed6a22fc3c4dfb805171c3)
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 
IsValidHandle(HANDLE handle)54 bool IsValidHandle( HANDLE handle )
55 {
56     return ((NULL != handle) && (INVALID_HANDLE_VALUE != handle));
57 }
58 
fail()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 
rebaseImage(wchar_t * pszFilePath,ULONG nNewImageBase)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 
getBrandPath(wchar_t * path)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 
rebaseImagesInFolder(wchar_t * pszFolder,DWORD nNewImageBase)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 
WinMain(HINSTANCE,HINSTANCE,LPSTR,int)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