e125ea5f9c
7-Zip 26.01 (ip7z/7zip) never shipped NSIS plugin sources, so they live in a separate bundle directory (versions/26.01-bundle/) that mirrors the layout expected by the shared overlay makefile and by MSBuild. Bundle contents: - CPP/7zip/Bundles/Nsis7z/: NSIS plugin wrapper sources (nsis7z.cpp, pluginapi.cpp, api.h, resource.rc, StdAfx.h, …) and the Windows build project file (Nsis7z_vs2026.vcxproj, adapted from versions/26.00/). The vcxproj references the vendor submodule tree via relative paths (../../../../../26.01/…), keeping the submodule pristine. - CPP/7zip/UI/NSIS/: NSIS UI adapter sources (Main.cpp, MainAr.cpp, NSISBreak.cpp, ExtractCallbackConsole.cpp, UserInputUtils2.cpp and corresponding headers), copied from versions/26.00/. - CPP/7zip/LzmaDec_gcc.mak: forwarding stub; GNU make resolves relative `include` paths against the CWD, so when make runs from Bundles/Nsis7z the upstream Arc_gcc.mak's `include ../../LzmaDec_gcc.mak` lands here. The stub re-includes the real file via $(VENDOR_7ZIP). - Symlinks (C, Asm, CPP/7zip/*, CPP/Common, CPP/Windows, …) pointing into the versions/26.01 submodule. These are required because the vendor makefile uses CWD-relative source paths (../../../../C/…, ../../Common/…). tools/linux/setup_26_01_bundle_symlinks.py recreates them if needed.
314 lines
7.5 KiB
C++
314 lines
7.5 KiB
C++
// Main.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "../../../Common/Common.h"
|
|
#include "Common/MyInitGuid.h"
|
|
|
|
#include "Common/CommandLineParser.h"
|
|
#include "Common/MyException.h"
|
|
#include "Common/IntToString.h"
|
|
#include "Common/StdOutStream.h"
|
|
#include "Common/StringConvert.h"
|
|
#include "Common/StringToInt.h"
|
|
|
|
#include "Windows/FileDir.h"
|
|
#include "Windows/FileName.h"
|
|
#include "Windows/Defs.h"
|
|
#include "Windows/ErrorMsg.h"
|
|
#ifdef _WIN32
|
|
#include "Windows/MemoryLock.h"
|
|
#endif
|
|
|
|
#include "../../IPassword.h"
|
|
#include "../../ICoder.h"
|
|
#include "../Common/UpdateAction.h"
|
|
#include "../Common/Update.h"
|
|
#include "../Common/Extract.h"
|
|
#include "../Common/ArchiveCommandLine.h"
|
|
#include "../Common/ExitCode.h"
|
|
#ifdef EXTERNAL_CODECS
|
|
#include "../Common/LoadCodecs.h"
|
|
#endif
|
|
|
|
//#include "../../Compress/LZMA_Alone/LzmaBenchCon.h"
|
|
|
|
#include "../Console/OpenCallbackConsole.h"
|
|
#include "ExtractCallbackConsole.h"
|
|
|
|
#include "../../MyVersion.h"
|
|
|
|
#if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES)
|
|
extern "C"
|
|
{
|
|
#include "../../../../C/Alloc.h"
|
|
}
|
|
#endif
|
|
|
|
using namespace NWindows;
|
|
using namespace NFile;
|
|
using namespace NCommandLineParser;
|
|
|
|
HINSTANCE g_hInstance = 0;
|
|
|
|
// ---------------------------
|
|
// exception messages
|
|
|
|
#ifndef _WIN32
|
|
static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts)
|
|
{
|
|
parts.Clear();
|
|
for(int i = 0; i < numArguments; i++)
|
|
{
|
|
UString s = MultiByteToUnicodeString(arguments[i]);
|
|
parts.Add(s);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef EXTERNAL_CODECS
|
|
static void PrintString(CStdOutStream &stdStream, const AString &s, int size)
|
|
{
|
|
int len = s.Length();
|
|
stdStream << s;
|
|
for (int i = len; i < size; i++)
|
|
stdStream << ' ';
|
|
}
|
|
#endif
|
|
|
|
static inline char GetHex(Byte value)
|
|
{
|
|
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
void SwitchFileAPIEncoding(BOOL ansi)
|
|
{
|
|
if (ansi)
|
|
{
|
|
SetFileApisToOEM();
|
|
}
|
|
else
|
|
{
|
|
SetFileApisToANSI();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
int DoExtractArchive(UString archive, UString targetDir, bool overwrite, bool extractPaths, ExtractProgressHandler epc, const UStringVector& skipPatterns)
|
|
{
|
|
CCodecs *codecs = new CCodecs;
|
|
CMyComPtr<IUnknown> compressCodecsInfo = codecs;
|
|
HRESULT result = codecs->Load();
|
|
|
|
if (result != S_OK)
|
|
throw CSystemException(result);
|
|
|
|
if (codecs->Formats.Size() == 0) throw -1;
|
|
|
|
CIntVector formatIndices;
|
|
|
|
if (!codecs->FindFormatForArchiveType(L"7z", formatIndices))
|
|
{
|
|
throw -1;
|
|
}
|
|
|
|
BOOL bApisAreAnsi = AreFileApisANSI();
|
|
|
|
#ifdef _WIN32
|
|
if (bApisAreAnsi)
|
|
SwitchFileAPIEncoding(bApisAreAnsi);
|
|
#endif
|
|
|
|
CExtractCallbackConsole *ecs = new CExtractCallbackConsole();
|
|
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
|
|
ecs->Init();
|
|
ecs->ProgressHandler = epc; // Imposta DOPO Init()
|
|
|
|
COpenCallbackConsole openCallback;
|
|
|
|
CExtractOptions eo;
|
|
eo.StdOutMode = false;
|
|
eo.PathMode = extractPaths?NExtract::NPathMode::kCurPaths:NExtract::NPathMode::kNoPaths;
|
|
eo.TestMode = false;
|
|
eo.OverwriteMode = overwrite?NExtract::NOverwriteMode::kOverwrite:NExtract::NOverwriteMode::kSkip;
|
|
eo.OutputDir = targetDir;
|
|
eo.YesToAll = true;
|
|
#ifdef COMPRESS_MT
|
|
CObjectVector<CProperty> prp;
|
|
eo.Properties = prp;
|
|
#endif
|
|
UString errorMessage;
|
|
CDecompressStat stat;
|
|
NWildcard::CCensor wildcardCensor;
|
|
NWildcard::CCensorPathProps props;
|
|
props.Recursive = true;
|
|
props.WildcardMatching = true;
|
|
wildcardCensor.AddItem(NWildcard::ECensorPathMode::k_FullPath, true, L"*", props);
|
|
for (unsigned i = 0; i < skipPatterns.Size(); i++)
|
|
{
|
|
const UString &p = skipPatterns[i];
|
|
if (p.IsEmpty()) continue;
|
|
// Keep only single-name patterns: multi-segment ones land in a separate Pair
|
|
// and would be silently ignored by Pairs.Front().Head below.
|
|
if (p.Find(L'\\') >= 0 || p.Find(L'/') >= 0) continue;
|
|
wildcardCensor.AddItem(NWildcard::ECensorPathMode::k_FullPath, false, p, props);
|
|
}
|
|
UStringVector ArchivePathsSorted;
|
|
UStringVector ArchivePathsFullSorted;
|
|
ArchivePathsSorted.Add(archive);
|
|
UString fullPath;
|
|
NFile::NDir::MyGetFullPathName(archive, fullPath);
|
|
ArchivePathsFullSorted.Add(fullPath);
|
|
|
|
UStringVector v1, v2;
|
|
v1.Add(fs2us(archive));
|
|
v2.Add(fs2us(archive));
|
|
const NWildcard::CCensorNode &wildcardCensorHead =
|
|
wildcardCensor.Pairs.Front().Head;
|
|
|
|
result = Extract(
|
|
codecs, CObjectVector<COpenType>(), CIntVector(),
|
|
v1, v2,
|
|
wildcardCensorHead,
|
|
eo, ecs, ecs, ecs,
|
|
#ifndef Z7_SFX
|
|
NULL, // hash
|
|
#endif
|
|
errorMessage, stat);
|
|
|
|
#ifdef _WIN32
|
|
if (bApisAreAnsi)
|
|
SwitchFileAPIEncoding(!bApisAreAnsi);
|
|
#endif
|
|
|
|
|
|
if (!errorMessage.IsEmpty())
|
|
{
|
|
if (result == S_OK)
|
|
result = E_FAIL;
|
|
}
|
|
|
|
if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
|
|
{
|
|
if (result != S_OK)
|
|
throw CSystemException(result);
|
|
|
|
return NExitCode::kFatalError;
|
|
}
|
|
|
|
if (result != S_OK)
|
|
throw CSystemException(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DoExtractArchiveWithFile(UString archive, UString targetDir, bool overwrite, bool extractPaths, ExtractProgressWithFileHandler epc, const UStringVector& skipPatterns)
|
|
{
|
|
CCodecs *codecs = new CCodecs;
|
|
CMyComPtr<IUnknown> compressCodecsInfo = codecs;
|
|
HRESULT result = codecs->Load();
|
|
|
|
if (result != S_OK)
|
|
throw CSystemException(result);
|
|
|
|
if (codecs->Formats.Size() == 0) throw -1;
|
|
|
|
CIntVector formatIndices;
|
|
|
|
if (!codecs->FindFormatForArchiveType(L"7z", formatIndices))
|
|
{
|
|
throw -1;
|
|
}
|
|
|
|
BOOL bApisAreAnsi = AreFileApisANSI();
|
|
|
|
#ifdef _WIN32
|
|
if (bApisAreAnsi)
|
|
SwitchFileAPIEncoding(bApisAreAnsi);
|
|
#endif
|
|
|
|
CExtractCallbackConsole *ecs = new CExtractCallbackConsole();
|
|
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
|
|
ecs->Init();
|
|
ecs->ProgressWithFileHandler = epc; // Imposta DOPO Init() per evitare che venga resettato
|
|
|
|
COpenCallbackConsole openCallback;
|
|
|
|
CExtractOptions eo;
|
|
eo.StdOutMode = false;
|
|
eo.PathMode = extractPaths?NExtract::NPathMode::kCurPaths:NExtract::NPathMode::kNoPaths;
|
|
eo.TestMode = false;
|
|
eo.OverwriteMode = overwrite?NExtract::NOverwriteMode::kOverwrite:NExtract::NOverwriteMode::kSkip;
|
|
eo.OutputDir = targetDir;
|
|
eo.YesToAll = true;
|
|
#ifdef COMPRESS_MT
|
|
CObjectVector<CProperty> prp;
|
|
eo.Properties = prp;
|
|
#endif
|
|
UString errorMessage;
|
|
CDecompressStat stat;
|
|
NWildcard::CCensor wildcardCensor;
|
|
NWildcard::CCensorPathProps props;
|
|
props.Recursive = true;
|
|
props.WildcardMatching = true;
|
|
wildcardCensor.AddItem(NWildcard::ECensorPathMode::k_FullPath, true, L"*", props);
|
|
for (unsigned i = 0; i < skipPatterns.Size(); i++)
|
|
{
|
|
const UString &p = skipPatterns[i];
|
|
if (p.IsEmpty()) continue;
|
|
// Keep only single-name patterns: multi-segment ones land in a separate Pair
|
|
// and would be silently ignored by Pairs.Front().Head below.
|
|
if (p.Find(L'\\') >= 0 || p.Find(L'/') >= 0) continue;
|
|
wildcardCensor.AddItem(NWildcard::ECensorPathMode::k_FullPath, false, p, props);
|
|
}
|
|
UStringVector ArchivePathsSorted;
|
|
UStringVector ArchivePathsFullSorted;
|
|
ArchivePathsSorted.Add(archive);
|
|
UString fullPath;
|
|
NFile::NDir::MyGetFullPathName(archive, fullPath);
|
|
ArchivePathsFullSorted.Add(fullPath);
|
|
|
|
UStringVector v1, v2;
|
|
v1.Add(fs2us(archive));
|
|
v2.Add(fs2us(archive));
|
|
const NWildcard::CCensorNode &wildcardCensorHead =
|
|
wildcardCensor.Pairs.Front().Head;
|
|
|
|
result = Extract(
|
|
codecs, CObjectVector<COpenType>(), CIntVector(),
|
|
v1, v2,
|
|
wildcardCensorHead,
|
|
eo, ecs, ecs, ecs,
|
|
#ifndef Z7_SFX
|
|
NULL, // hash
|
|
#endif
|
|
errorMessage, stat);
|
|
|
|
#ifdef _WIN32
|
|
if (bApisAreAnsi)
|
|
SwitchFileAPIEncoding(!bApisAreAnsi);
|
|
#endif
|
|
|
|
|
|
if (!errorMessage.IsEmpty())
|
|
{
|
|
if (result == S_OK)
|
|
result = E_FAIL;
|
|
}
|
|
|
|
if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
|
|
{
|
|
if (result != S_OK)
|
|
throw CSystemException(result);
|
|
|
|
return NExitCode::kFatalError;
|
|
}
|
|
|
|
if (result != S_OK)
|
|
throw CSystemException(result);
|
|
|
|
return 0;
|
|
}
|
|
|