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;
238 
239   bool _updatePathPrefix_is_AltFolder;
240   UString _updatePathPrefix;
241   CAgentFolder *_agentFolder;
242 
243   UString _archiveFilePath;
244   DWORD _attrib;
245   bool _isDeviceFile;
246 
247   #ifndef EXTRACT_ONLY
248   CObjectVector<UString> m_PropNames;
249   CObjectVector<NWindows::NCOM::CPropVariant> m_PropValues;
250   #endif
251 
GetArc()252   const CArc &GetArc() const { return _archiveLink.Arcs.Back(); }
GetArchive()253   IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
254   bool CanUpdate() const;
255 
Is_Attrib_ReadOnly()256   bool Is_Attrib_ReadOnly() const
257   {
258     return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY);
259   }
260 
IsThereReadOnlyArc()261   bool IsThereReadOnlyArc() const
262   {
263     FOR_VECTOR (i, _archiveLink.Arcs)
264     {
265       const CArc &arc = _archiveLink.Arcs[i];
266       if (arc.FormatIndex < 0
267           || arc.IsReadOnly
268           || !g_CodecsObj->Formats[arc.FormatIndex].UpdateEnabled)
269         return true;
270     }
271     return false;
272   }
273 
GetTypeOfArc(const CArc & arc)274   UString GetTypeOfArc(const CArc &arc) const
275   {
276     if (arc.FormatIndex < 0)
277       return UString("Parser");
278     return g_CodecsObj->GetFormatNamePtr(arc.FormatIndex);
279   }
280 
GetErrorMessage()281   UString GetErrorMessage() const
282   {
283     UString s;
284     for (int i = _archiveLink.Arcs.Size() - 1; i >= 0; i--)
285     {
286       const CArc &arc = _archiveLink.Arcs[i];
287 
288       UString s2;
289       if (arc.ErrorInfo.ErrorFormatIndex >= 0)
290       {
291         if (arc.ErrorInfo.ErrorFormatIndex == arc.FormatIndex)
292           s2 += "Warning: The archive is open with offset";
293         else
294         {
295           s2 += "Can not open the file as [";
296           s2 += g_CodecsObj->GetFormatNamePtr(arc.ErrorInfo.ErrorFormatIndex);
297           s2 += "] archive";
298         }
299       }
300 
301       if (!arc.ErrorInfo.ErrorMessage.IsEmpty())
302       {
303         if (!s2.IsEmpty())
304           s2.Add_LF();
305         s2 += "\n[";
306         s2 += GetTypeOfArc(arc);
307         s2 += "]: ";
308         s2 += arc.ErrorInfo.ErrorMessage;
309       }
310 
311       if (!s2.IsEmpty())
312       {
313         if (!s.IsEmpty())
314           s += "--------------------\n";
315         s += arc.Path;
316         s.Add_LF();
317         s += s2;
318         s.Add_LF();
319       }
320     }
321     return s;
322   }
323 
KeepModeForNextOpen()324   void KeepModeForNextOpen() { _archiveLink.KeepModeForNextOpen(); }
325 
326 };
327 
328 
329 #ifdef NEW_FOLDER_INTERFACE
330 
331 class CArchiveFolderManager:
332   public IFolderManager,
333   public CMyUnknownImp
334 {
335   void LoadFormats();
336   int FindFormat(const UString &type);
337 public:
338   MY_UNKNOWN_IMP1(IFolderManager)
339   INTERFACE_IFolderManager(;)
340 };
341 
342 #endif
343 
344 #endif
345