xref: /trunk/main/desktop/win32/source/rebase/rebase.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "precompiled_desktop.hxx"
29 #define UNICODE
30 #define _UNICODE
31 
32 #define WIN32_LEAN_AND_MEAN
33 #if defined _MSC_VER
34 #pragma warning(push, 1)
35 #endif
36 #include <windows.h>
37 #include <shellapi.h>
38 #include <imagehlp.h>
39 #include <wchar.h>
40 #if defined _MSC_VER
41 #pragma warning(pop)
42 #endif
43 
44 #include <time.h>
45 #include "sal/config.h"
46 #include "tools/pathutils.hxx"
47 
48 #define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
49 #define MY_STRING(s) (s), MY_LENGTH(s)
50 
51 const int   FORMAT_MESSAGE_SIZE = 4096;
52 const DWORD PE_Signature        = 0x00004550;
53 const DWORD BASEVIRTUALADDRESS  = 0x10000000;
54 
55 namespace
56 {
57 
58 bool IsValidHandle( HANDLE handle )
59 {
60     return ((NULL != handle) && (INVALID_HANDLE_VALUE != handle));
61 }
62 
63 void fail()
64 {
65     LPWSTR buf = NULL;
66     FormatMessageW(
67         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
68         GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL);
69     MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR);
70     LocalFree(buf);
71     TerminateProcess(GetCurrentProcess(), 255);
72 }
73 
74 bool rebaseImage( wchar_t* pszFilePath, ULONG nNewImageBase)
75 {
76     ULONG ulOldImageSize;
77     ULONG_PTR lpOldImageBase;
78     ULONG ulNewImageSize;
79     ULONG_PTR lpNewImageBase  = nNewImageBase;
80     ULONG     ulDateTimeStamp = 0;
81     bool      bResult(false);
82 
83     char cszFilePath[_MAX_PATH+1] = {0};
84     int nResult = WideCharToMultiByte(CP_ACP, 0, pszFilePath, -1, cszFilePath, _MAX_PATH, NULL, NULL);
85 
86     if (nResult != 0)
87     {
88         BOOL bResult = ReBaseImage(
89             cszFilePath,
90             "",
91             TRUE,
92             FALSE,
93             FALSE,
94             0,
95             &ulOldImageSize,
96             &lpOldImageBase,
97             &ulNewImageSize,
98             &lpNewImageBase,
99             ulDateTimeStamp );
100     }
101 
102     return bResult;
103 }
104 
105 wchar_t* getBrandPath(wchar_t * path)
106 {
107     DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH);
108     if (n == 0 || n >= MAX_PATH) {
109         exit(EXIT_FAILURE);
110     }
111     return tools::filename(path);
112 }
113 
114 void rebaseImagesInFolder( wchar_t* pszFolder, DWORD nNewImageBase )
115 {
116     wchar_t szPattern[MAX_PATH];
117     wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' );
118     if ( lpLastSlash )
119     {
120         size_t len = lpLastSlash - pszFolder + 1;
121         wcsncpy( szPattern, pszFolder, len );
122         wcsncpy( szPattern + len, TEXT("*.dll"), sizeof(szPattern)/sizeof(szPattern[0]) - len );
123     }
124 
125     WIN32_FIND_DATA aFindFileData;
126     HANDLE  hFind = FindFirstFile( szPattern, &aFindFileData );
127 
128     if ( IsValidHandle(hFind) )
129     {
130         BOOL fSuccess = false;
131 
132         do
133         {
134             wchar_t szLibFilePath[MAX_PATH];
135             wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' );
136             if ( lpLastSlash )
137             {
138                 size_t len = lpLastSlash - pszFolder + 1;
139                 wcsncpy( szLibFilePath, pszFolder, len );
140                 wcsncpy( szLibFilePath + len, aFindFileData.cFileName, sizeof(szLibFilePath)/sizeof(szLibFilePath[0]) - len );
141             }
142 
143             rebaseImage( szLibFilePath, nNewImageBase );
144             fSuccess = FindNextFile( hFind, &aFindFileData );
145         }
146         while ( fSuccess );
147 
148         FindClose( hFind );
149     }
150 }
151 
152 }
153 
154 extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
155 {
156     wchar_t path[MAX_PATH];
157 
158     wchar_t * pathEnd = getBrandPath(path);
159 
160     if (tools::buildPath(path, path, pathEnd, MY_STRING(L"")) == NULL)
161         fail();
162     rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
163 
164     if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL)
165         fail();
166     pathEnd = tools::resolveLink(path);
167 
168     if ( pathEnd == NULL )
169         return 0;
170 
171     if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\")) == NULL)
172         fail();
173     rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
174 
175     if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL)
176         fail();
177     pathEnd = tools::resolveLink(path);
178 
179     if ( pathEnd == NULL )
180         return 0;
181 
182     if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\")) == NULL)
183         fail();
184     rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
185 
186     return 0;
187 }
188