tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

OpenArchive.h (11446B)


      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 #ifndef _SFX
     13 
     14 #define SUPPORT_ALT_STREAMS
     15 
     16 #endif
     17 
     18 HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw();
     19 HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw();
     20 HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw();
     21 HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw();
     22 HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &deleted) throw();
     23 
     24 #ifdef SUPPORT_ALT_STREAMS
     25 int FindAltStreamColon_in_Path(const wchar_t *path);
     26 #endif
     27 
     28 /*
     29 struct COptionalOpenProperties
     30 {
     31  UString FormatName;
     32  CObjectVector<CProperty> Props;
     33 };
     34 */
     35 
     36 #ifdef _SFX
     37 #define OPEN_PROPS_DECL
     38 #else
     39 #define OPEN_PROPS_DECL const CObjectVector<CProperty> *props;
     40 // #define OPEN_PROPS_DECL , const CObjectVector<COptionalOpenProperties> *props
     41 #endif
     42 
     43 struct COpenSpecFlags
     44 {
     45  // bool CanReturnFull;
     46  bool CanReturnFrontal;
     47  bool CanReturnTail;
     48  bool CanReturnMid;
     49 
     50  bool CanReturn_NonStart() const { return CanReturnTail || CanReturnMid; }
     51 
     52  COpenSpecFlags():
     53    // CanReturnFull(true),
     54    CanReturnFrontal(false),
     55    CanReturnTail(false),
     56    CanReturnMid(false)
     57    {}
     58 };
     59 
     60 struct COpenType
     61 {
     62  int FormatIndex;
     63 
     64  COpenSpecFlags SpecForcedType;
     65  COpenSpecFlags SpecMainType;
     66  COpenSpecFlags SpecWrongExt;
     67  COpenSpecFlags SpecUnknownExt;
     68 
     69  bool Recursive;
     70 
     71  bool CanReturnArc;
     72  bool CanReturnParser;
     73  bool EachPos;
     74 
     75  // bool SkipSfxStub;
     76  // bool ExeAsUnknown;
     77 
     78  bool ZerosTailIsAllowed;
     79 
     80  bool MaxStartOffset_Defined;
     81  UInt64 MaxStartOffset;
     82 
     83  const COpenSpecFlags &GetSpec(bool isForced, bool isMain, bool isUnknown) const
     84  {
     85    return isForced ? SpecForcedType : (isMain ? SpecMainType : (isUnknown ? SpecUnknownExt : SpecWrongExt));
     86  }
     87 
     88  COpenType():
     89      FormatIndex(-1),
     90      Recursive(true),
     91      EachPos(false),
     92      CanReturnArc(true),
     93      CanReturnParser(false),
     94      // SkipSfxStub(true),
     95      // ExeAsUnknown(true),
     96      ZerosTailIsAllowed(false),
     97      MaxStartOffset_Defined(false),
     98      MaxStartOffset(0)
     99  {
    100    SpecForcedType.CanReturnFrontal = true;
    101    SpecForcedType.CanReturnTail = true;
    102    SpecForcedType.CanReturnMid = true;
    103 
    104    SpecMainType.CanReturnFrontal = true;
    105 
    106    SpecUnknownExt.CanReturnTail = true; // for sfx
    107    SpecUnknownExt.CanReturnMid = true;
    108    SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad
    109 
    110    // ZerosTailIsAllowed = true;
    111  }
    112 };
    113 
    114 struct COpenOptions
    115 {
    116  CCodecs *codecs;
    117  COpenType openType;
    118  const CObjectVector<COpenType> *types;
    119  const CIntVector *excludedFormats;
    120 
    121  IInStream *stream;
    122  ISequentialInStream *seqStream;
    123  IArchiveOpenCallback *callback;
    124  COpenCallbackImp *callbackSpec;
    125  OPEN_PROPS_DECL
    126  // bool openOnlySpecifiedByExtension,
    127 
    128  bool stdInMode;
    129  UString filePath;
    130 
    131  COpenOptions():
    132      codecs(NULL),
    133      types(NULL),
    134      excludedFormats(NULL),
    135      stream(NULL),
    136      seqStream(NULL),
    137      callback(NULL),
    138      callbackSpec(NULL),
    139      stdInMode(false)
    140    {}
    141 
    142 };
    143 
    144 UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL);
    145 
    146 struct CArcErrorInfo
    147 {
    148  bool ThereIsTail;
    149  bool UnexpecedEnd;
    150  bool IgnoreTail; // all are zeros
    151  // bool NonZerosTail;
    152  bool ErrorFlags_Defined;
    153  UInt32 ErrorFlags;
    154  UInt32 WarningFlags;
    155  int ErrorFormatIndex; // - 1 means no Error.
    156                        // if FormatIndex == ErrorFormatIndex, the archive is open with offset
    157  UInt64 TailSize;
    158 
    159  /* if CArc is Open OK with some format:
    160        - ErrorFormatIndex shows error format index, if extension is incorrect
    161        - other variables show message and warnings of archive that is open */
    162  
    163  UString ErrorMessage;
    164  UString WarningMessage;
    165 
    166  // call IsArc_After_NonOpen only if Open returns S_FALSE
    167  bool IsArc_After_NonOpen() const
    168  {
    169    return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0);
    170  }
    171 
    172 
    173  CArcErrorInfo():
    174      ThereIsTail(false),
    175      UnexpecedEnd(false),
    176      IgnoreTail(false),
    177      // NonZerosTail(false),
    178      ErrorFlags_Defined(false),
    179      ErrorFlags(0),
    180      WarningFlags(0),
    181      ErrorFormatIndex(-1),
    182      TailSize(0)
    183    {}
    184 
    185  void ClearErrors();
    186 
    187  void ClearErrors_Full()
    188  {
    189    ErrorFormatIndex = -1;
    190    ClearErrors();
    191  }
    192 
    193  bool IsThereErrorOrWarning() const
    194  {
    195    return ErrorFlags != 0
    196        || WarningFlags != 0
    197        || NeedTailWarning()
    198        || UnexpecedEnd
    199        || !ErrorMessage.IsEmpty()
    200        || !WarningMessage.IsEmpty();
    201  }
    202 
    203  bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; }
    204  bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); }
    205 
    206  bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; }
    207 
    208  UInt32 GetWarningFlags() const
    209  {
    210    UInt32 a = WarningFlags;
    211    if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0)
    212      a |= kpv_ErrorFlags_DataAfterEnd;
    213    return a;
    214  }
    215 
    216  UInt32 GetErrorFlags() const
    217  {
    218    UInt32 a = ErrorFlags;
    219    if (UnexpecedEnd)
    220      a |= kpv_ErrorFlags_UnexpectedEnd;
    221    return a;
    222  }
    223 };
    224 
    225 struct CReadArcItem
    226 {
    227  UString Path;            // Path from root (including alt stream name, if alt stream)
    228  UStringVector PathParts; // without altStream name, path from root or from _baseParentFolder, if _use_baseParentFolder_mode
    229 
    230  #ifdef SUPPORT_ALT_STREAMS
    231  UString MainPath;
    232                /* MainPath = Path for non-AltStream,
    233                   MainPath = Path of parent, if there is parent for AltStream. */
    234  UString AltStreamName;
    235  bool IsAltStream;
    236  bool WriteToAltStreamIfColon;
    237  #endif
    238 
    239  bool IsDir;
    240  bool MainIsDir;
    241  UInt32 ParentIndex; // use it, if IsAltStream
    242 
    243  #ifndef _SFX
    244  bool _use_baseParentFolder_mode;
    245  int _baseParentFolder;
    246  #endif
    247 
    248  CReadArcItem()
    249  {
    250    #ifdef SUPPORT_ALT_STREAMS
    251    WriteToAltStreamIfColon = false;
    252    #endif
    253 
    254    #ifndef _SFX
    255    _use_baseParentFolder_mode = false;
    256    _baseParentFolder = -1;
    257    #endif
    258  }
    259 };
    260 
    261 class CArc
    262 {
    263  HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive);
    264  HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset);
    265  HRESULT OpenStream2(const COpenOptions &options);
    266 
    267  #ifndef _SFX
    268  // parts.Back() can contain alt stream name "nams:AltName"
    269  HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const;
    270  #endif
    271 
    272 public:
    273  CMyComPtr<IInArchive> Archive;
    274  CMyComPtr<IInStream> InStream;
    275          // we use InStream in 2 cases (ArcStreamOffset != 0):
    276          // 1) if we use additional cache stream
    277          // 2) we reopen sfx archive with CTailInStream
    278  
    279  CMyComPtr<IArchiveGetRawProps> GetRawProps;
    280  CMyComPtr<IArchiveGetRootProps> GetRootProps;
    281 
    282  CArcErrorInfo ErrorInfo; // for OK archives
    283  CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN)
    284 
    285  UString Path;
    286  UString filePath;
    287  UString DefaultName;
    288  int FormatIndex; // - 1 means Parser.
    289  int SubfileIndex;
    290  FILETIME MTime;
    291  bool MTimeDefined;
    292  
    293  Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler
    294  UInt64 PhySize;
    295  // UInt64 OkPhySize;
    296  bool PhySizeDefined;
    297  // bool OkPhySize_Defined;
    298  UInt64 FileSize;
    299  UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file
    300  // bool offsetDefined;
    301 
    302  UInt64 GetEstmatedPhySize() const { return PhySizeDefined ? PhySize : FileSize; }
    303 
    304  UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler
    305  Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive
    306 
    307  // AString ErrorFlagsText;
    308 
    309  bool IsParseArc;
    310 
    311  bool IsTree;
    312  bool IsReadOnly;
    313  
    314  bool Ask_Deleted;
    315  bool Ask_AltStream;
    316  bool Ask_Aux;
    317  bool Ask_INode;
    318 
    319  bool IgnoreSplit; // don't try split handler
    320 
    321  // void Set_ErrorFlagsText();
    322 
    323  CArc():
    324    MTimeDefined(false),
    325    IsTree(false),
    326    IsReadOnly(false),
    327    Ask_Deleted(false),
    328    Ask_AltStream(false),
    329    Ask_Aux(false),
    330    Ask_INode(false),
    331    IgnoreSplit(false)
    332    {}
    333 
    334  HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes);
    335 
    336  // ~CArc();
    337 
    338  HRESULT Close()
    339  {
    340    InStream.Release();
    341    return Archive->Close();
    342  }
    343 
    344  HRESULT GetItemPath(UInt32 index, UString &result) const;
    345  HRESULT GetDefaultItemPath(UInt32 index, UString &result) const;
    346  
    347  // GetItemPath2 adds [DELETED] dir prefix for deleted items.
    348  HRESULT GetItemPath2(UInt32 index, UString &result) const;
    349 
    350  HRESULT GetItem(UInt32 index, CReadArcItem &item) const;
    351  
    352  HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const;
    353  HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;
    354  HRESULT IsItemAnti(UInt32 index, bool &result) const
    355    { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); }
    356 
    357 
    358  HRESULT OpenStream(const COpenOptions &options);
    359  HRESULT OpenStreamOrFile(COpenOptions &options);
    360 
    361  HRESULT ReOpen(const COpenOptions &options);
    362  
    363  HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream);
    364 };
    365 
    366 struct CArchiveLink
    367 {
    368  CObjectVector<CArc> Arcs;
    369  UStringVector VolumePaths;
    370  UInt64 VolumesSize;
    371  bool IsOpen;
    372 
    373  bool PasswordWasAsked;
    374  // UString Password;
    375 
    376  // int NonOpenErrorFormatIndex; // - 1 means no Error.
    377  UString NonOpen_ArcPath;
    378 
    379  CArcErrorInfo NonOpen_ErrorInfo;
    380 
    381  // UString ErrorsText;
    382  // void Set_ErrorsText();
    383 
    384  CArchiveLink():
    385      VolumesSize(0),
    386      IsOpen(false),
    387      PasswordWasAsked(false)
    388      {}
    389 
    390  void KeepModeForNextOpen();
    391  HRESULT Close();
    392  void Release();
    393  ~CArchiveLink() { Release(); }
    394 
    395  const CArc *GetArc() const { return &Arcs.Back(); }
    396  IInArchive *GetArchive() const { return Arcs.Back().Archive; }
    397  IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; }
    398  IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; }
    399 
    400  HRESULT Open(COpenOptions &options);
    401  HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI);
    402  HRESULT Open3(COpenOptions &options, IOpenCallbackUI *callbackUI);
    403 
    404  HRESULT Open_Strict(COpenOptions &options, IOpenCallbackUI *callbackUI)
    405  {
    406    HRESULT result = Open3(options, callbackUI);
    407    if (result == S_OK && NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
    408      result = S_FALSE;
    409    return result;
    410  }
    411 
    412  HRESULT ReOpen(COpenOptions &options);
    413 };
    414 
    415 bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types);
    416 
    417 
    418 struct CDirPathSortPair
    419 {
    420  unsigned Len;
    421  unsigned Index;
    422 
    423  void SetNumSlashes(const FChar *s);
    424  
    425  int Compare(const CDirPathSortPair &a) const
    426  {
    427    // We need sorting order where parent items will be after child items
    428    if (Len < a.Len) return 1;
    429    if (Len > a.Len) return -1;
    430    if (Index < a.Index) return -1;
    431    if (Index > a.Index) return 1;
    432    return 0;
    433  }
    434 };
    435 
    436 #endif