1 // Agent/Agent.h
2 
3 #ifndef __AGENT_AGENT_H
4 #define __AGENT_AGENT_H
5 
6 #include "../../../Common/MyCom.h"
7 
8 #include "../../../Windows/PropVariant.h"
9 
10 #include "../Common/OpenArchive.h"
11 #include "../Common/UpdateAction.h"
12 
13 #ifdef NEW_FOLDER_INTERFACE
14 #include "../FileManager/IFolder.h"
15 #include "../Common/LoadCodecs.h"
16 #endif
17 
18 #include "AgentProxy.h"
19 #include "IFolderArchive.h"
20 
21 extern CCodecs *g_CodecsObj;
22 HRESULT LoadGlobalCodecs();
23 void FreeGlobalCodecs();
24 
25 class CAgentFolder;
26 
27 DECL_INTERFACE(IArchiveFolderInternal, 0x01, 0xC)
28 {
29   STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder) PURE;
30 };
31 
32 struct CProxyItem
33 {
34   unsigned DirIndex;
35   unsigned Index;
36 };
37 
38 class CAgent;
39 
40 enum AGENT_OP
41 {
42   AGENT_OP_Uni,
43   AGENT_OP_Delete,
44   AGENT_OP_CreateFolder,
45   AGENT_OP_Rename,
46   AGENT_OP_CopyFromFile,
47   AGENT_OP_Comment
48 };
49 
50 class CAgentFolder:
51   public IFolderFolder,
52   public IFolderAltStreams,
53   public IFolderProperties,
54   public IArchiveGetRawProps,
55   public IGetFolderArcProps,
56   public IFolderCompare,
57   public IFolderGetItemName,
58   public IArchiveFolder,
59   public IArchiveFolderInternal,
60   public IInArchiveGetStream,
61   // public IFolderSetReplaceAltStreamCharsMode,
62 #ifdef NEW_FOLDER_INTERFACE
63   public IFolderOperations,
64   public IFolderSetFlatMode,
65 #endif
66   public CMyUnknownImp
67 {
68   void LoadFolder(unsigned proxyDirIndex);
69 public:
70 
71   MY_QUERYINTERFACE_BEGIN2(IFolderFolder)
72     MY_QUERYINTERFACE_ENTRY(IFolderAltStreams)
73     MY_QUERYINTERFACE_ENTRY(IFolderProperties)
74     MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
75     MY_QUERYINTERFACE_ENTRY(IGetFolderArcProps)
76     MY_QUERYINTERFACE_ENTRY(IFolderCompare)
77     MY_QUERYINTERFACE_ENTRY(IFolderGetItemName)
78     MY_QUERYINTERFACE_ENTRY(IArchiveFolder)
79     MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal)
80     MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
81     // MY_QUERYINTERFACE_ENTRY(IFolderSetReplaceAltStreamCharsMode)
82   #ifdef NEW_FOLDER_INTERFACE
83     MY_QUERYINTERFACE_ENTRY(IFolderOperations)
84     MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode)
85   #endif
86   MY_QUERYINTERFACE_END
87   MY_ADDREF_RELEASE
88 
89   HRESULT BindToFolder_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder);
90   HRESULT BindToAltStreams_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder);
91   int GetRealIndex(unsigned index) const;
92   void GetRealIndices(const UInt32 *indices, UInt32 numItems,
93       bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const;
94 
95   // INTERFACE_FolderSetReplaceAltStreamCharsMode(;)
96 
97   INTERFACE_FolderFolder(;)
98   INTERFACE_FolderAltStreams(;)
99   INTERFACE_FolderProperties(;)
100   INTERFACE_IArchiveGetRawProps(;)
101   INTERFACE_IFolderGetItemName(;)
102 
103   STDMETHOD(GetFolderArcProps)(IFolderArcProps **object);
104   STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
105   int CompareItems3(UInt32 index1, UInt32 index2, PROPID propID);
106   int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
107 
108   // IArchiveFolder
109   INTERFACE_IArchiveFolder(;)
110 
111   STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder);
112 
113   STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
114 
115   #ifdef NEW_FOLDER_INTERFACE
116   INTERFACE_FolderOperations(;)
117 
118   STDMETHOD(SetFlatMode)(Int32 flatMode);
119   #endif
120 
CAgentFolder()121   CAgentFolder():
122       _proxyDirIndex(0),
123       _isAltStreamFolder(false),
124       _flatMode(false),
125       _loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now
126       /* , _replaceAltStreamCharsMode(0) */
127       {}
128 
Init(const CProxyArc * proxy,const CProxyArc2 * proxy2,unsigned proxyDirIndex,CAgent * agent)129   void Init(const CProxyArc *proxy, const CProxyArc2 *proxy2,
130       unsigned proxyDirIndex,
131       /* IFolderFolder *parentFolder, */
132       CAgent *agent)
133   {
134     _proxy = proxy;
135     _proxy2 = proxy2;
136     _proxyDirIndex = proxyDirIndex;
137     _isAltStreamFolder = false;
138     if (_proxy2)
139       _isAltStreamFolder = _proxy2->IsAltDir(proxyDirIndex);
140     // _parentFolder = parentFolder;
141     _agent = (IInFolderArchive *)agent;
142     _agentSpec = agent;
143   }
144 
145   void GetPathParts(UStringVector &pathParts, bool &isAltStreamFolder);
146   HRESULT CommonUpdateOperation(
147       AGENT_OP operation,
148       bool moveMode,
149       const wchar_t *newItemName,
150       const NUpdateArchive::CActionSet *actionSet,
151       const UInt32 *indices, UInt32 numItems,
152       IProgress *progress);
153 
154 
155   void GetPrefix(UInt32 index, UString &prefix) const;
156   UString GetName(UInt32 index) const;
157   UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive
158 
159 public:
160   const CProxyArc *_proxy;
161   const CProxyArc2 *_proxy2;
162   unsigned _proxyDirIndex;
163   bool _isAltStreamFolder;
164   // CMyComPtr<IFolderFolder> _parentFolder;
165   CMyComPtr<IInFolderArchive> _agent;
166   CAgent *_agentSpec;
167 
168   CRecordVector<CProxyItem> _items;
169   bool _flatMode;
170   bool _loadAltStreams; // in Flat mode
171   // Int32 _replaceAltStreamCharsMode;
172 };
173 
174 class CAgent:
175   public IInFolderArchive,
176   public IFolderArcProps,
177   #ifndef EXTRACT_ONLY
178   public IOutFolderArchive,
179   public ISetProperties,
180   #endif
181   public CMyUnknownImp
182 {
183 public:
184 
185   MY_QUERYINTERFACE_BEGIN2(IInFolderArchive)
186     MY_QUERYINTERFACE_ENTRY(IFolderArcProps)
187   #ifndef EXTRACT_ONLY
188     MY_QUERYINTERFACE_ENTRY(IOutFolderArchive)
189     MY_QUERYINTERFACE_ENTRY(ISetProperties)
190   #endif
191   MY_QUERYINTERFACE_END
192   MY_ADDREF_RELEASE
193 
194   INTERFACE_IInFolderArchive(;)
195   INTERFACE_IFolderArcProps(;)
196 
197   #ifndef EXTRACT_ONLY
198   INTERFACE_IOutFolderArchive(;)
199 
200   HRESULT CommonUpdate(ISequentialOutStream *outArchiveStream,
201       unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback);
202 
203   HRESULT CreateFolder(ISequentialOutStream *outArchiveStream,
204       const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100);
205 
206   HRESULT RenameItem(ISequentialOutStream *outArchiveStream,
207       const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
208       IFolderArchiveUpdateCallback *updateCallback100);
209 
210   HRESULT CommentItem(ISequentialOutStream *outArchiveStream,
211       const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
212       IFolderArchiveUpdateCallback *updateCallback100);
213 
214   HRESULT UpdateOneFile(ISequentialOutStream *outArchiveStream,
215       const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath,
216       IFolderArchiveUpdateCallback *updateCallback100);
217 
218   // ISetProperties
219   STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
220   #endif
221 
222   CAgent();
223   ~CAgent();
224 private:
225   HRESULT ReadItems();
226 public:
227   CProxyArc *_proxy;
228   CProxyArc2 *_proxy2;
229   CArchiveLink _archiveLink;
230 
231   bool ThereIsPathProp;
232   // bool ThereIsAltStreamProp;
233 
234   UString ArchiveType;
235 
236   FStringVector _names;
237   FString _folderPrefix; // for new files from disk
238 
239   bool _updatePathPrefix_is_AltFolder;
240   UString _updatePathPrefix;
241   CAgentFolder *_agentFolder;
242 
243   UString _archiveFilePath;
244   DWORD _attrib;
245   bool _isDeviceFile;
246   bool _isHashHandler;
247   FString _hashBaseFolderPrefix;
248 
249   #ifndef EXTRACT_ONLY
250   CObjectVector<UString> m_PropNames;
251   CObjectVector<NWindows::NCOM::CPropVariant> m_PropValues;
252   #endif
253 
GetArc()254   const CArc &GetArc() const { return _archiveLink.Arcs.Back(); }
GetArchive()255   IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
256   bool CanUpdate() const;
257 
Is_Attrib_ReadOnly()258   bool Is_Attrib_ReadOnly() const
259   {
260     return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY);
261   }
262 
IsThere_ReadOnlyArc()263   bool IsThere_ReadOnlyArc() const
264   {
265     FOR_VECTOR (i, _archiveLink.Arcs)
266     {
267       const CArc &arc = _archiveLink.Arcs[i];
268       if (arc.FormatIndex < 0
269           || arc.IsReadOnly
270           || !g_CodecsObj->Formats[arc.FormatIndex].UpdateEnabled)
271         return true;
272     }
273     return false;
274   }
275 
GetTypeOfArc(const CArc & arc)276   UString GetTypeOfArc(const CArc &arc) const
277   {
278     if (arc.FormatIndex < 0)
279       return UString("Parser");
280     return g_CodecsObj->GetFormatNamePtr(arc.FormatIndex);
281   }
282 
GetErrorMessage()283   UString GetErrorMessage() const
284   {
285     UString s;
286     for (int i = _archiveLink.Arcs.Size() - 1; i >= 0; i--)
287     {
288       const CArc &arc = _archiveLink.Arcs[i];
289 
290       UString s2;
291       if (arc.ErrorInfo.ErrorFormatIndex >= 0)
292       {
293         if (arc.ErrorInfo.ErrorFormatIndex == arc.FormatIndex)
294           s2 += "Warning: The archive is open with offset";
295         else
296         {
297           s2 += "Cannot open the file as [";
298           s2 += g_CodecsObj->GetFormatNamePtr(arc.ErrorInfo.ErrorFormatIndex);
299           s2 += "] archive";
300         }
301       }
302 
303       if (!arc.ErrorInfo.ErrorMessage.IsEmpty())
304       {
305         if (!s2.IsEmpty())
306           s2.Add_LF();
307         s2 += "\n[";
308         s2 += GetTypeOfArc(arc);
309         s2 += "]: ";
310         s2 += arc.ErrorInfo.ErrorMessage;
311       }
312 
313       if (!s2.IsEmpty())
314       {
315         if (!s.IsEmpty())
316           s += "--------------------\n";
317         s += arc.Path;
318         s.Add_LF();
319         s += s2;
320         s.Add_LF();
321       }
322     }
323     return s;
324   }
325 
KeepModeForNextOpen()326   void KeepModeForNextOpen() { _archiveLink.KeepModeForNextOpen(); }
327 
328 };
329 
330 
331 #ifdef NEW_FOLDER_INTERFACE
332 
333 class CArchiveFolderManager:
334   public IFolderManager,
335   public CMyUnknownImp
336 {
337   void LoadFormats();
338   int FindFormat(const UString &type);
339 public:
340   MY_UNKNOWN_IMP1(IFolderManager)
341   INTERFACE_IFolderManager(;)
342 };
343 
344 #endif
345 
346 #endif
347