Source code

Revision control

Copy as Markdown

Other Tools

// OpenArchive.h↩
#ifndef __OPEN_ARCHIVE_H↩
#define __OPEN_ARCHIVE_H↩
#include "../../../Windows/PropVariant.h"
#include "ArchiveOpenCallback.h"
#include "LoadCodecs.h"
#include "Property.h"
#ifndef _SFX↩
#define SUPPORT_ALT_STREAMS↩
#endif
HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw();↩
HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw();↩
HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw();↩
HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw();↩
HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &deleted) throw();↩
#ifdef SUPPORT_ALT_STREAMS↩
int FindAltStreamColon_in_Path(const wchar_t *path);↩
#endif
/*↩
struct COptionalOpenProperties↩
{↩
UString FormatName;↩
CObjectVector<CProperty> Props;↩
};↩
*/
#ifdef _SFX↩
#define OPEN_PROPS_DECL↩
#else
#define OPEN_PROPS_DECL const CObjectVector<CProperty> *props;↩
// #define OPEN_PROPS_DECL , const CObjectVector<COptionalOpenProperties> *props↩
#endif
struct COpenSpecFlags↩
{↩
// bool CanReturnFull;↩
bool CanReturnFrontal;↩
bool CanReturnTail;↩
bool CanReturnMid;↩
bool CanReturn_NonStart() const { return CanReturnTail || CanReturnMid; }↩
COpenSpecFlags():↩
// CanReturnFull(true),↩
CanReturnFrontal(false),↩
CanReturnTail(false),↩
CanReturnMid(false)↩
{}↩
};↩
struct COpenType↩
{↩
int FormatIndex;↩
COpenSpecFlags SpecForcedType;↩
COpenSpecFlags SpecMainType;↩
COpenSpecFlags SpecWrongExt;↩
COpenSpecFlags SpecUnknownExt;↩
bool Recursive;↩
bool CanReturnArc;↩
bool CanReturnParser;↩
bool EachPos;↩
// bool SkipSfxStub;↩
// bool ExeAsUnknown;↩
bool ZerosTailIsAllowed;↩
bool MaxStartOffset_Defined;↩
UInt64 MaxStartOffset;↩
const COpenSpecFlags &GetSpec(bool isForced, bool isMain, bool isUnknown) const
{↩
return isForced ? SpecForcedType : (isMain ? SpecMainType : (isUnknown ? SpecUnknownExt : SpecWrongExt));↩
}↩
COpenType():↩
FormatIndex(-1),↩
Recursive(true),↩
EachPos(false),↩
CanReturnArc(true),↩
CanReturnParser(false),↩
// SkipSfxStub(true),↩
// ExeAsUnknown(true),↩
ZerosTailIsAllowed(false),↩
MaxStartOffset_Defined(false),↩
MaxStartOffset(0)↩
{↩
SpecForcedType.CanReturnFrontal = true;↩
SpecForcedType.CanReturnTail = true;↩
SpecForcedType.CanReturnMid = true;↩
SpecMainType.CanReturnFrontal = true;↩
SpecUnknownExt.CanReturnTail = true; // for sfx↩
SpecUnknownExt.CanReturnMid = true;↩
SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad↩
// ZerosTailIsAllowed = true;↩
}↩
};↩
struct COpenOptions↩
{↩
CCodecs *codecs;↩
COpenType openType;↩
const CObjectVector<COpenType> *types;↩
const CIntVector *excludedFormats;↩
IInStream *stream;↩
ISequentialInStream *seqStream;↩
IArchiveOpenCallback *callback;↩
COpenCallbackImp *callbackSpec;↩
OPEN_PROPS_DECL↩
// bool openOnlySpecifiedByExtension,↩
bool stdInMode;↩
UString filePath;↩
COpenOptions():↩
codecs(NULL),↩
types(NULL),↩
excludedFormats(NULL),↩
stream(NULL),↩
seqStream(NULL),↩
callback(NULL),↩
callbackSpec(NULL),↩
stdInMode(false)↩
{}↩
};↩
UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL);↩
struct CArcErrorInfo↩
{↩
bool ThereIsTail;↩
bool UnexpecedEnd;↩
bool IgnoreTail; // all are zeros↩
// bool NonZerosTail;↩
bool ErrorFlags_Defined;↩
UInt32 ErrorFlags;↩
UInt32 WarningFlags;↩
int ErrorFormatIndex; // - 1 means no Error.↩
// if FormatIndex == ErrorFormatIndex, the archive is open with offset↩
UInt64 TailSize;↩
/* if CArc is Open OK with some format:↩
- ErrorFormatIndex shows error format index, if extension is incorrect↩
- other variables show message and warnings of archive that is open */
UString ErrorMessage;↩
UString WarningMessage;↩
// call IsArc_After_NonOpen only if Open returns S_FALSE↩
bool IsArc_After_NonOpen() const
{↩
return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0);↩
}↩
CArcErrorInfo():↩
ThereIsTail(false),↩
UnexpecedEnd(false),↩
IgnoreTail(false),↩
// NonZerosTail(false),↩
ErrorFlags_Defined(false),↩
ErrorFlags(0),↩
WarningFlags(0),↩
ErrorFormatIndex(-1),↩
TailSize(0)↩
{}↩
void ClearErrors();↩
void ClearErrors_Full()↩
{↩
ErrorFormatIndex = -1;↩
ClearErrors();↩
}↩
bool IsThereErrorOrWarning() const
{↩
return ErrorFlags != 0↩
|| WarningFlags != 0↩
|| NeedTailWarning()↩
|| UnexpecedEnd↩
|| !ErrorMessage.IsEmpty()↩
|| !WarningMessage.IsEmpty();↩
}↩
bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; }↩
bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); }↩
bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; }↩
UInt32 GetWarningFlags() const
{↩
UInt32 a = WarningFlags;↩
if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0)↩
a |= kpv_ErrorFlags_DataAfterEnd;↩
return a;↩
}↩
UInt32 GetErrorFlags() const
{↩
UInt32 a = ErrorFlags;↩
if (UnexpecedEnd)↩
a |= kpv_ErrorFlags_UnexpectedEnd;↩
return a;↩
}↩
};↩
struct CReadArcItem↩
{↩
UString Path; // Path from root (including alt stream name, if alt stream)↩
UStringVector PathParts; // without altStream name, path from root or from _baseParentFolder, if _use_baseParentFolder_mode↩
#ifdef SUPPORT_ALT_STREAMS↩
UString MainPath;↩
/* MainPath = Path for non-AltStream,↩
MainPath = Path of parent, if there is parent for AltStream. */
UString AltStreamName;↩
bool IsAltStream;↩
bool WriteToAltStreamIfColon;↩
#endif
bool IsDir;↩
bool MainIsDir;↩
UInt32 ParentIndex; // use it, if IsAltStream↩
#ifndef _SFX↩
bool _use_baseParentFolder_mode;↩
int _baseParentFolder;↩
#endif
CReadArcItem()↩
{↩
#ifdef SUPPORT_ALT_STREAMS↩
WriteToAltStreamIfColon = false;↩
#endif
#ifndef _SFX↩
_use_baseParentFolder_mode = false;↩
_baseParentFolder = -1;↩
#endif
}↩
};↩
class CArc↩
{↩
HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive);↩
HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset);↩
HRESULT OpenStream2(const COpenOptions &options);↩
#ifndef _SFX↩
// parts.Back() can contain alt stream name "nams:AltName"↩
HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const;↩
#endif
public:↩
CMyComPtr<IInArchive> Archive;↩
CMyComPtr<IInStream> InStream;↩
// we use InStream in 2 cases (ArcStreamOffset != 0):↩
// 1) if we use additional cache stream↩
// 2) we reopen sfx archive with CTailInStream↩
CMyComPtr<IArchiveGetRawProps> GetRawProps;↩
CMyComPtr<IArchiveGetRootProps> GetRootProps;↩
CArcErrorInfo ErrorInfo; // for OK archives↩
CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN)↩
UString Path;↩
UString filePath;↩
UString DefaultName;↩
int FormatIndex; // - 1 means Parser.↩
int SubfileIndex;↩
FILETIME MTime;↩
bool MTimeDefined;↩
Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler↩
UInt64 PhySize;↩
// UInt64 OkPhySize;↩
bool PhySizeDefined;↩
// bool OkPhySize_Defined;↩
UInt64 FileSize;↩
UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file↩
// bool offsetDefined;↩
UInt64 GetEstmatedPhySize() const { return PhySizeDefined ? PhySize : FileSize; }↩
UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler↩
Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive↩
// AString ErrorFlagsText;↩
bool IsParseArc;↩
bool IsTree;↩
bool IsReadOnly;↩
bool Ask_Deleted;↩
bool Ask_AltStream;↩
bool Ask_Aux;↩
bool Ask_INode;↩
bool IgnoreSplit; // don't try split handler↩
// void Set_ErrorFlagsText();↩
CArc():↩
MTimeDefined(false),↩
IsTree(false),↩
IsReadOnly(false),↩
Ask_Deleted(false),↩
Ask_AltStream(false),↩
Ask_Aux(false),↩
Ask_INode(false),↩
IgnoreSplit(false)↩
{}↩
HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes);↩
// ~CArc();↩
HRESULT Close()↩
{↩
InStream.Release();↩
return Archive->Close();↩
}↩
HRESULT GetItemPath(UInt32 index, UString &result) const;↩
HRESULT GetDefaultItemPath(UInt32 index, UString &result) const;↩
// GetItemPath2 adds [DELETED] dir prefix for deleted items.↩
HRESULT GetItemPath2(UInt32 index, UString &result) const;↩
HRESULT GetItem(UInt32 index, CReadArcItem &item) const;↩
HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const;↩
HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;↩
HRESULT IsItemAnti(UInt32 index, bool &result) const
{ return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); }↩
HRESULT OpenStream(const COpenOptions &options);↩
HRESULT OpenStreamOrFile(COpenOptions &options);↩
HRESULT ReOpen(const COpenOptions &options);↩
HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream);↩
};↩
struct CArchiveLink↩
{↩
CObjectVector<CArc> Arcs;↩
UStringVector VolumePaths;↩
UInt64 VolumesSize;↩
bool IsOpen;↩
bool PasswordWasAsked;↩
// UString Password;↩
// int NonOpenErrorFormatIndex; // - 1 means no Error.↩
UString NonOpen_ArcPath;↩
CArcErrorInfo NonOpen_ErrorInfo;↩
// UString ErrorsText;↩
// void Set_ErrorsText();↩
CArchiveLink():↩
VolumesSize(0),↩
IsOpen(false),↩
PasswordWasAsked(false)↩
{}↩
void KeepModeForNextOpen();↩
HRESULT Close();↩
void Release();↩
~CArchiveLink() { Release(); }↩
const CArc *GetArc() const { return &Arcs.Back(); }↩
IInArchive *GetArchive() const { return Arcs.Back().Archive; }↩
IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; }↩
IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; }↩
HRESULT Open(COpenOptions &options);↩
HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI);↩
HRESULT Open3(COpenOptions &options, IOpenCallbackUI *callbackUI);↩
HRESULT Open_Strict(COpenOptions &options, IOpenCallbackUI *callbackUI)↩
{↩
HRESULT result = Open3(options, callbackUI);↩
if (result == S_OK && NonOpen_ErrorInfo.ErrorFormatIndex >= 0)↩
result = S_FALSE;↩
return result;↩
}↩
HRESULT ReOpen(COpenOptions &options);↩
};↩
bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types);↩
struct CDirPathSortPair↩
{↩
unsigned Len;↩
unsigned Index;↩
void SetNumSlashes(const FChar *s);↩
int Compare(const CDirPathSortPair &a) const
{↩
// We need sorting order where parent items will be after child items↩
if (Len < a.Len) return 1;↩
if (Len > a.Len) return -1;↩
if (Index < a.Index) return -1;↩
if (Index > a.Index) return 1;↩
return 0;↩
}↩
};↩
#endif