summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcrashrep/source/win32/soreport.cpp54
-rw-r--r--setup_native/prj/build.lst1
-rw-r--r--setup_native/source/win32/customactions/rebase/makefile.mk94
-rw-r--r--setup_native/source/win32/customactions/rebase/rebase.cxx168
-rw-r--r--setup_native/source/win32/customactions/rebase/rebase.dxp1
5 files changed, 318 insertions, 0 deletions
diff --git a/crashrep/source/win32/soreport.cpp b/crashrep/source/win32/soreport.cpp
index 4c897f76e0b5..043ad62b0051 100755
--- a/crashrep/source/win32/soreport.cpp
+++ b/crashrep/source/win32/soreport.cpp
@@ -1564,8 +1564,60 @@ static void repatch_soffice_exe( void *pBuffer, size_t nBufSize )
} while ( !bPatched && nBufSize );
}
+// Normalize executable/library images to prevent different MD5 checksums due
+// to a different PE header date/checksum (this doesn't affect the code/data
+// sections of a executable/library. Please see tools/source/bootstrp/md5.cxx
+// where the same method is also used. The tool so_checksum creates the MD5
+// checksums during build time. You have to make sure that both methods use the
+// same algorithm otherwise there could be problems with stack reports.
+static void normalize_pe_image(sal_uInt8* buffer, size_t nBufferSize)
+{
+ const int OFFSET_PE_OFFSET = 0x3c;
+ const int OFFSET_COFF_TIMEDATESTAMP = 4;
+ const int PE_SIGNATURE_SIZE = 4;
+ const int COFFHEADER_SIZE = 20;
+ const int OFFSET_PE_OPTIONALHEADER_CHECKSUM = 64;
+
+ // Check the header part of the file buffer
+ if (buffer[0] == 'M' && buffer[1] == 'Z')
+ {
+ unsigned long PEHeaderOffset = (long)buffer[OFFSET_PE_OFFSET];
+ if (PEHeaderOffset < nBufferSize-4)
+ {
+ if ( buffer[PEHeaderOffset] == 'P' &&
+ buffer[PEHeaderOffset+1] == 'E' &&
+ buffer[PEHeaderOffset+2] == 0 &&
+ buffer[PEHeaderOffset+3] == 0 )
+ {
+ PEHeaderOffset += PE_SIGNATURE_SIZE;
+ if (PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP < nBufferSize-4)
+ {
+ // Set timedatestamp and checksum fields to a normalized
+ // value to enforce the same MD5 checksum for identical
+ // Windows executables/libraries.
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+1] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+2] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+3] = 0;
+ }
+
+ if (PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM < nBufferSize-4)
+ {
+ // Set checksum to a normalized value
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+1] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+2] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+3] = 0;
+ }
+ }
+ }
+ }
+}
+
static sal_uInt32 calc_md5_checksum( const char *filename, sal_uInt8 *pChecksum, sal_uInt32 nChecksumLen )
{
+ const int MINIMAL_FILESIZE = 512;
+
sal_uInt32 nBytesProcessed = 0;
FILE *fp = fopen( filename, "rb" );
@@ -1585,6 +1637,8 @@ static sal_uInt32 calc_md5_checksum( const char *filename, sal_uInt8 *pChecksum
{
if ( 0 == stricmp( GetFileName(filename).c_str(), "soffice.bin" ) )
repatch_soffice_exe( pBuffer, nBytesRead );
+ else if ( nFileSize > MINIMAL_FILESIZE )
+ normalize_pe_image( pBuffer, nBytesRead );
rtlDigestError error = rtl_digest_MD5 (
pBuffer, nBytesRead,
diff --git a/setup_native/prj/build.lst b/setup_native/prj/build.lst
index 7966d21533fc..fcb276075a09 100644
--- a/setup_native/prj/build.lst
+++ b/setup_native/prj/build.lst
@@ -4,6 +4,7 @@ pk setup_native\scripts\source nmake - u sn_sour
pk setup_native\scripts nmake - u sn_scripts sn_source.u NULL
pk setup_native\source\win32\customactions\tools nmake - w sn_tools NULL
pk setup_native\source\win32\customactions\relnotes nmake - w sn_relnotes NULL
+pk setup_native\source\win32\customactions\rebase nmake - w sn_rebase NULL
pk setup_native\source\win32\customactions\regactivex nmake - w sn_regactivex NULL
pk setup_native\source\win32\customactions\regpatchactivex nmake - w sn_regpatchactivex NULL
pk setup_native\source\win32\customactions\reg4allmsdoc nmake - w sn_reg4allmsdoc NULL
diff --git a/setup_native/source/win32/customactions/rebase/makefile.mk b/setup_native/source/win32/customactions/rebase/makefile.mk
new file mode 100644
index 000000000000..6694c8cde6cc
--- /dev/null
+++ b/setup_native/source/win32/customactions/rebase/makefile.mk
@@ -0,0 +1,94 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.7 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=rebase
+
+# --- Settings -----------------------------------------------------
+
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+MINGW_NODLL=YES
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+UWINAPILIB=
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+STDSHL += \
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)\
+ $(MSILIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL += $(LIBSTLPORTST)
+.ENDIF
+
+.IF "$(COM)"=="GCC"
+STDSHL+= \
+ $(KERNEL32LIB)\
+ -lmsvcrt \
+ $(PSDK_HOME)$/lib$/imagehlp.lib
+.ELSE
+STDSHL+= \
+ Imagehlp.lib
+.ENDIF
+
+SHL1OBJS = \
+ $(SLO)$/rebase.obj
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+SHL1DEPN=$(SHL1OBJS)
+DEF1EXPORTFILE=$(TARGET).dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
diff --git a/setup_native/source/win32/customactions/rebase/rebase.cxx b/setup_native/source/win32/customactions/rebase/rebase.cxx
new file mode 100644
index 000000000000..4d031bee908a
--- /dev/null
+++ b/setup_native/source/win32/customactions/rebase/rebase.cxx
@@ -0,0 +1,168 @@
+#undef UNICODE
+#undef _UNICODE
+
+#pragma once
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#include <imagehlp.h>
+#include <tchar.h>
+#include <strsafe.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <time.h>
+#include <string>
+
+const DWORD PE_Signature = 0x00004550;
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
+{
+ CHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugStringA( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCSTR, ... )
+{
+}
+#endif
+
+static bool IsValidHandle( HANDLE handle )
+{
+ return NULL != handle && INVALID_HANDLE_VALUE != handle;
+}
+
+static std::string GetMsiProperty(MSIHANDLE handle, const std::string& sProperty)
+{
+ std::string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+}
+
+static BOOL rebaseImage( const std::string& filePath, LPVOID address )
+{
+ ULONG ulOldImageSize;
+ ULONG_PTR lpOldImageBase;
+ ULONG ulNewImageSize;
+ ULONG_PTR lpNewImageBase = reinterpret_cast<ULONG_PTR>(address);
+
+ BOOL bResult = ReBaseImage(
+ filePath.c_str(),
+ "",
+ TRUE,
+ FALSE,
+ FALSE,
+ 0,
+ &ulOldImageSize,
+ &lpOldImageBase,
+ &ulNewImageSize,
+ &lpNewImageBase,
+ (ULONG)time(NULL) );
+
+ return bResult;
+}
+
+static BOOL rebaseImage( MSIHANDLE /*handle*/, const std::string& sFilePath, LPVOID address )
+{
+ std::string mystr;
+ mystr = "Full file: " + sFilePath;
+
+ BOOL bResult = rebaseImage( sFilePath, address );
+
+ if ( !bResult )
+ {
+ OutputDebugStringFormat( "Rebasing library %s failed", mystr.c_str() );
+ }
+
+ return bResult;
+}
+
+static BOOL rebaseImagesInFolder( MSIHANDLE handle, const std::string& sPath, LPVOID address )
+{
+ std::string sDir = sPath;
+ std::string sPattern = sPath + TEXT("*.dll");
+
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ BOOL fSuccess = false;
+
+ do
+ {
+ std::string sLibFile = sDir + aFindFileData.cFileName;
+ rebaseImage( handle, sLibFile, address );
+ fSuccess = FindNextFile( hFind, &aFindFileData );
+ }
+ while ( fSuccess );
+
+ FindClose( hFind );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static BOOL rebaseImages( MSIHANDLE handle, LPVOID pAddress )
+{
+ std::string sOfficeInstallPath = GetMsiProperty(handle, TEXT("OFFICEINSTALLLOCATION"));
+ std::string sBasisInstallPath = GetMsiProperty(handle, TEXT("BASISINSTALLLOCATION"));
+ std::string sUreInstallPath = GetMsiProperty(handle, TEXT("UREINSTALLLOCATION"));
+
+ std::string sBasisDir = sBasisInstallPath + TEXT("program\\");
+ std::string sOfficeDir = sOfficeInstallPath + TEXT("program\\");
+ std::string sUreDir = sUreInstallPath + TEXT("bin\\");
+
+ BOOL bResult = rebaseImagesInFolder( handle, sBasisDir, pAddress );
+ bResult &= rebaseImagesInFolder( handle, sOfficeDir, pAddress );
+ bResult &= rebaseImagesInFolder( handle, sUreDir, pAddress );
+
+ return bResult;
+}
+
+static BOOL IsServerSystem( MSIHANDLE /*handle*/ )
+{
+ OSVERSIONINFOEX osVersionInfoEx;
+ osVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&osVersionInfoEx));
+
+ if ( osVersionInfoEx.wProductType != VER_NT_WORKSTATION )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+extern "C" BOOL __stdcall RebaseLibrariesOnProperties( MSIHANDLE handle )
+{
+ static LPVOID pDefault = reinterpret_cast<LPVOID>(0x10000000);
+
+ std::string sDontOptimizeLibs = GetMsiProperty(handle, TEXT("DONTOPTIMIZELIBS"));
+ if ( sDontOptimizeLibs.length() > 0 && sDontOptimizeLibs == "1" )
+ return TRUE;
+
+ if ( !IsServerSystem( handle ))
+ return rebaseImages( handle, pDefault );
+
+ return TRUE;
+}
diff --git a/setup_native/source/win32/customactions/rebase/rebase.dxp b/setup_native/source/win32/customactions/rebase/rebase.dxp
new file mode 100644
index 000000000000..47ea23951f04
--- /dev/null
+++ b/setup_native/source/win32/customactions/rebase/rebase.dxp
@@ -0,0 +1 @@
+RebaseLibrariesOnProperties