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