mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-02-01 00:24:14 -06:00
4.44 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
804edc5756
commit
d9666cf046
Executable
+152
@@ -0,0 +1,152 @@
|
||||
// Extract.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Extract.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "OpenArchive.h"
|
||||
#include "SetProperties.h"
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "Windows/DLL.h"
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
HRESULT DecompressArchive(
|
||||
IInArchive *archive,
|
||||
const UString &defaultName,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
const CExtractOptions &options,
|
||||
IExtractCallbackUI *callback,
|
||||
UString &errorMessage)
|
||||
{
|
||||
CRecordVector<UInt32> realIndices;
|
||||
UInt32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UString filePath;
|
||||
RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath));
|
||||
bool isFolder;
|
||||
RINOK(IsArchiveItemFolder(archive, i, isFolder));
|
||||
if (!wildcardCensor.CheckPath(filePath, !isFolder))
|
||||
continue;
|
||||
realIndices.Add(i);
|
||||
}
|
||||
if (realIndices.Size() == 0)
|
||||
{
|
||||
callback->ThereAreNoFiles();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
|
||||
|
||||
UStringVector removePathParts;
|
||||
|
||||
UString outDir = options.OutputDir;
|
||||
outDir.Replace(L"*", defaultName);
|
||||
if(!outDir.IsEmpty())
|
||||
if(!NFile::NDirectory::CreateComplexDirectory(outDir))
|
||||
{
|
||||
HRESULT res = ::GetLastError();
|
||||
if (res == S_OK)
|
||||
res = E_FAIL;
|
||||
errorMessage = ((UString)L"Can not create output directory ") + outDir;
|
||||
return res;
|
||||
}
|
||||
|
||||
extractCallbackSpec->Init(
|
||||
archive,
|
||||
callback,
|
||||
options.StdOutMode,
|
||||
outDir,
|
||||
options.PathMode,
|
||||
options.OverwriteMode,
|
||||
removePathParts,
|
||||
options.DefaultItemName,
|
||||
options.ArchiveFileInfo.LastWriteTime,
|
||||
options.ArchiveFileInfo.Attributes);
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
RINOK(SetProperties(archive, options.Properties));
|
||||
#endif
|
||||
|
||||
HRESULT result = archive->Extract(&realIndices.Front(),
|
||||
realIndices.Size(), options.TestMode? 1: 0,
|
||||
extractCallback);
|
||||
|
||||
return callback->ExtractResult(result);
|
||||
}
|
||||
|
||||
HRESULT DecompressArchives(
|
||||
UStringVector &archivePaths, UStringVector &archivePathsFull,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
const CExtractOptions &optionsSpec,
|
||||
IOpenCallbackUI *openCallback,
|
||||
IExtractCallbackUI *extractCallback,
|
||||
UString &errorMessage)
|
||||
{
|
||||
CExtractOptions options = optionsSpec;
|
||||
for (int i = 0; i < archivePaths.Size(); i++)
|
||||
{
|
||||
const UString &archivePath = archivePaths[i];
|
||||
NFile::NFind::CFileInfoW archiveFileInfo;
|
||||
if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
|
||||
throw "there is no such archive";
|
||||
|
||||
if (archiveFileInfo.IsDirectory())
|
||||
throw "there is no such archive";
|
||||
|
||||
options.ArchiveFileInfo = archiveFileInfo;
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
openCallback->ClearPasswordWasAskedFlag();
|
||||
#endif
|
||||
|
||||
RINOK(extractCallback->BeforeOpen(archivePath));
|
||||
CArchiveLink archiveLink;
|
||||
HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback);
|
||||
|
||||
bool crypted = false;
|
||||
#ifndef _NO_CRYPTO
|
||||
crypted = openCallback->WasPasswordAsked();
|
||||
#endif
|
||||
|
||||
RINOK(extractCallback->OpenResult(archivePath, result, crypted));
|
||||
if (result != S_OK)
|
||||
continue;
|
||||
|
||||
for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
|
||||
{
|
||||
int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
|
||||
if (index >= 0 && index > i)
|
||||
{
|
||||
archivePaths.Delete(index);
|
||||
archivePathsFull.Delete(index);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
UString password;
|
||||
RINOK(openCallback->GetPasswordIfAny(password));
|
||||
if (!password.IsEmpty())
|
||||
{
|
||||
RINOK(extractCallback->SetPassword(password));
|
||||
}
|
||||
#endif
|
||||
|
||||
options.DefaultItemName = archiveLink.GetDefaultItemName();
|
||||
RINOK(DecompressArchive(
|
||||
archiveLink.GetArchive(), archiveLink.GetDefaultItemName(),
|
||||
wildcardCensor, options, extractCallback, errorMessage));
|
||||
if (!errorMessage.IsEmpty())
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user