xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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