• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // ArchiveExtractCallback.h
2 
3 #ifndef __ARCHIVE_EXTRACT_CALLBACK_H
4 #define __ARCHIVE_EXTRACT_CALLBACK_H
5 
6 #include "../../../Common/MyCom.h"
7 #include "../../../Common/Wildcard.h"
8 
9 #include "../../IPassword.h"
10 
11 #include "../../Common/FileStreams.h"
12 #include "../../Common/ProgressUtils.h"
13 
14 #include "../../Archive/IArchive.h"
15 
16 #include "ExtractMode.h"
17 #include "IFileExtractCallback.h"
18 #include "OpenArchive.h"
19 
20 #include "HashCalc.h"
21 
22 #ifndef _SFX
23 
24 class COutStreamWithHash:
25   public ISequentialOutStream,
26   public CMyUnknownImp
27 {
28   CMyComPtr<ISequentialOutStream> _stream;
29   UInt64 _size;
30   bool _calculate;
31 public:
32   IHashCalc *_hash;
33 
34   MY_UNKNOWN_IMP
35   STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
SetStream(ISequentialOutStream * stream)36   void SetStream(ISequentialOutStream *stream) { _stream = stream; }
ReleaseStream()37   void ReleaseStream() { _stream.Release(); }
38   void Init(bool calculate = true)
39   {
40     InitCRC();
41     _size = 0;
42     _calculate = calculate;
43   }
EnableCalc(bool calculate)44   void EnableCalc(bool calculate) { _calculate = calculate; }
InitCRC()45   void InitCRC() { _hash->InitForNewFile(); }
GetSize()46   UInt64 GetSize() const { return _size; }
47 };
48 
49 #endif
50 
51 struct CExtractNtOptions
52 {
53   CBoolPair NtSecurity;
54   CBoolPair SymLinks;
55   CBoolPair HardLinks;
56   CBoolPair AltStreams;
57   bool ReplaceColonForAltStream;
58   bool WriteToAltStreamIfColon;
59 
CExtractNtOptionsCExtractNtOptions60   CExtractNtOptions():
61       ReplaceColonForAltStream(false),
62       WriteToAltStreamIfColon(false)
63   {
64     SymLinks.Val = true;
65     HardLinks.Val = true;
66     AltStreams.Val = true;
67   }
68 };
69 
70 #ifndef _SFX
71 
72 class CGetProp:
73   public IGetProp,
74   public CMyUnknownImp
75 {
76 public:
77   const CArc *Arc;
78   UInt32 IndexInArc;
79   // UString Name; // relative path
80 
81   MY_UNKNOWN_IMP1(IGetProp)
82   INTERFACE_IGetProp(;)
83 };
84 
85 #endif
86 
87 #ifndef _SFX
88 #ifndef UNDER_CE
89 
90 #define SUPPORT_LINKS
91 
92 #endif
93 #endif
94 
95 
96 #ifdef SUPPORT_LINKS
97 
98 struct CHardLinkNode
99 {
100   UInt64 StreamId;
101   UInt64 INode;
102 
103   int Compare(const CHardLinkNode &a) const;
104 };
105 
106 class CHardLinks
107 {
108 public:
109   CRecordVector<CHardLinkNode> IDs;
110   CObjectVector<FString> Links;
111 
Clear()112   void Clear()
113   {
114     IDs.Clear();
115     Links.Clear();
116   }
117 
PrepareLinks()118   void PrepareLinks()
119   {
120     while (Links.Size() < IDs.Size())
121       Links.AddNew();
122   }
123 };
124 
125 #endif
126 
127 #ifdef SUPPORT_ALT_STREAMS
128 
129 struct CIndexToPathPair
130 {
131   UInt32 Index;
132   FString Path;
133 
CIndexToPathPairCIndexToPathPair134   CIndexToPathPair(UInt32 index): Index(index) {}
CIndexToPathPairCIndexToPathPair135   CIndexToPathPair(UInt32 index, const FString &path): Index(index), Path(path) {}
136 
CompareCIndexToPathPair137   int Compare(const CIndexToPathPair &pair) const
138   {
139     return MyCompare(Index, pair.Index);
140   }
141 };
142 
143 #endif
144 
145 class CArchiveExtractCallback:
146   public IArchiveExtractCallback,
147   public IArchiveExtractCallbackMessage,
148   public ICryptoGetTextPassword,
149   public ICompressProgressInfo,
150   public CMyUnknownImp
151 {
152   const CArc *_arc;
153   CExtractNtOptions _ntOptions;
154 
155   const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
156   CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
157   CMyComPtr<ICompressProgressInfo> _compressProgress;
158   CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
159   CMyComPtr<IArchiveExtractCallbackMessage> _callbackMessage;
160   CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2;
161 
162   FString _dirPathPrefix;
163   FString _dirPathPrefix_Full;
164   NExtract::NPathMode::EEnum _pathMode;
165   NExtract::NOverwriteMode::EEnum _overwriteMode;
166 
167   #ifndef _SFX
168 
169   CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
170   CGetProp *GetProp_Spec;
171   CMyComPtr<IGetProp> GetProp;
172 
173   #endif
174 
175   CReadArcItem _item;
176   FString _diskFilePath;
177   UInt64 _position;
178   bool _isSplit;
179 
180   bool _extractMode;
181 
182   bool WriteCTime;
183   bool WriteATime;
184   bool WriteMTime;
185 
186   bool _encrypted;
187 
188   struct CProcessedFileInfo
189   {
190     FILETIME CTime;
191     FILETIME ATime;
192     FILETIME MTime;
193     UInt32 Attrib;
194 
195     bool CTimeDefined;
196     bool ATimeDefined;
197     bool MTimeDefined;
198     bool AttribDefined;
199   } _fi;
200 
201   UInt32 _index;
202   UInt64 _curSize;
203   bool _curSizeDefined;
204   COutFileStream *_outFileStreamSpec;
205   CMyComPtr<ISequentialOutStream> _outFileStream;
206 
207   #ifndef _SFX
208 
209   COutStreamWithHash *_hashStreamSpec;
210   CMyComPtr<ISequentialOutStream> _hashStream;
211   bool _hashStreamWasUsed;
212 
213   #endif
214 
215   bool _removePartsForAltStreams;
216   UStringVector _removePathParts;
217 
218   #ifndef _SFX
219   bool _use_baseParentFolder_mode;
220   UInt32 _baseParentFolder;
221   #endif
222 
223   bool _stdOutMode;
224   bool _testMode;
225   bool _multiArchives;
226 
227   CMyComPtr<ICompressProgressInfo> _localProgress;
228   UInt64 _packTotal;
229 
230   UInt64 _progressTotal;
231   bool _progressTotal_Defined;
232 
233   FStringVector _extractedFolderPaths;
234   CRecordVector<UInt32> _extractedFolderIndices;
235 
236   #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
237   bool _saclEnabled;
238   #endif
239 
240   void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
241   HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
242   HRESULT GetUnpackSize();
243 
244   HRESULT SendMessageError(const char *message, const FString &path);
245   HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
246   HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
247 
248 public:
249 
250   CLocalProgress *LocalProgressSpec;
251 
252   UInt64 NumFolders;
253   UInt64 NumFiles;
254   UInt64 NumAltStreams;
255   UInt64 UnpackSize;
256   UInt64 AltStreams_UnpackSize;
257 
258   MY_UNKNOWN_IMP3(IArchiveExtractCallbackMessage, ICryptoGetTextPassword, ICompressProgressInfo)
259 
260   INTERFACE_IArchiveExtractCallback(;)
261   INTERFACE_IArchiveExtractCallbackMessage(;)
262 
263   STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
264 
265   STDMETHOD(CryptoGetTextPassword)(BSTR *password);
266 
267   CArchiveExtractCallback();
268 
InitForMulti(bool multiArchives,NExtract::NPathMode::EEnum pathMode,NExtract::NOverwriteMode::EEnum overwriteMode)269   void InitForMulti(bool multiArchives,
270       NExtract::NPathMode::EEnum pathMode,
271       NExtract::NOverwriteMode::EEnum overwriteMode)
272   {
273     _multiArchives = multiArchives;
274     _pathMode = pathMode;
275     _overwriteMode = overwriteMode;
276     NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
277   }
278 
279   #ifndef _SFX
280 
SetHashMethods(IHashCalc * hash)281   void SetHashMethods(IHashCalc *hash)
282   {
283     if (!hash)
284       return;
285     _hashStreamSpec = new COutStreamWithHash;
286     _hashStream = _hashStreamSpec;
287     _hashStreamSpec->_hash = hash;
288   }
289 
290   #endif
291 
292   void Init(
293       const CExtractNtOptions &ntOptions,
294       const NWildcard::CCensorNode *wildcardCensor,
295       const CArc *arc,
296       IFolderArchiveExtractCallback *extractCallback2,
297       bool stdOutMode, bool testMode,
298       const FString &directoryPath,
299       const UStringVector &removePathParts, bool removePartsForAltStreams,
300       UInt64 packSize);
301 
302 
303   #ifdef SUPPORT_LINKS
304 
305 private:
306   CHardLinks _hardLinks;
307   UString linkPath;
308 
309   // FString _CopyFile_Path;
310   // HRESULT MyCopyFile(ISequentialOutStream *outStream);
311 
312 public:
313   // call PrepareHardLinks() after Init()
314   HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices);  // NULL means all items
315 
316   #endif
317 
318 
319   #ifdef SUPPORT_ALT_STREAMS
320   CObjectVector<CIndexToPathPair> _renamedFiles;
321   #endif
322 
323   // call it after Init()
324 
325   #ifndef _SFX
SetBaseParentFolderIndex(UInt32 indexInArc)326   void SetBaseParentFolderIndex(UInt32 indexInArc)
327   {
328     _baseParentFolder = indexInArc;
329     _use_baseParentFolder_mode = true;
330   }
331   #endif
332 
333   HRESULT SetDirsTimes();
334 };
335 
336 bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
337 
338 #endif
339