1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// ArchiveExtractCallback.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/ComTry.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/Wildcard.h"
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileDir.h"
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileFind.h"
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariant.h"
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariantConversions.h"
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/FilePathAutoRename.h"
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/ExtractingFilePath.h"
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "ArchiveExtractCallback.h"
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
19baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows;
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
21baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name";
22baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";
23baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
25baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CArchiveExtractCallback::Init(
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const NWildcard::CCensorNode *wildcardCensor,
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CArc *arc,
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IFolderArchiveExtractCallback *extractCallback2,
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool stdOutMode, bool testMode, bool crcMode,
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UString &directoryPath,
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UStringVector &removePathParts,
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 packSize)
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _wildcardCensor = wildcardCensor;
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _stdOutMode = stdOutMode;
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _testMode = testMode;
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _crcMode = crcMode;
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _unpTotal = 1;
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _packTotal = packSize;
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _extractCallback2 = extractCallback2;
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _compressProgress.Release();
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LocalProgressSpec->Init(extractCallback2, true);
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LocalProgressSpec->SendProgress = false;
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _removePathParts = removePathParts;
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _arc = arc;
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _directoryPath = directoryPath;
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NFile::NName::NormalizeDirPathPrefix(_directoryPath);
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
56baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _unpTotal = size;
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!_multiArchives && _extractCallback2)
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return _extractCallback2->SetTotal(size);
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
66baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void NormalizeVals(UInt64 &v1, UInt64 &v2)
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UInt64 kMax = (UInt64)1 << 31;
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (v1 > kMax)
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    v1 >>= 1;
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    v2 >>= 1;
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
76baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal)
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NormalizeVals(packTotal, unpTotal);
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NormalizeVals(unpCur, unpTotal);
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (unpTotal == 0)
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    unpTotal = 1;
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return unpCur * packTotal / unpTotal;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
85baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!_extractCallback2)
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_multiArchives)
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (completeValue != NULL)
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt64 packCur = LocalProgressSpec->InSize + MyMultDiv64(*completeValue, _unpTotal, _packTotal);
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return _extractCallback2->SetCompleted(&packCur);
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return _extractCallback2->SetCompleted(completeValue);
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
103baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return _localProgress->SetRatioInfo(inSize, outSize);
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
110baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath)
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  fullPath = _directoryPath;
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < dirPathParts.Size(); i++)
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (i > 0)
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fullPath += wchar_t(NFile::NName::kDirDelimiter);
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    fullPath += dirPathParts[i];
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NFile::NDirectory::MyCreateDirectory(fullPath);
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
122baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  filetimeIsDefined = false;
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NCOM::CPropVariant prop;
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(_arc->Archive->GetProperty(index, propID, &prop));
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (prop.vt == VT_FILETIME)
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    filetime = prop.filetime;
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0);
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else if (prop.vt != VT_EMPTY)
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
137baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CArchiveExtractCallback::GetUnpackSize()
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NCOM::CPropVariant prop;
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(_arc->Archive->GetProperty(_index, kpidSize, &prop));
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _curSizeDefined = (prop.vt != VT_EMPTY);
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_curSizeDefined)
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _curSize = ConvertPropVariantToUInt64(prop);
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
147baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _crcStream.Release();
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *outStream = 0;
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _outFileStream.Release();
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _encrypted = false;
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _isSplit = false;
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _curSize = 0;
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _curSizeDefined = false;
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _index = index;
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString fullPath;
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IInArchive *archive = _arc->Archive;
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(_arc->GetItemPath(index, fullPath));
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(IsArchiveItemFolder(archive, index, _fi.IsDir));
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _filePath = fullPath;
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCOM::CPropVariant prop;
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(archive->GetProperty(index, kpidPosition, &prop));
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (prop.vt != VT_EMPTY)
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_UI8)
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _position = prop.uhVal.QuadPart;
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _isSplit = true;
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(GetArchiveItemBoolProp(archive, index, kpidEncrypted, _encrypted));
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(GetUnpackSize());
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_wildcardCensor)
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!_wildcardCensor->CheckPath(fullPath, !_fi.IsDir))
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_OK;
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_stdOutMode)
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream;
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      *outStream = outStreamLoc.Detach();
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_OK;
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCOM::CPropVariant prop;
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(archive->GetProperty(index, kpidAttrib, &prop));
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt == VT_UI4)
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _fi.Attrib = prop.ulVal;
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _fi.AttribDefined = true;
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else if (prop.vt == VT_EMPTY)
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _fi.AttribDefined = false;
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(GetTime(index, kpidCTime, _fi.CTime, _fi.CTimeDefined));
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(GetTime(index, kpidATime, _fi.ATime, _fi.ATimeDefined));
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(GetTime(index, kpidMTime, _fi.MTime, _fi.MTimeDefined));
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool isAnti = false;
218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_arc->IsItemAnti(index, isAnti));
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UStringVector pathParts;
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SplitPathToParts(fullPath, pathParts);
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pathParts.IsEmpty())
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int numRemovePathParts = 0;
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    switch(_pathMode)
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case NExtract::NPathMode::kFullPathnames:
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case NExtract::NPathMode::kCurrentPathnames:
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        numRemovePathParts = _removePathParts.Size();
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (pathParts.Size() <= numRemovePathParts)
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_FAIL;
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (int i = 0; i < numRemovePathParts; i++)
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (_removePathParts[i].CompareNoCase(pathParts[i]) != 0)
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            return E_FAIL;
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case NExtract::NPathMode::kNoPathnames:
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        numRemovePathParts = pathParts.Size() - 1;
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pathParts.Delete(0, numRemovePathParts);
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MakeCorrectPath(pathParts);
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString processedPath = MakePathNameFromParts(pathParts);
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!isAnti)
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!_fi.IsDir)
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!pathParts.IsEmpty())
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          pathParts.DeleteBack();
255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!pathParts.IsEmpty())
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UString fullPathNew;
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        CreateComplexDirectory(pathParts, fullPathNew);
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (_fi.IsDir)
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          NFile::NDirectory::SetDirTime(fullPathNew,
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString fullProcessedPath = _directoryPath + processedPath;
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_fi.IsDir)
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _diskFilePath = fullProcessedPath;
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (isAnti)
276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        NFile::NDirectory::MyRemoveDirectory(_diskFilePath);
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_OK;
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!_isSplit)
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NFile::NFind::CFileInfoW fileInfo;
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (fileInfo.Find(fullProcessedPath))
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      switch(_overwriteMode)
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        case NExtract::NOverwriteMode::kSkipExisting:
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return S_OK;
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        case NExtract::NOverwriteMode::kAskBefore:
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          Int32 overwiteResult;
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          RINOK(_extractCallback2->AskOverwrite(
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              fullProcessedPath, &fileInfo.MTime, &fileInfo.Size, fullPath,
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              _fi.MTimeDefined ? &_fi.MTime : NULL,
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              _curSizeDefined ? &_curSize : NULL,
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              &overwiteResult))
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          switch(overwiteResult)
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            case NOverwriteAnswer::kCancel:
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              return E_ABORT;
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            case NOverwriteAnswer::kNo:
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              return S_OK;
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            case NOverwriteAnswer::kNoToAll:
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              _overwriteMode = NExtract::NOverwriteMode::kSkipExisting;
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              return S_OK;
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            case NOverwriteAnswer::kYesToAll:
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              break;
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            case NOverwriteAnswer::kYes:
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              break;
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            case NOverwriteAnswer::kAutoRename:
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              _overwriteMode = NExtract::NOverwriteMode::kAutoRename;
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              break;
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            default:
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              return E_FAIL;
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename)
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!AutoRenamePath(fullProcessedPath))
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          UString message = UString(kCantAutoRename) + fullProcessedPath;
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          RINOK(_extractCallback2->MessageError(message));
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_FAIL;
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UString existPath = fullProcessedPath;
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!AutoRenamePath(existPath))
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          UString message = kCantAutoRename + fullProcessedPath;
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          RINOK(_extractCallback2->MessageError(message));
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_FAIL;
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          UString message = UString(kCantRenameFile) + fullProcessedPath;
341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          RINOK(_extractCallback2->MessageError(message));
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_FAIL;
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          UString message = UString(kCantDeleteOutputFile) +  fullProcessedPath;
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          RINOK(_extractCallback2->MessageError(message));
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return S_OK;
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          // return E_FAIL;
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!isAnti)
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _outFileStreamSpec = new COutFileStream;
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          UString message = L"can not open output file " + fullProcessedPath;
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          RINOK(_extractCallback2->MessageError(message));
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return S_OK;
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (_isSplit)
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _outFileStream = outStreamLoc;
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      *outStream = outStreamLoc.Detach();
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _diskFilePath = fullProcessedPath;
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *outStream = NULL;
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_crcMode)
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crcStreamSpec = new COutStreamWithCRC;
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crcStream = _crcStreamSpec;
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISequentialOutStream> crcStream = _crcStreamSpec;
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crcStreamSpec->SetStream(*outStream);
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (*outStream)
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      (*outStream)->Release();
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *outStream = crcStream.Detach();
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crcStreamSpec->Init(true);
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
396baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _extractMode = false;
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch (askExtractMode)
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NAskMode::kExtract:
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (_testMode)
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        askExtractMode = NArchive::NExtract::NAskMode::kTest;
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _extractMode = true;
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  };
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return _extractCallback2->PrepareOperation(_filePath, _fi.IsDir,
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      askExtractMode, _isSplit ? &_position: 0);
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
414baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch(operationResult)
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NOperationResult::kOK:
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NOperationResult::kCRCError:
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NOperationResult::kDataError:
423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    default:
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _outFileStream.Release();
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_crcStream)
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CrcSum += _crcStreamSpec->GetCRC();
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _curSize = _crcStreamSpec->GetSize();
432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _curSizeDefined = true;
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crcStream.Release();
434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_outFileStream)
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outFileStreamSpec->SetTime(
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _curSize = _outFileStreamSpec->ProcessedSize;
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _curSizeDefined = true;
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_outFileStreamSpec->Close());
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outFileStream.Release();
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!_curSizeDefined)
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    GetUnpackSize();
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_curSizeDefined)
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UnpackSize += _curSize;
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_fi.IsDir)
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NumFolders++;
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NumFiles++;
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_extractMode && _fi.AttribDefined)
456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib);
457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/*
463baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::GetInStream(
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const wchar_t *name, ISequentialInStream **inStream)
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CInFileStream *inFile = new CInFileStream;
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialInStream> inStreamTemp = inFile;
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!inFile->Open(_srcDirectoryPrefix + name))
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return ::GetLastError();
471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *inStream = inStreamTemp.Detach();
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/
476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
477baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!_cryptoGetTextPassword)
481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword,
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        &_cryptoGetTextPassword));
484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return _cryptoGetTextPassword->CryptoGetTextPassword(password);
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
489