From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- other-licenses/7zstub/mozilla_customizations.diff | 644 ++++++++++++++++++++++ 1 file changed, 644 insertions(+) create mode 100644 other-licenses/7zstub/mozilla_customizations.diff (limited to 'other-licenses/7zstub/mozilla_customizations.diff') diff --git a/other-licenses/7zstub/mozilla_customizations.diff b/other-licenses/7zstub/mozilla_customizations.diff new file mode 100644 index 0000000000..6680a6f893 --- /dev/null +++ b/other-licenses/7zstub/mozilla_customizations.diff @@ -0,0 +1,644 @@ +diff --git a/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp +--- a/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp ++++ b/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp +@@ -54,7 +54,7 @@ BSC32=bscmake.exe + # ADD BSC32 /nologo + LINK32=link.exe + # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +-# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /opt:NOWIN98 ++# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /out:"Release\7zS.sfx" /opt:NOWIN98 /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll + # SUBTRACT LINK32 /pdb:none + + !ELSEIF "$(CFG)" == "SFXSetup - Win32 Debug" +@@ -81,7 +81,7 @@ BSC32=bscmake.exe + # ADD BSC32 /nologo + LINK32=link.exe + # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept ++# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib delayimp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Debug\7zSfxS.exe" /pdbtype:sept /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll + + !ELSEIF "$(CFG)" == "SFXSetup - Win32 ReleaseD" + +@@ -107,9 +107,9 @@ BSC32=bscmake.exe + # ADD BASE BSC32 /nologo + # ADD BSC32 /nologo + LINK32=link.exe +-# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe" ++# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe" + # SUBTRACT BASE LINK32 /debug /nodefaultlib +-# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zSD.sfx" /opt:NOWIN98 ++# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /out:"ReleaseD\7zSD.sfx" /opt:NOWIN98 /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll + # SUBTRACT LINK32 /pdb:none + + !ENDIF +diff --git a/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp b/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp +--- a/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp ++++ b/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp +@@ -27,6 +27,10 @@ + + #include "resource.h" + ++/* BEGIN Mozilla customizations */ ++#include "../../../Common/IntToString.h" ++/* END Mozilla customizations */ ++ + using namespace NWindows; + using namespace NFile; + using namespace NDir; +@@ -125,6 +129,398 @@ static void ShowErrorMessageSpec(const U + ShowErrorMessage(NULL, message); + } + ++/* BEGIN Mozilla customizations */ ++ ++static char const * ++FindStrInBuf(char const * buf, size_t bufLen, char const * str) ++{ ++ size_t index = 0; ++ while (index < bufLen) { ++ char const * result = strstr(buf + index, str); ++ if (result) { ++ return result; ++ } ++ while ((buf[index] != '\0') && (index < bufLen)) { ++ index++; ++ } ++ index++; ++ } ++ return NULL; ++} ++ ++static bool ++ReadPostSigningDataFromView(char const * view, DWORD size, AString& data) ++{ ++ // Find the offset and length of the certificate table, ++ // so we know the valid range to look for the token. ++ if (size < (0x3c + sizeof(UInt32))) { ++ return false; ++ } ++ UInt32 PEHeaderOffset = *(UInt32*)(view + 0x3c); ++ UInt32 optionalHeaderOffset = PEHeaderOffset + 24; ++ UInt32 certDirEntryOffset = 0; ++ if (size < (optionalHeaderOffset + sizeof(UInt16))) { ++ return false; ++ } ++ UInt16 magic = *(UInt16*)(view + optionalHeaderOffset); ++ if (magic == 0x010b) { ++ // 32-bit executable ++ certDirEntryOffset = optionalHeaderOffset + 128; ++ } else if (magic == 0x020b) { ++ // 64-bit executable; certain header fields are wider ++ certDirEntryOffset = optionalHeaderOffset + 144; ++ } else { ++ // Unknown executable ++ return false; ++ } ++ if (size < certDirEntryOffset + 8) { ++ return false; ++ } ++ UInt32 certTableOffset = *(UInt32*)(view + certDirEntryOffset); ++ UInt32 certTableLen = *(UInt32*)(view + certDirEntryOffset + sizeof(UInt32)); ++ if (certTableOffset == 0 || certTableLen == 0 || ++ size < (certTableOffset + certTableLen)) { ++ return false; ++ } ++ ++ char const token[] = "__MOZCUSTOM__:"; ++ // We're searching for a string inside a binary blob, ++ // so a normal strstr that bails on the first NUL won't work. ++ char const * tokenPos = FindStrInBuf(view + certTableOffset, ++ certTableLen, token); ++ if (tokenPos) { ++ size_t tokenLen = (sizeof(token) / sizeof(token[0])) - 1; ++ data = AString(tokenPos + tokenLen); ++ return true; ++ } ++ return false; ++} ++ ++static bool ++ReadPostSigningData(UString exePath, AString& data) ++{ ++ bool retval = false; ++ HANDLE exeFile = CreateFileW(exePath, GENERIC_READ, FILE_SHARE_READ, NULL, ++ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ++ if (exeFile != INVALID_HANDLE_VALUE) { ++ HANDLE mapping = CreateFileMapping(exeFile, NULL, PAGE_READONLY, 0, 0, NULL); ++ if (mapping != INVALID_HANDLE_VALUE) { ++ // MSDN claims the return value on failure is NULL, ++ // but I've also seen it returned on success, so double-check. ++ if (mapping || GetLastError() == ERROR_SUCCESS) { ++ char * view = (char*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); ++ if (view) { ++ DWORD fileSize = GetFileSize(exeFile, NULL); ++ retval = ReadPostSigningDataFromView(view, fileSize, data); ++ } ++ CloseHandle(mapping); ++ } ++ } ++ CloseHandle(exeFile); ++ } ++ return retval; ++} ++ ++// Simple class for allocating a character buffer and automatically freeing it ++// when it goes out of scope. ++class AutoCharBuffer { ++private: ++ char *buffer; ++ ++ void Alloc(UInt32 size) { ++ buffer = new char[size]; ++ length = 0; ++ } ++public: ++ // Other than being reset when the buffer is deallocated/reallocated, this ++ // isn't updated by this class. ++ UInt32 length; ++ ++ AutoCharBuffer() ++ : length(0) ++ , buffer(NULL) {} ++ ++ AutoCharBuffer(UInt32 size) { ++ Alloc(size); ++ } ++ ++ void Realloc(UInt32 size) { ++ delete [] buffer; ++ Alloc(size); ++ } ++ ++ void Dealloc() { ++ delete [] buffer; ++ buffer = NULL; ++ length = 0; ++ } ++ ++ virtual ~AutoCharBuffer() { ++ Dealloc(); ++ } ++ ++ char *Buffer() { ++ return buffer; ++ } ++}; ++ ++static void ++AppendStringValueToIni(AString& iniData, const char* key, const char* value) { ++ iniData += key; ++ iniData += '='; ++ iniData += value; ++ iniData += '\n'; ++} ++ ++static void ++AppendDwordValueToIni(AString& iniData, const char* key, DWORD intValue) { ++ AString stringValue; ++ stringValue.Add_UInt32(intValue); ++ AppendStringValueToIni(iniData, key, stringValue.Ptr()); ++} ++ ++static void ++AppendQwordValueToIni(AString& iniData, const char* key, LONGLONG intValue) { ++ // The implementations for `ConvertToString` are a little wonky and ++ // expect the output buffer to just be the correct size. To make sure we are ++ // using it right here, this int conversion implementation was copied from ++ // `CStdOutStream::operator<<(Int64 number)` in `StdOutStream.cpp`. ++ char stringValue[32]; ++ ConvertInt64ToString(intValue, stringValue); ++ AppendStringValueToIni(iniData, key, stringValue); ++} ++ ++static void ++ReadExeFileSystemIntoIniData(const UString &exePath, AString& iniData) { ++ const char* fsKey = "fileSystem"; ++ const char* readFsErrorTypeKey = "readFsError"; ++ const char* readFsErrorCodeKey = "readFsErrorCode"; ++ ++ HANDLE exeFile = CreateFileW(exePath, GENERIC_READ, FILE_SHARE_READ, NULL, ++ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ++ if (exeFile == INVALID_HANDLE_VALUE) { ++ DWORD errorCode = GetLastError(); ++ AppendStringValueToIni(iniData, readFsErrorTypeKey, "openFile"); ++ AppendDwordValueToIni(iniData, readFsErrorCodeKey, errorCode); ++ return; ++ } ++ ++ const size_t bufferSize = MAX_PATH + 1; ++ wchar_t buffer[bufferSize]; ++ BOOL success = GetVolumeInformationByHandleW(exeFile, NULL, 0, NULL, NULL, ++ NULL, buffer, bufferSize); ++ if (!success) { ++ DWORD errorCode = GetLastError(); ++ AppendStringValueToIni(iniData, readFsErrorTypeKey, "getVolInfo"); ++ AppendDwordValueToIni(iniData, readFsErrorCodeKey, errorCode); ++ CloseHandle(exeFile); ++ return; ++ } ++ CloseHandle(exeFile); ++ ++ size_t fsLen = wcsnlen(buffer, bufferSize); ++ if (fsLen == bufferSize) { ++ AppendStringValueToIni(iniData, readFsErrorTypeKey, "fsUnterminated"); ++ return; ++ } ++ ++ const int narrowBufferSize = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, ++ 0, NULL, NULL); ++ if (narrowBufferSize <= 0) { ++ DWORD errorCode = GetLastError(); ++ AppendStringValueToIni(iniData, readFsErrorTypeKey, "getBufferSize"); ++ AppendDwordValueToIni(iniData, readFsErrorCodeKey, errorCode); ++ return; ++ } ++ AutoCharBuffer fs(narrowBufferSize); ++ int written = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, fs.Buffer(), ++ narrowBufferSize, NULL, NULL); ++ if (written <= 0) { ++ DWORD errorCode = GetLastError(); ++ AppendStringValueToIni(iniData, readFsErrorTypeKey, "convertString"); ++ AppendDwordValueToIni(iniData, readFsErrorCodeKey, errorCode); ++ return; ++ } ++ ++ // Like "fileSystem=FAT32" or "fileSystem=NTFS". ++ AppendStringValueToIni(iniData, fsKey, fs.Buffer()); ++} ++ ++// Read Zone Identifier information from alternate data stream. ++// Always either returns the data that was read, or data indicating what sort of ++// error was encountered when obtaining the data. ++// When this function returns, `metadata` is guaranteed to contain relevant ++// metadata that should be written out. But `data.Buffer()` may be null ++// depending on whether we successfully read data. ++static void ++ReadZoneIdentifierData(const UString &exePath, AString& metadata, ++ AutoCharBuffer& data) ++{ ++ metadata.Empty(); ++ data.Dealloc(); ++ ++ // We don't want to allow this function to just read an unlimited amount into ++ // `data`, so this value will control at what point we consider the file too ++ // big to be valid. ++ // 1 MB should be way more than enough. The Zone Identifier file generally ++ // consists of no more than 4 short lines of text. ++ const size_t maxReadSize = 1 * 1000 * 1000; ++ const char* readZoneIdErrorTypeKey = "readZoneIdError"; ++ const char* readZoneIdErrorCodeKey = "readZoneIdErrorCode"; ++ // It looks like the Zone Identifier will be INI data. But since there is no ++ // real guarantee of this, we are going to put an INI-compatible sentinel ++ // before we start appending the Zone Identifier file. This should help us ++ // better parse the file contents if we discover, say, that there is another ++ // possible format for Zone Identifier data. ++ const char* zoneIdStartSentinel = "\n[MozillaZoneIdentifierStartSentinel]\n"; ++ ++ metadata += "[Mozilla]\n"; ++ ReadExeFileSystemIntoIniData(exePath, metadata); ++ ++ UString adsPath(exePath); ++ // A colon (`:`) is not a valid path constituent (see ++ // https://learn.microsoft.com/en-ca/windows/win32/fileio/naming-a-file), so ++ // file systems that don't support ADS will fail to open rather than open an ++ // unrelated file. ++ adsPath += L":Zone.Identifier"; ++ HANDLE adsFile = CreateFileW(adsPath, GENERIC_READ, FILE_SHARE_READ, NULL, ++ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ++ if (adsFile == INVALID_HANDLE_VALUE) { ++ DWORD errorCode = GetLastError(); ++ AppendStringValueToIni(metadata, readZoneIdErrorTypeKey, "openFile"); ++ AppendDwordValueToIni(metadata, readZoneIdErrorCodeKey, errorCode); ++ return; ++ } ++ ++ LARGE_INTEGER fileSize; ++ BOOL success = GetFileSizeEx(adsFile, &fileSize); ++ UInt32 bufferSize = maxReadSize; ++ if (!success) { ++ AppendStringValueToIni(metadata, "zoneIdFileSize", "unknown"); ++ AppendStringValueToIni(metadata, "zoneIdBufferLargeEnough", "unknown"); ++ } else { ++ AppendQwordValueToIni(metadata, "zoneIdFileSize", fileSize.QuadPart); ++ if (fileSize.QuadPart < (LONGLONG)bufferSize) { ++ AppendStringValueToIni(metadata, "zoneIdBufferLargeEnough", "true"); ++ bufferSize = (UInt32)fileSize.QuadPart; ++ } else { ++ AppendStringValueToIni(metadata, "zoneIdBufferLargeEnough", "false"); ++ } ++ } ++ data.Realloc(bufferSize); ++ ++ DWORD readCount; ++ success = ReadFile(adsFile, data.Buffer(), bufferSize, &readCount, NULL); ++ if (!success) { ++ DWORD errorCode = GetLastError(); ++ AppendStringValueToIni(metadata, readZoneIdErrorTypeKey, "readFile"); ++ AppendDwordValueToIni(metadata, readZoneIdErrorCodeKey, errorCode); ++ ++ data.Dealloc(); ++ CloseHandle(adsFile); ++ return; ++ } ++ data.length = readCount; ++ ++ char dummyBuffer; ++ ++ success = ReadFile(adsFile, &dummyBuffer, 1, &readCount, NULL); ++ CloseHandle(adsFile); ++ if (success) { ++ if (readCount == 0) { ++ // We are at the end of the file ++ AppendStringValueToIni(metadata, "zoneIdTruncated", "false"); ++ } else { ++ AppendStringValueToIni(metadata, "zoneIdTruncated", "true"); ++ } ++ } else { ++ AppendStringValueToIni(metadata, "zoneIdTruncated", "unknown"); ++ } ++ ++ metadata += zoneIdStartSentinel; ++} ++ ++// Delayed load libraries are loaded when the first symbol is used. ++// The following ensures that we load the delayed loaded libraries from the ++// system directory. ++struct AutoLoadSystemDependencies ++{ ++ AutoLoadSystemDependencies() ++ { ++ HMODULE module = ::GetModuleHandleW(L"kernel32.dll"); ++ if (module) { ++ // SetDefaultDllDirectories is always available on Windows 8 and above. It ++ // is also available on Windows Vista, Windows Server 2008, and ++ // Windows 7 when MS KB2533623 has been applied. ++ typedef BOOL (WINAPI *SetDefaultDllDirectoriesType)(DWORD); ++ SetDefaultDllDirectoriesType setDefaultDllDirectories = ++ (SetDefaultDllDirectoriesType) GetProcAddress(module, "SetDefaultDllDirectories"); ++ if (setDefaultDllDirectories) { ++ setDefaultDllDirectories(0x0800 /* LOAD_LIBRARY_SEARCH_SYSTEM32 */ ); ++ return; ++ } ++ } ++ ++ static LPCWSTR delayDLLs[] = { L"uxtheme.dll", L"userenv.dll", ++ L"setupapi.dll", L"apphelp.dll", ++ L"propsys.dll", L"dwmapi.dll", ++ L"cryptbase.dll", L"oleacc.dll", ++ L"clbcatq.dll" }; ++ WCHAR systemDirectory[MAX_PATH + 1] = { L'\0' }; ++ // If GetSystemDirectory fails we accept that we'll load the DLLs from the ++ // normal search path. ++ GetSystemDirectoryW(systemDirectory, MAX_PATH + 1); ++ size_t systemDirLen = wcslen(systemDirectory); ++ ++ // Make the system directory path terminate with a slash ++ if (systemDirectory[systemDirLen - 1] != L'\\' && systemDirLen) { ++ systemDirectory[systemDirLen] = L'\\'; ++ ++systemDirLen; ++ // No need to re-NULL terminate ++ } ++ ++ // For each known DLL ensure it is loaded from the system32 directory ++ for (size_t i = 0; i < sizeof(delayDLLs) / sizeof(delayDLLs[0]); ++i) { ++ size_t fileLen = wcslen(delayDLLs[i]); ++ wcsncpy(systemDirectory + systemDirLen, delayDLLs[i], ++ MAX_PATH - systemDirLen); ++ if (systemDirLen + fileLen <= MAX_PATH) { ++ systemDirectory[systemDirLen + fileLen] = L'\0'; ++ } else { ++ systemDirectory[MAX_PATH] = L'\0'; ++ } ++ LPCWSTR fullModulePath = systemDirectory; // just for code readability ++ LoadLibraryW(fullModulePath); ++ } ++ } ++} loadDLLs; ++ ++BOOL ++RemoveCurrentDirFromSearchPath() ++{ ++ // kernel32.dll is in the knownDLL list so it is safe to load without a full path ++ HMODULE kernel32 = LoadLibraryW(L"kernel32.dll"); ++ if (!kernel32) { ++ return FALSE; ++ } ++ ++ typedef BOOL (WINAPI *SetDllDirectoryType)(LPCWSTR); ++ SetDllDirectoryType SetDllDirectoryFn = ++ (SetDllDirectoryType)GetProcAddress(kernel32, "SetDllDirectoryW"); ++ if (!SetDllDirectoryFn) { ++ FreeLibrary(kernel32); ++ return FALSE; ++ } ++ ++ // If this call fails we can't do much about it, so ignore it. ++ // It is unlikely to fail and this is just a precaution anyway. ++ SetDllDirectoryFn(L""); ++ FreeLibrary(kernel32); ++ return TRUE; ++} ++ ++/* END Mozilla customizations */ ++ + int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, + #ifdef UNDER_CE + LPWSTR +@@ -133,13 +529,35 @@ int APIENTRY WinMain(HINSTANCE hInstance + #endif + /* lpCmdLine */,int /* nCmdShow */) + { ++ /* BEGIN Mozilla customizations */ ++ // Disable current directory from being in the search path. ++ // This call does not help with implicitly loaded DLLs. ++ if (!RemoveCurrentDirFromSearchPath()) { ++ WCHAR minOSTitle[512] = { '\0' }; ++ WCHAR minOSText[512] = { '\0' }; ++ LoadStringW(NULL, IDS_MIN_OS_TITLE, minOSTitle, ++ sizeof(minOSTitle) / sizeof(minOSTitle[0])); ++ LoadStringW(NULL, IDS_MIN_OS_TEXT, minOSText, ++ sizeof(minOSText) / sizeof(minOSText[0])); ++ MessageBoxW(NULL, minOSText, minOSTitle, MB_OK | MB_ICONERROR); ++ return 1; ++ } ++ /* END Mozilla customizations */ ++ + g_hInstance = (HINSTANCE)hInstance; + + NT_CHECK + +- #ifdef _WIN32 +- LoadSecurityDlls(); +- #endif ++ // BEGIN Mozilla customizations ++ // Our AutoLoadSystemDependencies (see above) does the same job as the ++ // LoadSecurityDlls function, but slightly better because it runs as a static ++ // initializer, and it doesn't include LOAD_LIBRARY_SEARCH_USER_DIRS in ++ // the search path, which partially defeats the purpose of calling ++ // SetDefaultDllDirectories at all. ++ //#ifdef _WIN32 ++ //LoadSecurityDlls(); ++ //#endif ++ // END Mozilla customizations + + // InitCommonControls(); + +@@ -172,6 +590,18 @@ int APIENTRY WinMain(HINSTANCE hInstance + UString dirPrefix ("." STRING_PATH_SEPARATOR); + UString appLaunched; + bool showProgress = true; ++ ++ /* BEGIN Mozilla customizations */ ++ bool extractOnly = false; ++ if (switches.IsPrefixedBy_NoCase(L"/extractdir=")) { ++ assumeYes = true; ++ showProgress = false; ++ extractOnly = true; ++ } else if (!switches.IsEmpty()) { ++ showProgress = false; ++ } ++ /* END Mozilla customizations */ ++ + if (!config.IsEmpty()) + { + CObjectVector pairs; +@@ -204,7 +634,8 @@ int APIENTRY WinMain(HINSTANCE hInstance + } + + CTempDir tempDir; +- if (!tempDir.Create(kTempDirPrefix)) ++ /* Mozilla customizations - Added !extractOnly */ ++ if (!extractOnly && !tempDir.Create(kTempDirPrefix)) + { + if (!assumeYes) + ShowErrorMessage(L"Can not create temp folder archive"); +@@ -222,7 +653,9 @@ int APIENTRY WinMain(HINSTANCE hInstance + } + } + +- const FString tempDirPath = tempDir.GetPath(); ++ /* BEGIN Mozilla customizations - added extractOnly parameter support */ ++ const FString tempDirPath = extractOnly ? switches.Ptr(12) : GetUnicodeString(tempDir.GetPath()); ++ /* END Mozilla customizations */ + // tempDirPath = L"M:\\1\\"; // to test low disk space + { + bool isCorrupt = false; +@@ -250,6 +683,84 @@ int APIENTRY WinMain(HINSTANCE hInstance + } + } + ++ /* BEGIN Mozilla customizations */ ++ // Retrieve and store any data added to this file after signing. ++ { ++ AString postSigningData; ++ if (ReadPostSigningData(fullPath, postSigningData)) { ++ FString postSigningDataFilePath(tempDirPath); ++ NFile::NName::NormalizeDirPathPrefix(postSigningDataFilePath); ++ postSigningDataFilePath += L"postSigningData"; ++ ++ NFile::NIO::COutFile postSigningDataFile; ++ postSigningDataFile.Create(postSigningDataFilePath, true); ++ ++ UInt32 written = 0; ++ postSigningDataFile.Write(postSigningData, postSigningData.Len(), written); ++ } ++ } ++ ++ // Read Zone Identifier information ++ // This will consist of two types of data that we will write to the same file. ++ // First we have the metadata, which will be INI data with these possible ++ // keys: ++ // - `fileSystem`: What file system the executable is on ++ // - `readFsError`: A string describing why we couldn't get the file system. ++ // Either this key will be present or the `fileSystem` key ++ // will be. ++ // - `readFsErrorCode`: An integer returned by `GetLastError()` indicating, ++ // in more detail, why we failed to obtain the file ++ // system. This key may exist if `readFsError` exists. ++ // - `readZoneIdError`: A string describing why we couldn't get the ++ // provenance data. ++ // - `readZoneIdErrorCode`: An integer returned by `GetLastError()` ++ // indicating, in more detail, why we failed to get the ++ // provenance data. This key may exist if ++ // `readZoneIdError` exists. ++ // - `zoneIdFileSize`: Either `"unknown"`, or an integer indicating the ++ // number of bytes in the zone identifier ADS. ++ // - `zoneIdBufferLargeEnough`: Either `"unknown"`, `"true"`, or `"false"`, ++ // indicating whether the file size was bigger ++ // than the maximum size that we will read from ++ // that file. ++ // - `zoneIdTruncated`: Either `"unknown"`, `"true"`, or `"false"`. Indicates ++ // whether or not we saw the end of the ADS file when we ++ // read from it. ++ // The above keys will be in the `"[Mozilla]"` section of the metadata. ++ // The other type of data that will go into the file is the directly copied ++ // data from the Zone Identifier ADS. This _should_ also be INI data, making ++ // the entirety of the file valid INI data. ++ // In the "good" case, this makes things very easy for us since INI reading ++ // functionality is already available. If we see an unexpected amount of ++ // telemetry data reporting that the INI is invalid, we will probably need to ++ // determine what other data formats are possible in that ADS. ++ // To make it easier to separate out the Zone Identifier data from the ++ // metadata, in that case, the metadata will always end with this sentinel, ++ // as long as `zoneIdData` contains valid data: ++ // `"\n[MozillaZoneIdentifierStartSentinel]\n"` ++ { ++ AString metadata; ++ AutoCharBuffer zoneIdData; ++ ReadZoneIdentifierData(fullPath, metadata, zoneIdData); ++ FString zoneIdDataFilePath(tempDirPath); ++ NFile::NName::NormalizeDirPathPrefix(zoneIdDataFilePath); ++ zoneIdDataFilePath += L"zoneIdProvenanceData"; ++ ++ NFile::NIO::COutFile zoneIdDataFile; ++ zoneIdDataFile.Create(zoneIdDataFilePath, true); ++ ++ UInt32 written = 0; ++ zoneIdDataFile.Write(metadata, metadata.Len(), written); ++ if (zoneIdData.length > 0 && zoneIdData.Buffer()) { ++ zoneIdDataFile.Write(zoneIdData.Buffer(), zoneIdData.length, written); ++ } ++ } ++ ++ if (extractOnly) { ++ return 0; ++ } ++ /* END Mozilla customizations */ ++ + #ifndef UNDER_CE + CCurrentDirRestorer currentDirRestorer; + if (!SetCurrentDir(tempDirPath)) +diff --git a/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/resource.h b/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/resource.h +--- a/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/resource.h ++++ b/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/resource.h +@@ -4,3 +4,5 @@ + #define IDS_EXTRACTION_ERROR_MESSAGE 8 + #define IDS_CANNOT_CREATE_FOLDER 3003 + #define IDS_PROGRESS_EXTRACTING 3300 ++#define IDS_MIN_OS_TITLE 70 ++#define IDS_MIN_OS_TEXT 71 +diff --git a/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/resource.rc b/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/resource.rc +--- a/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/resource.rc ++++ b/other-licenses/7zstub/src/CPP/7zip/Bundles/SFXSetup/resource.rc +@@ -11,6 +11,8 @@ BEGIN + IDS_EXTRACTION_ERROR_MESSAGE "File is corrupt" + IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'" + IDS_PROGRESS_EXTRACTING "Extracting" ++ IDS_MIN_OS_TITLE "Setup Error" ++ IDS_MIN_OS_TEXT "Microsoft Windows 7 or newer is required." + END + + #include "../../UI/FileManager/ProgressDialog.rc" +diff --git a/other-licenses/7zstub/src/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/other-licenses/7zstub/src/CPP/7zip/UI/FileManager/ProgressDialog.cpp +--- a/other-licenses/7zstub/src/CPP/7zip/UI/FileManager/ProgressDialog.cpp ++++ b/other-licenses/7zstub/src/CPP/7zip/UI/FileManager/ProgressDialog.cpp +@@ -165,7 +165,8 @@ bool CProgressDialog::OnButtonClicked(in + bool paused = Sync.GetPaused(); + Sync.SetPaused(true); + _inCancelMessageBox = true; +- int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNOCANCEL); ++ // Mozilla Customization - Removed redundant cancel button from dialog. ++ int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNO); + _inCancelMessageBox = false; + Sync.SetPaused(paused); + if (res == IDCANCEL || res == IDNO) -- cgit v1.2.3