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