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 17Z7_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 40Z7_IFACE_DECL_PURE(IOpenCallbackUI) 41 42Z7_PURE_INTERFACES_END 43 44 45class CMultiStreams Z7_final 46{ 47public: 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; 70private: 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; 76public: 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 97class 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) 120public: 121 Z7_IFACE_COM7_IMP(IArchiveOpenSetSubArchiveName) 122private: 123 #ifndef Z7_NO_CRYPTO 124 Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) 125 #endif 126 127 bool _subArchiveMode; 128 129public: 130 bool PasswordWasAsked; 131 UStringVector FileNames; 132 CBoolVector FileNames_WasUsed; 133 CRecordVector<UInt64> FileSizes; 134 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 158private: 159 FString _folderPrefix; 160 UString _subArchiveName; 161 NWindows::NFile::NFind::CFileInfo _fileInfo; 162 163public: 164 CMultiStreams Volumes; 165 166 // UInt64 TotalSize; 167 168 COpenCallbackImp(): 169 _subArchiveMode(false), 170 ReOpenCallback(NULL), 171 Callback(NULL) {} 172 173 HRESULT Init2(const FString &folderPrefix, const FString &fileName); 174 175 bool SetSecondFileInfo(CFSTR newName) 176 { 177 return _fileInfo.Find_FollowLink(newName) && !_fileInfo.IsDir(); 178 } 179}; 180 181#endif 182