• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // ExtractCallback.h
2 
3 #ifndef ZIP7_INC_EXTRACT_CALLBACK_H
4 #define ZIP7_INC_EXTRACT_CALLBACK_H
5 
6 #include "../../../../C/Alloc.h"
7 
8 #include "../../../Common/MyCom.h"
9 #include "../../../Common/StringConvert.h"
10 
11 #ifndef Z7_SFX
12 #include "../Agent/IFolderArchive.h"
13 #endif
14 
15 #include "../Common/ArchiveExtractCallback.h"
16 #include "../Common/ArchiveOpenCallback.h"
17 
18 #ifndef Z7_NO_CRYPTO
19 #include "../../IPassword.h"
20 #endif
21 
22 #ifndef Z7_SFX
23 #include "IFolder.h"
24 #endif
25 
26 #include "ProgressDialog2.h"
27 
28 #ifdef Z7_LANG
29 // #include "LangUtils.h"
30 #endif
31 
32 #ifndef Z7_SFX
33 
34 class CGrowBuf
35 {
36   Byte *_items;
37   size_t _size;
38 
Z7_CLASS_NO_COPY(CGrowBuf)39   Z7_CLASS_NO_COPY(CGrowBuf)
40 
41 public:
42   bool ReAlloc_KeepData(size_t newSize, size_t keepSize)
43   {
44     void *buf = MyAlloc(newSize);
45     if (!buf)
46       return false;
47     if (keepSize != 0)
48       memcpy(buf, _items, keepSize);
49     MyFree(_items);
50     _items = (Byte *)buf;
51     _size = newSize;
52     return true;
53   }
54 
CGrowBuf()55   CGrowBuf(): _items(NULL), _size(0) {}
~CGrowBuf()56   ~CGrowBuf() { MyFree(_items); }
57 
58   operator Byte *() { return _items; }
59   operator const Byte *() const { return _items; }
Size()60   size_t Size() const { return _size; }
61 };
62 
63 struct CVirtFile
64 {
65   CGrowBuf Data;
66 
67   UInt64 Size; // real size
68   UInt64 ExpectedSize; // the size from props request. 0 if unknown
69 
70   UString Name;
71 
72   bool CTimeDefined;
73   bool ATimeDefined;
74   bool MTimeDefined;
75   bool AttribDefined;
76 
77   bool IsDir;
78   bool IsAltStream;
79 
80   DWORD Attrib;
81 
82   FILETIME CTime;
83   FILETIME ATime;
84   FILETIME MTime;
85 
CVirtFileCVirtFile86   CVirtFile():
87     CTimeDefined(false),
88     ATimeDefined(false),
89     MTimeDefined(false),
90     AttribDefined(false),
91     IsDir(false),
92     IsAltStream(false) {}
93 };
94 
95 
96 Z7_CLASS_IMP_NOQIB_1(
97   CVirtFileSystem,
98   ISequentialOutStream
99 )
100   UInt64 _totalAllocSize;
101 
102   size_t _pos;
103   unsigned _numFlushed;
104   bool _fileIsOpen;
105   bool _fileMode;
106   CMyComPtr2<ISequentialOutStream, COutFileStream> _outFileStream;
107 public:
108   CObjectVector<CVirtFile> Files;
109   UInt64 MaxTotalAllocSize;
110   FString DirPrefix;
111   CByteBuffer ZoneBuf;
112 
113 
AddNewFile()114   CVirtFile &AddNewFile()
115   {
116     if (!Files.IsEmpty())
117     {
118       MaxTotalAllocSize -= Files.Back().Data.Size();
119     }
120     return Files.AddNew();
121   }
CloseMemFile()122   HRESULT CloseMemFile()
123   {
124     if (_fileMode)
125     {
126       return FlushToDisk(true);
127     }
128     CVirtFile &file = Files.Back();
129     if (file.Data.Size() != file.Size)
130     {
131       file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size);
132     }
133     return S_OK;
134   }
135 
IsStreamInMem()136   bool IsStreamInMem() const
137   {
138     if (_fileMode)
139       return false;
140     if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir)
141       return false;
142     return true;
143   }
144 
GetMemStreamWrittenSize()145   size_t GetMemStreamWrittenSize() const { return _pos; }
146 
CVirtFileSystem()147   CVirtFileSystem():
148     MaxTotalAllocSize((UInt64)0 - 1)
149     {}
150 
Init()151   void Init()
152   {
153     _totalAllocSize = 0;
154     _fileMode = false;
155     _pos = 0;
156     _numFlushed = 0;
157     _fileIsOpen = false;
158   }
159 
160   HRESULT CloseFile(const FString &path);
161   HRESULT FlushToDisk(bool closeLast);
GetPos()162   size_t GetPos() const { return _pos; }
163 };
164 
165 #endif
166 
167 
168 
169 class CExtractCallbackImp Z7_final:
170   public IFolderArchiveExtractCallback,
171   /* IExtractCallbackUI:
172        before v23.00 : it         included IFolderArchiveExtractCallback
173        since  v23.00 : it doesn't include  IFolderArchiveExtractCallback
174   */
175   public IExtractCallbackUI, // NON-COM interface since 23.00
176   public IOpenCallbackUI,    // NON-COM interface
177   public IFolderArchiveExtractCallback2,
178  #ifndef Z7_SFX
179   public IFolderOperationsExtractCallback,
180   public IFolderExtractToStreamCallback,
181   public ICompressProgressInfo,
182   public IArchiveRequestMemoryUseCallback,
183  #endif
184  #ifndef Z7_NO_CRYPTO
185   public ICryptoGetTextPassword,
186  #endif
187   public CMyUnknownImp
188 {
189   Z7_COM_QI_BEGIN2(IFolderArchiveExtractCallback)
190   Z7_COM_QI_ENTRY(IFolderArchiveExtractCallback2)
191  #ifndef Z7_SFX
192   Z7_COM_QI_ENTRY(IFolderOperationsExtractCallback)
193   Z7_COM_QI_ENTRY(IFolderExtractToStreamCallback)
194   Z7_COM_QI_ENTRY(ICompressProgressInfo)
195   Z7_COM_QI_ENTRY(IArchiveRequestMemoryUseCallback)
196  #endif
197  #ifndef Z7_NO_CRYPTO
198   Z7_COM_QI_ENTRY(ICryptoGetTextPassword)
199  #endif
200   Z7_COM_QI_END
201   Z7_COM_ADDREF_RELEASE
202 
203   Z7_IFACE_IMP(IExtractCallbackUI)
204   Z7_IFACE_IMP(IOpenCallbackUI)
205   Z7_IFACE_COM7_IMP(IProgress)
206   Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback)
207   Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback2)
208  #ifndef Z7_SFX
209   Z7_IFACE_COM7_IMP(IFolderOperationsExtractCallback)
210   Z7_IFACE_COM7_IMP(IFolderExtractToStreamCallback)
211   Z7_IFACE_COM7_IMP(ICompressProgressInfo)
212   Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback)
213  #endif
214  #ifndef Z7_NO_CRYPTO
215   Z7_IFACE_COM7_IMP(ICryptoGetTextPassword)
216  #endif
217 
218   bool _needWriteArchivePath;
219   bool _isFolder;
220   bool _totalFilesDefined;
221   bool _totalBytesDefined;
222 public:
223   bool MultiArcMode;
224   bool ProcessAltStreams;
225   bool StreamMode;
226   bool ThereAreMessageErrors;
227 #ifndef Z7_NO_CRYPTO
228   bool PasswordIsDefined;
229   bool PasswordWasAsked;
230 #endif
231 
232 private:
233 #ifndef Z7_SFX
234   bool _needUpdateStat;
235   bool _newVirtFileWasAdded;
236   bool _isAltStream;
237   // bool _extractMode;
238   // bool _testMode;
239   bool _hashStream_WasUsed;
240   bool _curSize_Defined;
241   bool NeedAddFile;
242 
243   bool _remember;
244   bool _skipArc;
245 #endif
246 
247   UString _currentArchivePath;
248   UString _currentFilePath;
249   UString _filePath;
250 
251 #ifndef Z7_SFX
252   UInt64 _curSize;
253   CMyComPtr2<ISequentialOutStream, COutStreamWithHash> _hashStream;
254   IHashCalc *_hashCalc; // it's for stat in Test operation
255 #endif
256 
257 public:
258   CProgressDialog *ProgressDialog;
259 
260 #ifndef Z7_SFX
261   CVirtFileSystem *VirtFileSystemSpec;
262   CMyComPtr<ISequentialOutStream> VirtFileSystem;
263   UInt64 NumFolders;
264   UInt64 NumFiles;
265 #endif
266 
267   UInt32 NumArchiveErrors;
268   NExtract::NOverwriteMode::EEnum OverwriteMode;
269 
270   bool YesToAll;
271   bool TestMode;
272 
273 #ifndef Z7_NO_CRYPTO
274   UString Password;
275 #endif
276 
277   UString _lang_Extracting;
278   UString _lang_Testing;
279   UString _lang_Skipping;
280   UString _lang_Reading;
281   UString _lang_Empty;
282 
283   CExtractCallbackImp():
284       _totalFilesDefined(false)
285     , _totalBytesDefined(false)
286     , MultiArcMode(false)
287     , ProcessAltStreams(true)
288     , StreamMode(false)
289 #ifndef Z7_NO_CRYPTO
290     , PasswordIsDefined(false)
291     , PasswordWasAsked(false)
292 #endif
293 #ifndef Z7_SFX
294     , _remember(false)
295     , _skipArc(false)
296     , _hashCalc(NULL)
297 #endif
298     , OverwriteMode(NExtract::NOverwriteMode::kAsk)
299     , YesToAll(false)
300     , TestMode(false)
301     {}
302 
303   ~CExtractCallbackImp();
304   void Init();
305 
306   HRESULT SetCurrentFilePath2(const wchar_t *filePath);
307   void AddError_Message(LPCWSTR message);
308   void AddError_Message_ShowArcPath(LPCWSTR message);
309   HRESULT MessageError(const char *message, const FString &path);
310   void Add_ArchiveName_Error();
311 
312   #ifndef Z7_SFX
313   void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; }
314 
315   void SetHashMethods(IHashCalc *hash)
316   {
317     if (!hash)
318       return;
319     _hashStream.Create_if_Empty();
320     _hashStream->_hash = hash;
321   }
322   #endif
323 
324   bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; }
325 };
326 
327 #endif
328