1 // OpenArchive.h 2 3 #ifndef __OPEN_ARCHIVE_H 4 #define __OPEN_ARCHIVE_H 5 6 #include "../../../Windows/PropVariant.h" 7 8 #include "ArchiveOpenCallback.h" 9 #include "LoadCodecs.h" 10 #include "Property.h" 11 12 HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw(); 13 HRESULT Archive_IsItem_Folder(IInArchive *arc, UInt32 index, bool &result) throw(); 14 HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw(); 15 HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw(); 16 HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &deleted) throw(); 17 18 /* 19 struct COptionalOpenProperties 20 { 21 UString FormatName; 22 CObjectVector<CProperty> Props; 23 }; 24 */ 25 26 #ifdef _SFX 27 #define OPEN_PROPS_DECL 28 #else 29 #define OPEN_PROPS_DECL const CObjectVector<CProperty> *props; 30 // #define OPEN_PROPS_DECL , const CObjectVector<COptionalOpenProperties> *props 31 #endif 32 33 struct COpenSpecFlags 34 { 35 // bool CanReturnFull; 36 bool CanReturnFrontal; 37 bool CanReturnTail; 38 bool CanReturnMid; 39 40 bool CanReturn_NonStart() const { return CanReturnTail || CanReturnMid; } 41 42 COpenSpecFlags(): 43 // CanReturnFull(true), 44 CanReturnFrontal(false), 45 CanReturnTail(false), 46 CanReturnMid(false) 47 {} 48 }; 49 50 struct COpenType 51 { 52 int FormatIndex; 53 54 COpenSpecFlags SpecForcedType; 55 COpenSpecFlags SpecMainType; 56 COpenSpecFlags SpecWrongExt; 57 COpenSpecFlags SpecUnknownExt; 58 59 bool Recursive; 60 61 bool CanReturnArc; 62 bool CanReturnParser; 63 bool EachPos; 64 65 // bool SkipSfxStub; 66 // bool ExeAsUnknown; 67 68 bool ZerosTailIsAllowed; 69 70 bool MaxStartOffset_Defined; 71 UInt64 MaxStartOffset; 72 73 const COpenSpecFlags &GetSpec(bool isForced, bool isMain, bool isUnknown) const 74 { 75 return isForced ? SpecForcedType : (isMain ? SpecMainType : (isUnknown ? SpecUnknownExt : SpecWrongExt)); 76 } 77 78 COpenType(): 79 FormatIndex(-1), 80 Recursive(true), 81 EachPos(false), 82 CanReturnArc(true), 83 CanReturnParser(false), 84 // SkipSfxStub(true), 85 // ExeAsUnknown(true), 86 ZerosTailIsAllowed(false), 87 MaxStartOffset_Defined(false), 88 MaxStartOffset(0) 89 { 90 SpecForcedType.CanReturnFrontal = true; 91 SpecForcedType.CanReturnTail = true; 92 SpecForcedType.CanReturnMid = true; 93 94 SpecMainType.CanReturnFrontal = true; 95 96 SpecUnknownExt.CanReturnTail = true; // for sfx 97 SpecUnknownExt.CanReturnMid = true; 98 SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad 99 100 // ZerosTailIsAllowed = true; 101 } 102 }; 103 104 struct COpenOptions 105 { 106 CCodecs *codecs; 107 COpenType openType; 108 const CObjectVector<COpenType> *types; 109 const CIntVector *excludedFormats; 110 111 IInStream *stream; 112 ISequentialInStream *seqStream; 113 IArchiveOpenCallback *callback; 114 COpenCallbackImp *callbackSpec; 115 OPEN_PROPS_DECL 116 // bool openOnlySpecifiedByExtension, 117 118 bool stdInMode; 119 UString filePath; 120 121 COpenOptions(): 122 codecs(NULL), 123 types(NULL), 124 excludedFormats(NULL), 125 stream(NULL), 126 seqStream(NULL), 127 callback(NULL), 128 callbackSpec(NULL), 129 stdInMode(false) 130 {} 131 132 }; 133 134 UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL); 135 136 struct CArcErrorInfo 137 { 138 bool ThereIsTail; 139 bool UnexpecedEnd; 140 bool IgnoreTail; // all are zeros 141 // bool NonZerosTail; 142 bool ErrorFlags_Defined; 143 UInt32 ErrorFlags; 144 UInt32 WarningFlags; 145 int ErrorFormatIndex; // - 1 means no Error. 146 // if FormatIndex == ErrorFormatIndex, the archive is open with offset 147 UInt64 TailSize; 148 149 /* if CArc is Open OK with some format: 150 - ErrorFormatIndex shows error format index, if extension is incorrect 151 - other variables show message and warnings of archive that is open */ 152 153 UString ErrorMessage; 154 UString WarningMessage; 155 156 // call IsArc_After_NonOpen only if Open returns S_FALSE 157 bool IsArc_After_NonOpen() const 158 { 159 return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0); 160 } 161 162 163 CArcErrorInfo(): 164 ThereIsTail(false), 165 UnexpecedEnd(false), 166 IgnoreTail(false), 167 // NonZerosTail(false), 168 ErrorFlags_Defined(false), 169 ErrorFlags(0), 170 WarningFlags(0), 171 ErrorFormatIndex(-1), 172 TailSize(0) 173 {} 174 175 void ClearErrors(); 176 177 void ClearErrors_Full() 178 { 179 ErrorFormatIndex = -1; 180 ClearErrors(); 181 } 182 183 bool IsThereErrorOrWarning() const 184 { 185 return ErrorFlags != 0 186 || WarningFlags != 0 187 || NeedTailWarning() 188 || UnexpecedEnd 189 || !ErrorMessage.IsEmpty() 190 || !WarningMessage.IsEmpty(); 191 } 192 193 bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; } 194 bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); } 195 196 bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; } 197 198 UInt32 GetWarningFlags() const 199 { 200 UInt32 a = WarningFlags; 201 if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0) 202 a |= kpv_ErrorFlags_DataAfterEnd; 203 return a; 204 } 205 206 UInt32 GetErrorFlags() const 207 { 208 UInt32 a = ErrorFlags; 209 if (UnexpecedEnd) 210 a |= kpv_ErrorFlags_UnexpectedEnd; 211 return a; 212 } 213 }; 214 215 class CArc 216 { 217 HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive); 218 HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset); 219 HRESULT OpenStream2(const COpenOptions &options); 220 221 public: 222 CMyComPtr<IInArchive> Archive; 223 CMyComPtr<IInStream> InStream; 224 // we use InStream in 2 cases (ArcStreamOffset != 0): 225 // 1) if we use additional cache stream 226 // 2) we reopen sfx archive with CTailInStream 227 228 CMyComPtr<IArchiveGetRawProps> GetRawProps; 229 CMyComPtr<IArchiveGetRootProps> GetRootProps; 230 231 CArcErrorInfo ErrorInfo; // for OK archives 232 CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN) 233 234 UString Path; 235 UString filePath; 236 UString DefaultName; 237 int FormatIndex; // - 1 means Parser. 238 int SubfileIndex; 239 FILETIME MTime; 240 bool MTimeDefined; 241 242 Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler 243 UInt64 PhySize; 244 // UInt64 OkPhySize; 245 bool PhySizeDefined; 246 // bool OkPhySize_Defined; 247 UInt64 FileSize; 248 UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file 249 // bool offsetDefined; 250 251 UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler 252 Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive 253 254 // AString ErrorFlagsText; 255 256 bool IsParseArc; 257 258 bool IsTree; 259 260 bool Ask_Deleted; 261 bool Ask_AltStream; 262 bool Ask_Aux; 263 bool Ask_INode; 264 265 bool IgnoreSplit; // don't try split handler 266 267 // void Set_ErrorFlagsText(); 268 269 CArc(): 270 MTimeDefined(false), 271 IsTree(false), 272 Ask_Deleted(false), 273 Ask_AltStream(false), 274 Ask_Aux(false), 275 Ask_INode(false), 276 IgnoreSplit(false) 277 {} 278 279 HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes); 280 281 // ~CArc(); 282 283 HRESULT Close() 284 { 285 InStream.Release(); 286 return Archive->Close(); 287 } 288 289 // AltStream's name is concatenated with base file name in one string in parts.Back() 290 HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const; 291 292 HRESULT GetItemPath(UInt32 index, UString &result) const; 293 294 // GetItemPath2 adds [DELETED] dir prefix for deleted items. 295 HRESULT GetItemPath2(UInt32 index, UString &result) const; 296 297 HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const; 298 HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const; 299 HRESULT IsItemAnti(UInt32 index, bool &result) const 300 { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); } 301 302 303 HRESULT OpenStream(const COpenOptions &options); 304 HRESULT OpenStreamOrFile(COpenOptions &options); 305 306 HRESULT ReOpen(const COpenOptions &options); 307 308 HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream); 309 }; 310 311 struct CArchiveLink 312 { 313 CObjectVector<CArc> Arcs; 314 UStringVector VolumePaths; 315 UInt64 VolumesSize; 316 bool IsOpen; 317 318 // int NonOpenErrorFormatIndex; // - 1 means no Error. 319 UString NonOpen_ArcPath; 320 321 CArcErrorInfo NonOpen_ErrorInfo; 322 323 // UString ErrorsText; 324 // void Set_ErrorsText(); 325 326 CArchiveLink(): VolumesSize(0), IsOpen(false) {} 327 void KeepModeForNextOpen(); 328 HRESULT Close(); 329 void Release(); 330 ~CArchiveLink() { Release(); } 331 332 const CArc *GetArc() const { return &Arcs.Back(); } 333 IInArchive *GetArchive() const { return Arcs.Back().Archive; } 334 IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; } 335 IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; } 336 337 HRESULT Open(COpenOptions &options); 338 339 HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI); 340 341 HRESULT ReOpen(COpenOptions &options); 342 }; 343 344 bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types); 345 346 #endif 347