Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/UI/Common/Extract.cpp')
-rwxr-xr-xCPP/7zip/UI/Common/Extract.cpp152
1 files changed, 152 insertions, 0 deletions
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
new file mode 100755
index 00000000..34fb383b
--- /dev/null
+++ b/CPP/7zip/UI/Common/Extract.cpp
@@ -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;
+}