1 // ArchiveOpenCallback.h
2
3 #ifndef ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H
4 #define ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H
5
6 #include "../../../Common/MyCom.h"
7
8 #include "../../../Windows/FileFind.h"
9
10 #include "../../Common/FileStreams.h"
11
12 #ifndef Z7_NO_CRYPTO
13 #include "../../IPassword.h"
14 #endif
15 #include "../../Archive/IArchive.h"
16
17 Z7_PURE_INTERFACES_BEGIN
18
19 #ifdef Z7_NO_CRYPTO
20
21 #define Z7_IFACEM_IOpenCallbackUI_Crypto(x)
22
23 #else
24
25 #define Z7_IFACEM_IOpenCallbackUI_Crypto(x) \
26 virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x \
27 /* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x */ \
28 /* virtual bool Open_WasPasswordAsked() x */ \
29 /* virtual void Open_Clear_PasswordWasAsked_Flag() x */ \
30
31 #endif
32
33 #define Z7_IFACEN_IOpenCallbackUI(x) \
34 virtual HRESULT Open_CheckBreak() x \
35 virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x \
36 virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x \
37 virtual HRESULT Open_Finished() x \
38 Z7_IFACEM_IOpenCallbackUI_Crypto(x)
39
Z7_IFACE_DECL_PURE(IOpenCallbackUI)40 Z7_IFACE_DECL_PURE(IOpenCallbackUI)
41
42 Z7_PURE_INTERFACES_END
43
44
45 class CMultiStreams Z7_final
46 {
47 public:
48 struct CSubStream
49 {
50 CMyComPtr<IInStream> Stream;
51 CInFileStream *FileSpec;
52 FString Path;
53 // UInt64 Size;
54 UInt64 LocalPos;
55 int Next; // next older
56 int Prev; // prev newer
57 // bool IsOpen;
58
59 CSubStream():
60 FileSpec(NULL),
61 // Size(0),
62 LocalPos(0),
63 Next(-1),
64 Prev(-1)
65 // IsOpen(false)
66 {}
67 };
68
69 CObjectVector<CSubStream> Streams;
70 private:
71 // we must use critical section here, if we want to access from different volumnes simultaneously
72 int Head; // newest
73 int Tail; // oldest
74 unsigned NumListItems;
75 unsigned NumOpenFiles_AllowedMax;
76 public:
77
78 CMultiStreams();
79 void Init();
80 HRESULT PrepareToOpenNew();
81 void InsertToList(unsigned index);
82 void RemoveFromList(CSubStream &s);
83 void CloseFile(unsigned index);
84 HRESULT EnsureOpen(unsigned index);
85 };
86
87
88 /*
89 We need COpenCallbackImp class for multivolume processing.
90 Also we use it as proxy from COM interfaces (IArchiveOpenCallback) to internal (IOpenCallbackUI) interfaces.
91 If archive is multivolume:
92 COpenCallbackImp object will exist after Open stage.
93 COpenCallbackImp object will be deleted when last reference
94 from each volume object (CInFileStreamVol) will be closed (when archive will be closed).
95 */
96
97 class COpenCallbackImp Z7_final:
98 public IArchiveOpenCallback,
99 public IArchiveOpenVolumeCallback,
100 public IArchiveOpenSetSubArchiveName,
101 #ifndef Z7_NO_CRYPTO
102 public ICryptoGetTextPassword,
103 #endif
104 public IProgress, // IProgress is used for 7zFM
105 public CMyUnknownImp
106 {
107 Z7_COM_QI_BEGIN2(IArchiveOpenCallback)
108 Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback)
109 Z7_COM_QI_ENTRY(IArchiveOpenSetSubArchiveName)
110 #ifndef Z7_NO_CRYPTO
111 Z7_COM_QI_ENTRY(ICryptoGetTextPassword)
112 #endif
113 // Z7_COM_QI_ENTRY(IProgress) // the code doesn't require it
114 Z7_COM_QI_END
115 Z7_COM_ADDREF_RELEASE
116
117 Z7_IFACE_COM7_IMP(IArchiveOpenCallback)
118 Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback)
119 Z7_IFACE_COM7_IMP(IProgress)
120 public:
121 Z7_IFACE_COM7_IMP(IArchiveOpenSetSubArchiveName)
122 private:
123 #ifndef Z7_NO_CRYPTO
124 Z7_IFACE_COM7_IMP(ICryptoGetTextPassword)
125 #endif
126
127 bool _subArchiveMode;
128
129 public:
130 bool PasswordWasAsked;
131 UStringVector FileNames;
132 CBoolVector FileNames_WasUsed;
133 CRecordVector<UInt64> FileSizes;
134
AtCloseFile(unsigned fileIndex)135 void AtCloseFile(unsigned fileIndex)
136 {
137 FileNames_WasUsed[fileIndex] = false;
138 Volumes.CloseFile(fileIndex);
139 }
140
141 /* we have two ways to Callback from this object
142 1) IArchiveOpenCallback * ReOpenCallback - for ReOpen function, when IOpenCallbackUI is not available
143 2) IOpenCallbackUI *Callback - for usual callback
144 we can't transfer IOpenCallbackUI pointer via internal interface,
145 so we use ReOpenCallback to callback without IOpenCallbackUI.
146 */
147
148 /* we use Callback/ReOpenCallback only at Open stage.
149 So the CMyComPtr reference counter is not required,
150 and we don't want additional reference to unused object,
151 if COpenCallbackImp is not closed
152 */
153 IArchiveOpenCallback *ReOpenCallback;
154 // CMyComPtr<IArchiveOpenCallback> ReOpenCallback;
155 IOpenCallbackUI *Callback;
156 // CMyComPtr<IUnknown> Callback_Ref;
157
158 private:
159 FString _folderPrefix;
160 UString _subArchiveName;
161 NWindows::NFile::NFind::CFileInfo _fileInfo;
162
163 public:
164 CMultiStreams Volumes;
165
166 // UInt64 TotalSize;
167
COpenCallbackImp()168 COpenCallbackImp():
169 _subArchiveMode(false),
170 PasswordWasAsked(false),
171 ReOpenCallback(NULL),
172 Callback(NULL) {}
173
174 HRESULT Init2(const FString &folderPrefix, const FString &fileName);
175
SetSecondFileInfo(CFSTR newName)176 bool SetSecondFileInfo(CFSTR newName)
177 {
178 return _fileInfo.Find_FollowLink(newName) && !_fileInfo.IsDir();
179 }
180 };
181
182 #endif
183