1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
8 #pragma warning(push, 1) /* disable warnings within system headers */
10 #define WIN32_LEAN_AND_MEAN
15 #define STRSAFE_NO_DEPRECATE
24 #include <boost/unordered_map.hpp>
26 const DWORD PE_Signature
= 0x00004550;
27 typedef std::pair
< std::string
, bool > StringPair
;
28 typedef boost::unordered_map
< std::string
, bool > ExcludeLibsMap
;
31 static void OutputDebugStringFormat( LPCSTR pFormat
, ... )
36 va_start( args
, pFormat
);
37 StringCchVPrintfA( buffer
, sizeof(buffer
), pFormat
, args
);
38 OutputDebugStringA( buffer
);
41 static void OutputDebugStringFormat( LPCSTR
, ... )
46 static bool IsValidHandle( HANDLE handle
)
48 return NULL
!= handle
&& INVALID_HANDLE_VALUE
!= handle
;
51 static std::string
GetMsiProperty(MSIHANDLE handle
, const std::string
& sProperty
)
54 TCHAR szDummy
[1] = TEXT("");
57 if (MsiGetProperty(handle
, sProperty
.c_str(), szDummy
, &nChars
) == ERROR_MORE_DATA
)
59 DWORD nBytes
= ++nChars
* sizeof(TCHAR
);
60 LPTSTR buffer
= reinterpret_cast<LPTSTR
>(_alloca(nBytes
));
61 ZeroMemory( buffer
, nBytes
);
62 MsiGetProperty(handle
, sProperty
.c_str(), buffer
, &nChars
);
68 static BOOL
rebaseImage( const std::string
& filePath
, LPVOID address
)
71 ULONG_PTR lpOldImageBase
;
73 ULONG_PTR lpNewImageBase
= reinterpret_cast<ULONG_PTR
>(address
);
75 BOOL bResult
= ReBaseImage(
76 (PSTR
)filePath
.c_str(),
91 static BOOL
rebaseImage( MSIHANDLE
/*handle*/, const std::string
& sFilePath
, LPVOID address
)
94 mystr
= "Full file: " + sFilePath
;
96 BOOL bResult
= rebaseImage( sFilePath
, address
);
100 OutputDebugStringFormat( "Rebasing library %s failed", mystr
.c_str() );
106 static BOOL
rebaseImagesInFolder( MSIHANDLE handle
, const std::string
& sPath
, LPVOID address
, ExcludeLibsMap
& rExcludeMap
)
108 std::string sDir
= sPath
;
109 std::string sPattern
= sPath
+ TEXT("*.dll");
110 WIN32_FIND_DATA aFindFileData
;
112 HANDLE hFind
= FindFirstFile( sPattern
.c_str(), &aFindFileData
);
113 if ( IsValidHandle(hFind
) )
115 BOOL fSuccess
= false;
119 std::string sFileName
= aFindFileData
.cFileName
;
120 if ( rExcludeMap
.find( sFileName
) == rExcludeMap
.end() )
122 OutputDebugStringFormat( "Rebase library: %s", sFileName
.c_str() );
123 std::string sLibFile
= sDir
+ sFileName
;
124 rebaseImage( handle
, sLibFile
, address
);
128 OutputDebugStringFormat( "Exclude library %s from rebase", sFileName
.c_str() );
131 fSuccess
= FindNextFile( hFind
, &aFindFileData
);
138 return ERROR_SUCCESS
;
141 static BOOL
rebaseImages( MSIHANDLE handle
, LPVOID pAddress
, ExcludeLibsMap
& rMap
)
143 std::string sInstallPath
= GetMsiProperty(handle
, TEXT("INSTALLLOCATION"));
145 std::string sBasisDir
= sInstallPath
+ TEXT("Basis\\program\\");
146 std::string sOfficeDir
= sInstallPath
+ TEXT("program\\");
147 std::string sUreDir
= sInstallPath
+ TEXT("URE\\bin\\");
149 BOOL bResult
= rebaseImagesInFolder( handle
, sBasisDir
, pAddress
, rMap
);
150 bResult
&= rebaseImagesInFolder( handle
, sOfficeDir
, pAddress
, rMap
);
151 bResult
&= rebaseImagesInFolder( handle
, sUreDir
, pAddress
, rMap
);
156 static BOOL
IsServerSystem( MSIHANDLE
/*handle*/ )
158 OSVERSIONINFOEX osVersionInfoEx
;
159 osVersionInfoEx
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOEX
);
160 GetVersionEx(reinterpret_cast<LPOSVERSIONINFO
>(&osVersionInfoEx
));
162 if ( osVersionInfoEx
.wProductType
!= VER_NT_WORKSTATION
)
164 OutputDebugStringFormat( "Server system detected. No rebase necessary!" );
169 OutputDebugStringFormat( "Client system detected. Rebase necessary!" );
174 static void InitExcludeFromRebaseList( MSIHANDLE handle
, ExcludeLibsMap
& rMap
)
177 const TCHAR cDelim
= ',';
178 std::string sLibsExcluded
= GetMsiProperty(handle
, TEXT("EXCLUDE_FROM_REBASE"));
180 while ( nPos
< sLibsExcluded
.size() )
182 size_t nDelPos
= sLibsExcluded
.find_first_of( cDelim
, nPos
);
184 std::string sExcludedLibName
;
185 if ( nDelPos
!= std::string::npos
)
187 sExcludedLibName
= sLibsExcluded
.substr( nPos
, nDelPos
- nPos
);
192 sExcludedLibName
= sLibsExcluded
.substr( nPos
);
193 nPos
= sLibsExcluded
.size();
196 if ( sExcludedLibName
.size() > 0 )
198 OutputDebugStringFormat( "Insert library %s into exclude from rebase list", sExcludedLibName
.c_str() );
199 rMap
.insert( StringPair( sExcludedLibName
, true ));
204 extern "C" BOOL __stdcall
RebaseLibrariesOnProperties( MSIHANDLE handle
)
206 static LPVOID pDefault
= reinterpret_cast<LPVOID
>(0x10000000);
208 OutputDebugStringFormat( "RebaseLibrariesOnProperties has been called" );
209 std::string sDontOptimizeLibs
= GetMsiProperty(handle
, TEXT("DONTOPTIMIZELIBS"));
210 if ( sDontOptimizeLibs
.length() > 0 && sDontOptimizeLibs
== "1" )
212 OutputDebugStringFormat( "Don't optimize libraries set. No rebase necessary!" );
216 if ( !IsServerSystem( handle
))
218 ExcludeLibsMap aExcludeLibsMap
;
219 InitExcludeFromRebaseList( handle
, aExcludeLibsMap
);
221 return rebaseImages( handle
, pDefault
, aExcludeLibsMap
);
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */