Update ooo320-m1
[ooovba.git] / setup_native / source / win32 / customactions / rebase / rebase.cxx
blobc2630ed9cbaf481c6de08ab578e08817cc62499a
1 #undef UNICODE
2 #undef _UNICODE
4 #pragma once
6 #ifdef _MSC_VER
7 #pragma warning(push, 1) /* disable warnings within system headers */
8 #endif
9 #define WIN32_LEAN_AND_MEAN
10 #include <windows.h>
11 #include <msiquery.h>
12 #include <imagehlp.h>
13 #include <tchar.h>
14 #include <strsafe.h>
15 #ifdef _MSC_VER
16 #pragma warning(pop)
17 #endif
19 #include <malloc.h>
20 #include <time.h>
21 #include <string>
23 const DWORD PE_Signature = 0x00004550;
25 #ifdef DEBUG
26 inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
28 CHAR buffer[1024];
29 va_list args;
31 va_start( args, pFormat );
32 StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
33 OutputDebugStringA( buffer );
35 #else
36 static inline void OutputDebugStringFormat( LPCSTR, ... )
39 #endif
41 static bool IsValidHandle( HANDLE handle )
43 return NULL != handle && INVALID_HANDLE_VALUE != handle;
46 static std::string GetMsiProperty(MSIHANDLE handle, const std::string& sProperty)
48 std::string result;
49 TCHAR szDummy[1] = TEXT("");
50 DWORD nChars = 0;
52 if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
54 DWORD nBytes = ++nChars * sizeof(TCHAR);
55 LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
56 ZeroMemory( buffer, nBytes );
57 MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
58 result = buffer;
60 return result;
63 static BOOL rebaseImage( const std::string& filePath, LPVOID address )
65 ULONG ulOldImageSize;
66 ULONG_PTR lpOldImageBase;
67 ULONG ulNewImageSize;
68 ULONG_PTR lpNewImageBase = reinterpret_cast<ULONG_PTR>(address);
70 BOOL bResult = ReBaseImage(
71 filePath.c_str(),
72 "",
73 TRUE,
74 FALSE,
75 FALSE,
77 &ulOldImageSize,
78 &lpOldImageBase,
79 &ulNewImageSize,
80 &lpNewImageBase,
81 (ULONG)time(NULL) );
83 return bResult;
86 static BOOL rebaseImage( MSIHANDLE /*handle*/, const std::string& sFilePath, LPVOID address )
88 std::string mystr;
89 mystr = "Full file: " + sFilePath;
91 BOOL bResult = rebaseImage( sFilePath, address );
93 if ( !bResult )
95 OutputDebugStringFormat( "Rebasing library %s failed", mystr.c_str() );
98 return bResult;
101 static BOOL rebaseImagesInFolder( MSIHANDLE handle, const std::string& sPath, LPVOID address )
103 std::string sDir = sPath;
104 std::string sPattern = sPath + TEXT("*.dll");
106 WIN32_FIND_DATA aFindFileData;
107 HANDLE hFind = FindFirstFile( sPattern.c_str(), &aFindFileData );
109 if ( IsValidHandle(hFind) )
111 BOOL fSuccess = false;
115 std::string sLibFile = sDir + aFindFileData.cFileName;
116 rebaseImage( handle, sLibFile, address );
117 fSuccess = FindNextFile( hFind, &aFindFileData );
119 while ( fSuccess );
121 FindClose( hFind );
124 return ERROR_SUCCESS;
127 static BOOL rebaseImages( MSIHANDLE handle, LPVOID pAddress )
129 std::string sOfficeInstallPath = GetMsiProperty(handle, TEXT("OFFICEINSTALLLOCATION"));
130 std::string sBasisInstallPath = GetMsiProperty(handle, TEXT("BASISINSTALLLOCATION"));
131 std::string sUreInstallPath = GetMsiProperty(handle, TEXT("UREINSTALLLOCATION"));
133 std::string sBasisDir = sBasisInstallPath + TEXT("program\\");
134 std::string sOfficeDir = sOfficeInstallPath + TEXT("program\\");
135 std::string sUreDir = sUreInstallPath + TEXT("bin\\");
137 BOOL bResult = rebaseImagesInFolder( handle, sBasisDir, pAddress );
138 bResult &= rebaseImagesInFolder( handle, sOfficeDir, pAddress );
139 bResult &= rebaseImagesInFolder( handle, sUreDir, pAddress );
141 return bResult;
144 static BOOL IsServerSystem( MSIHANDLE /*handle*/ )
146 OSVERSIONINFOEX osVersionInfoEx;
147 osVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
148 GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&osVersionInfoEx));
150 if ( osVersionInfoEx.wProductType != VER_NT_WORKSTATION )
151 return TRUE;
152 else
153 return FALSE;
156 extern "C" BOOL __stdcall RebaseLibrariesOnProperties( MSIHANDLE handle )
158 static LPVOID pDefault = reinterpret_cast<LPVOID>(0x10000000);
160 std::string sDontOptimizeLibs = GetMsiProperty(handle, TEXT("DONTOPTIMIZELIBS"));
161 if ( sDontOptimizeLibs.length() > 0 && sDontOptimizeLibs == "1" )
162 return TRUE;
164 if ( !IsServerSystem( handle ))
165 return rebaseImages( handle, pDefault );
167 return TRUE;