1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Client7z.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/IntToString.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/MyInitGuid.h"
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/StringConvert.h"
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/DLL.h"
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileDir.h"
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileFind.h"
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileName.h"
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/NtCheck.h"
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariant.h"
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariantConversions.h"
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/FileStreams.h"
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Archive/IArchive.h"
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../IPassword.h"
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../MyVersion.h"
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// use another CLSIDs, if you want to support other formats (zip, rar, ...).
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// {23170F69-40C1-278A-1000-000110070000}
26baa3858d3f5d128a5c8466b700098109edcad5f2repo syncDEFINE_GUID(CLSID_CFormat7z,
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
29baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows;
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define kDllName "7z.dll"
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
33baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kCopyrightString = MY_7ZIP_VERSION
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync" ("  kDllName " client) "
35baa3858d3f5d128a5c8466b700098109edcad5f2repo syncMY_COPYRIGHT " " MY_DATE;
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
37baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kHelpString =
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync"Examples:\n"
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync"  Client7z.exe a archive.7z f1.txt f2.txt  : compress two files to archive.7z\n"
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync"  Client7z.exe l archive.7z   : List contents of archive.7z\n"
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync"  Client7z.exe x archive.7z   : eXtract files from archive.7z\n";
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
45baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef UINT32 (WINAPI * CreateObjectFunc)(
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const GUID *clsID,
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const GUID *interfaceID,
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    void **outObject);
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
51baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid PrintString(const UString &s)
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  printf("%s", (LPCSTR)GetOemString(s));
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
56baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid PrintString(const AString &s)
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  printf("%s", (LPCSTR)s);
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
61baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid PrintNewLine()
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintString("\n");
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
66baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid PrintStringLn(const AString &s)
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintString(s);
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintNewLine();
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
72baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid PrintError(const AString &s)
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintNewLine();
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintString(s);
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintNewLine();
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
79baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NCOM::CPropVariant prop;
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(archive->GetProperty(index, propID, &prop));
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (prop.vt == VT_BOOL)
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    result = VARIANT_BOOLToBool(prop.boolVal);
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else if (prop.vt == VT_EMPTY)
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    result = false;
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
92baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return IsArchiveItemProp(archive, index, kpidIsDir, result);
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
98baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kEmptyFileAlias = L"[Content]";
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync//////////////////////////////////////////////////////////////
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Archive Open callback class
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
105baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CArchiveOpenCallback:
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public IArchiveOpenCallback,
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public ICryptoGetTextPassword,
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
110baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(CryptoGetTextPassword)(BSTR *password);
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool PasswordIsDefined;
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString Password;
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CArchiveOpenCallback() : PasswordIsDefined(false) {}
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
124baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
129baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
134baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!PasswordIsDefined)
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // You can ask real password here from user
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // Password = GetPassword(OutStream);
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // PasswordIsDefined = true;
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintError("Password is not defined");
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_ABORT;
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return StringToBstr(Password, password);
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync//////////////////////////////////////////////////////////////
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Archive Extracting callback class
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
151baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
153baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kTestingString    =  "Testing     ";
154baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kExtractingString =  "Extracting  ";
155baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kSkippingString   =  "Skipping    ";
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
157baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kUnsupportedMethod = "Unsupported Method";
158baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kCRCFailed = "CRC Failed";
159baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kDataError = "Data Error";
160baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kUnknownError = "Unknown Error";
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
162baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CArchiveExtractCallback:
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public IArchiveExtractCallback,
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public ICryptoGetTextPassword,
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
167baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // IProgress
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetTotal)(UInt64 size);
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetCompleted)(const UInt64 *completeValue);
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // IArchiveExtractCallback
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(PrepareOperation)(Int32 askExtractMode);
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // ICryptoGetTextPassword
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
182baa3858d3f5d128a5c8466b700098109edcad5f2repo syncprivate:
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<IInArchive> _archiveHandler;
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString _directoryPath;  // Output directory
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString _filePath;       // name inside arcvhive
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString _diskFilePath;   // full path to file on disk
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool _extractMode;
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  struct CProcessedFileInfo
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    FILETIME MTime;
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 Attrib;
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool isDir;
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool AttribDefined;
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool MTimeDefined;
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  } _processedFileInfo;
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COutFileStream *_outFileStreamSpec;
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialOutStream> _outFileStream;
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
200baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Init(IInArchive *archiveHandler, const UString &directoryPath);
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 NumErrors;
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool PasswordIsDefined;
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString Password;
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CArchiveExtractCallback() : PasswordIsDefined(false) {}
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
210baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath)
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NumErrors = 0;
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _archiveHandler = archiveHandler;
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _directoryPath = directoryPath;
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NFile::NName::NormalizeDirPathPrefix(_directoryPath);
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
218baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */)
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
223baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
228baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISequentialOutStream **outStream, Int32 askExtractMode)
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *outStream = 0;
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _outFileStream.Release();
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // Get Name
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCOM::CPropVariant prop;
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString fullPath;
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (prop.vt == VT_EMPTY)
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fullPath = kEmptyFileAlias;
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_BSTR)
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fullPath = prop.bstrVal;
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _filePath = fullPath;
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (askExtractMode != NArchive::NExtract::NAskMode::kExtract)
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // Get Attrib
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCOM::CPropVariant prop;
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (prop.vt == VT_EMPTY)
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _processedFileInfo.Attrib = 0;
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _processedFileInfo.AttribDefined = false;
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_UI4)
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _processedFileInfo.Attrib = prop.ulVal;
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _processedFileInfo.AttribDefined = true;
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir));
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // Get Modified Time
276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCOM::CPropVariant prop;
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _processedFileInfo.MTimeDefined = false;
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    switch(prop.vt)
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case VT_EMPTY:
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        // _processedFileInfo.MTime = _utcMTimeDefault;
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case VT_FILETIME:
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _processedFileInfo.MTime = prop.filetime;
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        _processedFileInfo.MTimeDefined = true;
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      default:
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // Get Size
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCOM::CPropVariant prop;
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool newFileSizeDefined = (prop.vt != VT_EMPTY);
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 newFileSize;
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (newFileSizeDefined)
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      newFileSize = ConvertPropVariantToUInt64(prop);
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // Create folders for file
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (slashPos >= 0)
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos));
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString fullProcessedPath = _directoryPath + _filePath;
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _diskFilePath = fullProcessedPath;
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_processedFileInfo.isDir)
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NFile::NFind::CFileInfoW fi;
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (fi.Find(fullProcessedPath))
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath);
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_ABORT;
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outFileStreamSpec = new COutFileStream;
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintString((UString)L"can not open output file " + fullProcessedPath);
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_ABORT;
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outFileStream = outStreamLoc;
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *outStream = outStreamLoc.Detach();
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
343baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _extractMode = false;
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch (askExtractMode)
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NAskMode::kExtract:  _extractMode = true; break;
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  };
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch (askExtractMode)
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NAskMode::kExtract:  PrintString(kExtractingString); break;
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NAskMode::kTest:  PrintString(kTestingString); break;
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NAskMode::kSkip:  PrintString(kSkippingString); break;
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  };
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintString(_filePath);
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
360baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch(operationResult)
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NArchive::NExtract::NOperationResult::kOK:
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    default:
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NumErrors++;
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintString("     ");
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      switch(operationResult)
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          PrintString(kUnsupportedMethod);
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        case NArchive::NExtract::NOperationResult::kCRCError:
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          PrintString(kCRCFailed);
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        case NArchive::NExtract::NOperationResult::kDataError:
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          PrintString(kDataError);
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        default:
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          PrintString(kUnknownError);
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_outFileStream != NULL)
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_processedFileInfo.MTimeDefined)
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_outFileStreamSpec->Close());
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _outFileStream.Release();
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_extractMode && _processedFileInfo.AttribDefined)
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib);
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintNewLine();
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
401baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!PasswordIsDefined)
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // You can ask real password here from user
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // Password = GetPassword(OutStream);
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // PasswordIsDefined = true;
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintError("Password is not defined");
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_ABORT;
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return StringToBstr(Password, password);
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync//////////////////////////////////////////////////////////////
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Archive Creating callback class
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
419baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CDirItem
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 Size;
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  FILETIME CTime;
423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  FILETIME ATime;
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  FILETIME MTime;
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString Name;
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString FullPath;
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 Attrib;
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool isDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
432baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CArchiveUpdateCallback:
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public IArchiveUpdateCallback2,
434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public ICryptoGetTextPassword2,
435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
437baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // IProgress
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetTotal)(UInt64 size);
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetCompleted)(const UInt64 *completeValue);
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // IUpdateCallback2
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(GetUpdateItemInfo)(UInt32 index,
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetOperationResult)(Int32 operationResult);
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
456baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<UInt64> VolumesSizes;
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString VolName;
459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString VolExt;
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString DirPrefix;
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const CObjectVector<CDirItem> *DirItems;
463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool PasswordIsDefined;
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString Password;
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool AskPassword;
467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool m_NeedBeClosed;
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UStringVector FailedFiles;
471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<HRESULT> FailedCodes;
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ~CArchiveUpdateCallback() { Finilize(); }
476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT Finilize();
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Init(const CObjectVector<CDirItem> *dirItems)
479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DirItems = dirItems;
481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    m_NeedBeClosed = false;
482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    FailedFiles.Clear();
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    FailedCodes.Clear();
484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
487baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */)
488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
492baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)
493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
498baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)
499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return E_NOTIMPL;
501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
503baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,
504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (newData != NULL)
507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *newData = BoolToInt(true);
508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (newProperties != NULL)
509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *newProperties = BoolToInt(true);
510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (indexInArchive != NULL)
511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *indexInArchive = (UInt32)-1;
512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
515baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NWindows::NCOM::CPropVariant prop;
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (propID == kpidIsAnti)
520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    prop = false;
522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    prop.Detach(value);
523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CDirItem &dirItem = (*DirItems)[index];
528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    switch(propID)
529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case kpidPath:  prop = dirItem.Name; break;
531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case kpidIsDir:  prop = dirItem.isDir(); break;
532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case kpidSize:  prop = dirItem.Size; break;
533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case kpidAttrib:  prop = dirItem.Attrib; break;
534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case kpidCTime:  prop = dirItem.CTime; break;
535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case kpidATime:  prop = dirItem.ATime; break;
536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case kpidMTime:  prop = dirItem.MTime; break;
537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  prop.Detach(value);
540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
543baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CArchiveUpdateCallback::Finilize()
544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (m_NeedBeClosed)
546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintNewLine();
548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    m_NeedBeClosed = false;
549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
553baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void GetStream2(const wchar_t *name)
554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintString("Compressing  ");
556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (name[0] == 0)
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    name = kEmptyFileAlias;
558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintString(name);
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
561baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(Finilize());
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const CDirItem &dirItem = (*DirItems)[index];
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  GetStream2(dirItem.Name);
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (dirItem.isDir())
569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CInFileStream *inStreamSpec = new CInFileStream;
573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString path = DirPrefix + dirItem.FullPath;
575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!inStreamSpec->Open(path))
576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      DWORD sysError = ::GetLastError();
578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      FailedCodes.Add(sysError);
579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      FailedFiles.Add(path);
580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // if (systemError == ERROR_SHARING_VIOLATION)
581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintNewLine();
583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintError("WARNING: can't open file");
584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        // PrintString(NError::MyFormatMessageW(systemError));
585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return S_FALSE;
586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // return sysError;
588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *inStream = inStreamLoc.Detach();
590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
594baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  m_NeedBeClosed = true;
597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
600baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (VolumesSizes.Size() == 0)
603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_FALSE;
604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (index >= (UInt32)VolumesSizes.Size())
605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    index = VolumesSizes.Size() - 1;
606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *size = VolumesSizes[index];
607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
610baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  wchar_t temp[16];
613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ConvertUInt32ToString(index + 1, temp);
614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString res = temp;
615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (res.Length() < 2)
616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = UString(L'0') + res;
617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString fileName = VolName;
618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  fileName += L'.';
619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  fileName += res;
620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  fileName += VolExt;
621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COutFileStream *streamSpec = new COutFileStream;
622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!streamSpec->Create(fileName, false))
624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return ::GetLastError();
625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *volumeStream = streamLoc.Detach();
626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
629baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!PasswordIsDefined)
632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (AskPassword)
634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // You can ask real password here from user
636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // Password = GetPassword(OutStream);
637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // PasswordIsDefined = true;
638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintError("Password is not defined");
639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_ABORT;
640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *passwordIsDefined = BoolToInt(PasswordIsDefined);
643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return StringToBstr(Password, password);
644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync//////////////////////////////////////////////////////////////////////////
649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Main function
650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
653baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint MY_CDECL main(int numArgs, const char *args[])
654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NT_CHECK
656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintStringLn(kCopyrightString);
658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numArgs < 3)
660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintStringLn(kHelpString);
662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 1;
663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NWindows::NDLL::CLibrary lib;
665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!lib.Load(TEXT(kDllName)))
666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintError("Can not load 7-zip library");
668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 1;
669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CreateObjectFunc createObjectFunc = (CreateObjectFunc)lib.GetProc("CreateObject");
671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (createObjectFunc == 0)
672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintError("Can not get CreateObject");
674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 1;
675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  char c;
678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    AString command = args[1];
680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (command.Length() != 1)
681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintError("incorrect command");
683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    c = MyCharLower(command[0]);
686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString archiveName = GetUnicodeString(args[2]);
688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (c == 'a')
689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // create archive command
691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numArgs < 4)
692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintStringLn(kHelpString);
694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CObjectVector<CDirItem> dirItems;
697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int i;
698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 3; i < numArgs; i++)
699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CDirItem di;
701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UString name = GetUnicodeString(args[i]);
702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NFile::NFind::CFileInfoW fi;
704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!fi.Find(name))
705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintString(UString(L"Can't find file") + name);
707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return 1;
708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      di.Attrib = fi.Attrib;
711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      di.Size = fi.Size;
712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      di.CTime = fi.CTime;
713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      di.ATime = fi.ATime;
714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      di.MTime = fi.MTime;
715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      di.Name = name;
716baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      di.FullPath = name;
717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      dirItems.Add(di);
718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    COutFileStream *outFileStreamSpec = new COutFileStream;
720baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!outFileStreamSpec->Create(archiveName, false))
722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintError("can't create archive file");
724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<IOutArchive> outArchive;
728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK)
729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
730baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintError("Can not get class object");
731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    updateCallbackSpec->Init(&dirItems);
737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // updateCallbackSpec->PasswordIsDefined = true;
738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // updateCallbackSpec->Password = L"1";
739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /*
741baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
742baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      const wchar_t *names[] =
743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        L"s",
745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        L"x"
746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      };
747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      const int kNumProps = sizeof(names) / sizeof(names[0]);
748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NWindows::NCOM::CPropVariant values[kNumProps] =
749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        false,    // solid mode OFF
751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (UInt32)9 // compression level = 9 - ultra
752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      };
753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<ISetProperties> setProperties;
754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties);
755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!setProperties)
756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintError("ISetProperties unsupported");
758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return 1;
759baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
760baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(setProperties->SetProperties(names, values, kNumProps));
761baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
762baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    */
763baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);
765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    updateCallbackSpec->Finilize();
766baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (result != S_OK)
767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintError("Update Error");
769baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
771baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)
772baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
773baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintNewLine();
774baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]);
775baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
776baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (updateCallbackSpec->FailedFiles.Size() != 0)
777baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
778baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numArgs != 3)
782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
783baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintStringLn(kHelpString);
784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool listCommand;
788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (c == 'l')
789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      listCommand = true;
790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else if (c == 'x')
791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      listCommand = false;
792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintError("incorrect command");
795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<IInArchive> archive;
799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK)
800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintError("Can not get class object");
802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CInFileStream *fileSpec = new CInFileStream;
806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<IInStream> file = fileSpec;
807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!fileSpec->Open(archiveName))
809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintError("Can not open archive file");
811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;
816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      openCallbackSpec->PasswordIsDefined = false;
818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // openCallbackSpec->PasswordIsDefined = true;
819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // openCallbackSpec->Password = L"1";
820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
821baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (archive->Open(file, 0, openCallback) != S_OK)
822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintError("Can not open archive");
824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return 1;
825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (listCommand)
829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
830baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // List command
831baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt32 numItems = 0;
832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      archive->GetNumberOfItems(&numItems);
833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (UInt32 i = 0; i < numItems; i++)
834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
836baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          // Get uncompressed size of file
837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          NWindows::NCOM::CPropVariant prop;
838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          archive->GetProperty(i, kpidSize, &prop);
839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          UString s = ConvertPropVariantToString(prop);
840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          PrintString(s);
841baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          PrintString("  ");
842baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
844baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          // Get name of file
845baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          NWindows::NCOM::CPropVariant prop;
846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          archive->GetProperty(i, kpidPath, &prop);
847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          UString s = ConvertPropVariantToString(prop);
848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          PrintString(s);
849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintString("\n");
851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
852baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
855baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // Extract command
856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      extractCallbackSpec->Init(archive, L""); // second parameter is output folder path
859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      extractCallbackSpec->PasswordIsDefined = false;
860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // extractCallbackSpec->PasswordIsDefined = true;
861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // extractCallbackSpec->Password = L"1";
862baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);
863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (result != S_OK)
864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
865baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintError("Extract Error");
866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return 1;
867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
868baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
869baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
870baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 0;
871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
872