1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Extract.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <stdio.h> 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileDir.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariant.h" 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariantConversions.h" 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/ExtractingFilePath.h" 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Extract.h" 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "SetProperties.h" 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 16baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows; 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 18baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT DecompressArchive( 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CArc &arc, 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 packSize, 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const NWildcard::CCensorNode &wildcardCensor, 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CExtractOptions &options, 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IExtractCallbackUI *callback, 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchiveExtractCallback *extractCallbackSpec, 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString &errorMessage, 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 &stdInProcessed) 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stdInProcessed = 0; 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IInArchive *archive = arc.Archive; 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt32> realIndices; 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!options.StdInMode) 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numItems; 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(archive->GetNumberOfItems(&numItems)); 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = 0; i < numItems; i++) 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString filePath; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(arc.GetItemPath(i, filePath)); 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool isFolder; 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(IsArchiveItemFolder(archive, i, isFolder)); 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!wildcardCensor.CheckPath(filePath, !isFolder)) 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync realIndices.Add(i); 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (realIndices.Size() == 0) 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync callback->ThereAreNoFiles(); 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UStringVector removePathParts; 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString outDir = options.OutputDir; 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName)); 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _WIN32 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // GetCorrectFullFsPath doesn't like "..". 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // outDir.TrimRight(); 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // outDir = GetCorrectFullFsPath(outDir); 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!outDir.IsEmpty()) 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!NFile::NDirectory::CreateComplexDirectory(outDir)) 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT res = ::GetLastError(); 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == S_OK) 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = E_FAIL; 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorMessage = ((UString)L"Can not create output directory ") + outDir; 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync extractCallbackSpec->Init( 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.StdInMode ? &wildcardCensor : NULL, 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &arc, 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync callback, 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.StdOutMode, options.TestMode, options.CalcCrc, 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outDir, 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync removePathParts, 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync packSize); 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #if !defined(_7ZIP_ST) && !defined(_SFX) 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SetProperties(archive, options.Properties)); 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result; 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0; 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.StdInMode) 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec); 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK) 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt == VT_UI8 || prop.vt == VT_UI4) 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stdInProcessed = ConvertPropVariantToUInt64(prop); 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec); 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return callback->ExtractResult(result); 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 102baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT DecompressArchives( 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCodecs *codecs, const CIntVector &formatIndices, 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UStringVector &arcPaths, UStringVector &arcPathsFull, 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const NWildcard::CCensorNode &wildcardCensor, 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CExtractOptions &options, 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IOpenCallbackUI *openCallback, 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IExtractCallbackUI *extractCallback, 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString &errorMessage, 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CDecompressStat &stat) 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stat.Clear(); 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 totalPackSize = 0; 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> archiveSizes; 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numArcs = options.StdInMode ? 1 : arcPaths.Size(); 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numArcs; i++) 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NFile::NFind::CFileInfoW fi; 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fi.Size = 0; 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!options.StdInMode) 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString &arcPath = arcPaths[i]; 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!fi.Find(arcPath)) 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw "there is no such archive"; 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (fi.IsDir()) 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw "can't decompress folder"; 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync archiveSizes.Add(fi.Size); 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync totalPackSize += fi.Size; 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec); 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool multi = (numArcs > 1); 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode); 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (multi) 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->SetTotal(totalPackSize)); 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numArcs; i++) 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString &arcPath = arcPaths[i]; 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NFile::NFind::CFileInfoW fi; 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.StdInMode) 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fi.Size = 0; 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fi.Attrib = 0; 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!fi.Find(arcPath) || fi.IsDir()) 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw "there is no such archive"; 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _NO_CRYPTO 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync openCallback->Open_ClearPasswordWasAskedFlag(); 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->BeforeOpen(arcPath)); 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchiveLink archiveLink; 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CIntVector formatIndices2 = formatIndices; 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _SFX 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (formatIndices.IsEmpty()) 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int pos = arcPath.ReverseFind(L'.'); 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos >= 0) 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString s = arcPath.Mid(pos + 1); 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int index = codecs->FindFormatForExtension(s); 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (index >= 0 && s == L"001") 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s = arcPath.Left(pos); 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos = s.ReverseFind(L'.'); 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos >= 0) 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int index2 = codecs->FindFormatForExtension(s.Mid(pos + 1)); 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (index2 >= 0 && s.CompareNoCase(L"rar") != 0) 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync formatIndices2.Add(index2); 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync formatIndices2.Add(index); 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = archiveLink.Open2(codecs, formatIndices2, options.StdInMode, NULL, arcPath, openCallback); 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result == E_ABORT) 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result; 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool crypted = false; 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _NO_CRYPTO 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crypted = openCallback->Open_WasPasswordAsked(); 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->OpenResult(arcPath, result, crypted)); 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result != S_OK) 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!options.StdInMode) 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]); 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (index >= 0 && index > i) 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcPaths.Delete(index); 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcPathsFull.Delete(index); 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync totalPackSize -= archiveSizes[index]; 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync archiveSizes.Delete(index); 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numArcs = arcPaths.Size(); 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (archiveLink.VolumePaths.Size() != 0) 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync totalPackSize += archiveLink.VolumesSize; 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->SetTotal(totalPackSize)); 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _NO_CRYPTO 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString password; 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(openCallback->Open_GetPasswordIfAny(password)); 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!password.IsEmpty()) 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->SetPassword(password)); 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int v = 0; v < archiveLink.Arcs.Size(); v++) 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString &s = archiveLink.Arcs[v].ErrorMessage; 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!s.IsEmpty()) 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->MessageError(s)); 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArc &arc = archiveLink.Arcs.Back(); 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice); 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arc.MTime = fi.MTime; 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 packProcessed; 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(DecompressArchive(arc, 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fi.Size + archiveLink.VolumesSize, 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage, packProcessed)); 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!options.StdInMode) 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync packProcessed = fi.Size + archiveLink.VolumesSize; 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync extractCallbackSpec->LocalProgressSpec->InSize += packProcessed; 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize; 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!errorMessage.IsEmpty()) 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stat.NumFolders = extractCallbackSpec->NumFolders; 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stat.NumFiles = extractCallbackSpec->NumFiles; 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stat.UnpackSize = extractCallbackSpec->UnpackSize; 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stat.CrcSum = extractCallbackSpec->CrcSum; 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stat.NumArchives = arcPaths.Size(); 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize; 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 264