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 class CArchiveExtractCallback:
128   public IArchiveExtractCallback,
129   // public IArchiveVolumeExtractCallback,
130   public ICryptoGetTextPassword,
131   public ICompressProgressInfo,
132   public CMyUnknownImp
133 {
134   const CArc *_arc;
135   CExtractNtOptions _ntOptions;
136 
137   const NWildcard::CCensorNode *_wildcardCensor;
138   CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
139   CMyComPtr<ICompressProgressInfo> _compressProgress;
140   CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
141   FString _directoryPath;
142   FString _directoryPathFull;
143   NExtract::NPathMode::EEnum _pathMode;
144   NExtract::NOverwriteMode::EEnum _overwriteMode;
145 
146   #ifndef _SFX
147 
148   CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
149   CGetProp *GetProp_Spec;
150   CMyComPtr<IGetProp> GetProp;
151 
152   #endif
153 
154   FString _diskFilePath;
155   UString _filePath;
156   UInt64 _position;
157   bool _isSplit;
158   bool _isAltStream;
159 
160   bool _extractMode;
161 
162   bool WriteCTime;
163   bool WriteATime;
164   bool WriteMTime;
165 
166   bool _encrypted;
167 
168   struct CProcessedFileInfo
169   {
170     FILETIME CTime;
171     FILETIME ATime;
172     FILETIME MTime;
173     UInt32 Attrib;
174 
175     bool CTimeDefined;
176     bool ATimeDefined;
177     bool MTimeDefined;
178     bool AttribDefined;
179 
180     bool IsDir;
181   } _fi;
182 
183   UInt32 _index;
184   UInt64 _curSize;
185   bool _curSizeDefined;
186   COutFileStream *_outFileStreamSpec;
187   CMyComPtr<ISequentialOutStream> _outFileStream;
188 
189   #ifndef _SFX
190 
191   COutStreamWithHash *_hashStreamSpec;
192   CMyComPtr<ISequentialOutStream> _hashStream;
193   bool _hashStreamWasUsed;
194 
195   #endif
196 
197   UStringVector _removePathParts;
198   bool _use_baseParentFolder_mode;
199   UInt32 _baseParentFolder;
200 
201   bool _stdOutMode;
202   bool _testMode;
203   bool _multiArchives;
204 
205   CMyComPtr<ICompressProgressInfo> _localProgress;
206   UInt64 _packTotal;
207   UInt64 _unpTotal;
208 
209   FStringVector _extractedFolderPaths;
210   CRecordVector<UInt32> _extractedFolderIndices;
211 
212   #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
213   bool _saclEnabled;
214   #endif
215 
216   void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
217   HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
218   HRESULT GetUnpackSize();
219 
220   HRESULT SendMessageError(const char *message, const FString &path);
221   HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
222 
223 public:
224 
225   CLocalProgress *LocalProgressSpec;
226 
227   UInt64 NumFolders;
228   UInt64 NumFiles;
229   UInt64 NumAltStreams;
230   UInt64 UnpackSize;
231   UInt64 AltStreams_UnpackSize;
232 
233   MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
234   // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
235 
236   INTERFACE_IArchiveExtractCallback(;)
237 
238   STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
239 
240   // IArchiveVolumeExtractCallback
241   // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
242 
243   STDMETHOD(CryptoGetTextPassword)(BSTR *password);
244 
245   CArchiveExtractCallback();
246 
InitForMulti(bool multiArchives,NExtract::NPathMode::EEnum pathMode,NExtract::NOverwriteMode::EEnum overwriteMode)247   void InitForMulti(bool multiArchives,
248       NExtract::NPathMode::EEnum pathMode,
249       NExtract::NOverwriteMode::EEnum overwriteMode)
250   {
251     _multiArchives = multiArchives;
252     _pathMode = pathMode;
253     _overwriteMode = overwriteMode;
254     NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
255   }
256 
257   #ifndef _SFX
258 
SetHashMethods(IHashCalc * hash)259   void SetHashMethods(IHashCalc *hash)
260   {
261     if (!hash)
262       return;
263     _hashStreamSpec = new COutStreamWithHash;
264     _hashStream = _hashStreamSpec;
265     _hashStreamSpec->_hash = hash;
266   }
267 
268   #endif
269 
270   void Init(
271       const CExtractNtOptions &ntOptions,
272       const NWildcard::CCensorNode *wildcardCensor,
273       const CArc *arc,
274       IFolderArchiveExtractCallback *extractCallback2,
275       bool stdOutMode, bool testMode,
276       const FString &directoryPath,
277       const UStringVector &removePathParts,
278       UInt64 packSize);
279 
280   #ifdef SUPPORT_LINKS
281 private:
282   CHardLinks _hardLinks;
283 public:
284   // call PrepareHardLinks() after Init()
285   HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices);  // NULL means all items
286   #endif
287 
288   // call it after Init()
289 
SetBaseParentFolderIndex(UInt32 indexInArc)290   void SetBaseParentFolderIndex(UInt32 indexInArc)
291   {
292     _use_baseParentFolder_mode = true;
293     _baseParentFolder = indexInArc;
294   }
295 
296   HRESULT SetDirsTimes();
297 };
298 
299 #endif
300