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