• 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   COutFileStream *_outFileStreamSpec;
107   CMyComPtr<ISequentialOutStream> _outFileStream;
108 public:
109   CObjectVector<CVirtFile> Files;
110   UInt64 MaxTotalAllocSize;
111   FString DirPrefix;
112 
AddNewFile()113   CVirtFile &AddNewFile()
114   {
115     if (!Files.IsEmpty())
116     {
117       MaxTotalAllocSize -= Files.Back().Data.Size();
118     }
119     return Files.AddNew();
120   }
CloseMemFile()121   HRESULT CloseMemFile()
122   {
123     if (_fileMode)
124     {
125       return FlushToDisk(true);
126     }
127     CVirtFile &file = Files.Back();
128     if (file.Data.Size() != file.Size)
129     {
130       file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size);
131     }
132     return S_OK;
133   }
134 
IsStreamInMem()135   bool IsStreamInMem() const
136   {
137     if (_fileMode)
138       return false;
139     if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir)
140       return false;
141     return true;
142   }
143 
GetMemStreamWrittenSize()144   size_t GetMemStreamWrittenSize() const { return _pos; }
145 
CVirtFileSystem()146   CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {}
147 
Init()148   void Init()
149   {
150     _totalAllocSize = 0;
151     _fileMode = false;
152     _pos = 0;
153     _numFlushed = 0;
154     _fileIsOpen = false;
155   }
156 
157   HRESULT CloseFile(const FString &path);
158   HRESULT FlushToDisk(bool closeLast);
GetPos()159   size_t GetPos() const { return _pos; }
160 };
161 
162 #endif
163 
164 class CExtractCallbackImp Z7_final:
165   public IFolderArchiveExtractCallback,
166   /* IExtractCallbackUI:
167        before v23.00 : it         included IFolderArchiveExtractCallback
168        since  v23.00 : it doesn't include  IFolderArchiveExtractCallback
169   */
170   public IExtractCallbackUI, // NON-COM interface since 23.00
171   public IOpenCallbackUI,    // NON-COM interface
172   public IFolderArchiveExtractCallback2,
173  #ifndef Z7_SFX
174   public IFolderOperationsExtractCallback,
175   public IFolderExtractToStreamCallback,
176   public ICompressProgressInfo,
177  #endif
178  #ifndef Z7_NO_CRYPTO
179   public ICryptoGetTextPassword,
180  #endif
181   public CMyUnknownImp
182 {
183   Z7_COM_QI_BEGIN2(IFolderArchiveExtractCallback)
184   Z7_COM_QI_ENTRY(IFolderArchiveExtractCallback2)
185  #ifndef Z7_SFX
186   Z7_COM_QI_ENTRY(IFolderOperationsExtractCallback)
187   Z7_COM_QI_ENTRY(IFolderExtractToStreamCallback)
188   Z7_COM_QI_ENTRY(ICompressProgressInfo)
189  #endif
190  #ifndef Z7_NO_CRYPTO
191   Z7_COM_QI_ENTRY(ICryptoGetTextPassword)
192  #endif
193   Z7_COM_QI_END
194   Z7_COM_ADDREF_RELEASE
195 
196   Z7_IFACE_IMP(IExtractCallbackUI)
197   Z7_IFACE_IMP(IOpenCallbackUI)
198   Z7_IFACE_COM7_IMP(IProgress)
199   Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback)
200   Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback2)
201  #ifndef Z7_SFX
202   Z7_IFACE_COM7_IMP(IFolderOperationsExtractCallback)
203   Z7_IFACE_COM7_IMP(IFolderExtractToStreamCallback)
204   Z7_IFACE_COM7_IMP(ICompressProgressInfo)
205  #endif
206  #ifndef Z7_NO_CRYPTO
207   Z7_IFACE_COM7_IMP(ICryptoGetTextPassword)
208  #endif
209 
210 
211   UString _currentArchivePath;
212   bool _needWriteArchivePath;
213 
214   bool _isFolder;
215   UString _currentFilePath;
216   UString _filePath;
217 
218  #ifndef Z7_SFX
219   bool _needUpdateStat;
220   bool _newVirtFileWasAdded;
221   bool _isAltStream;
222   bool _curSize_Defined;
223   UInt64 _curSize;
224   // bool _extractMode;
225   // bool _testMode;
226   bool _hashStreamWasUsed;
227   COutStreamWithHash *_hashStreamSpec;
228   CMyComPtr<ISequentialOutStream> _hashStream;
229   IHashCalc *_hashCalc; // it's for stat in Test operation
230  #endif
231 
232   HRESULT SetCurrentFilePath2(const wchar_t *filePath);
233   void AddError_Message(LPCWSTR message);
234   HRESULT MessageError(const char *message, const FString &path);
235   void Add_ArchiveName_Error();
236 
237 public:
238 
239   #ifndef Z7_SFX
240   CVirtFileSystem *VirtFileSystemSpec;
241   CMyComPtr<ISequentialOutStream> VirtFileSystem;
242   #endif
243 
244   bool ProcessAltStreams;
245 
246   bool StreamMode;
247 
248   CProgressDialog *ProgressDialog;
249   #ifndef Z7_SFX
250   UInt64 NumFolders;
251   UInt64 NumFiles;
252   bool NeedAddFile;
253   #endif
254   UInt32 NumArchiveErrors;
255   bool ThereAreMessageErrors;
256   NExtract::NOverwriteMode::EEnum OverwriteMode;
257 
258   #ifndef Z7_NO_CRYPTO
259   bool PasswordIsDefined;
260   bool PasswordWasAsked;
261   UString Password;
262   #endif
263 
264 
265   UString _lang_Extracting;
266   UString _lang_Testing;
267   UString _lang_Skipping;
268   UString _lang_Reading;
269   UString _lang_Empty;
270 
271   bool _totalFilesDefined;
272   bool _totalBytesDefined;
273   bool MultiArcMode;
274 
275   CExtractCallbackImp():
276     #ifndef Z7_SFX
277     _hashCalc(NULL),
278     #endif
279     ProcessAltStreams(true),
280     StreamMode(false),
281     OverwriteMode(NExtract::NOverwriteMode::kAsk),
282     #ifndef Z7_NO_CRYPTO
283     PasswordIsDefined(false),
284     PasswordWasAsked(false),
285     #endif
286     _totalFilesDefined(false),
287     _totalBytesDefined(false),
288     MultiArcMode(false)
289     {}
290 
291   ~CExtractCallbackImp();
292   void Init();
293 
294   #ifndef Z7_SFX
295   void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; }
296 
297   void SetHashMethods(IHashCalc *hash)
298   {
299     if (!hash)
300       return;
301     _hashStreamSpec = new COutStreamWithHash;
302     _hashStream = _hashStreamSpec;
303     _hashStreamSpec->_hash = hash;
304   }
305   #endif
306 
307   bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; }
308 };
309 
310 #endif
311