diff options
Diffstat (limited to 'CPP/7zip/Archive/Wim/WimIn.h')
-rwxr-xr-x | CPP/7zip/Archive/Wim/WimIn.h | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/CPP/7zip/Archive/Wim/WimIn.h b/CPP/7zip/Archive/Wim/WimIn.h new file mode 100755 index 00000000..bc74f61b --- /dev/null +++ b/CPP/7zip/Archive/Wim/WimIn.h @@ -0,0 +1,139 @@ +// Archive/WimIn.h + +#ifndef __ARCHIVE_WIM_IN_H +#define __ARCHIVE_WIM_IN_H + +#include "Common/MyString.h" +#include "Common/Buffer.h" + +#include "../../Compress/Lzx/LzxDecoder.h" +#include "../../Compress/Copy/CopyCoder.h" + +namespace NArchive { +namespace NWim { + +namespace NResourceFlags +{ + const Byte Compressed = 4; + const Byte kMetadata = 2; +} + +struct CResource +{ + UInt64 PackSize; + UInt64 Offset; + UInt64 UnpackSize; + Byte Flags; + bool IsCompressed() const { return (Flags & NResourceFlags::Compressed) != 0; } + bool IsMetadata() const { return (Flags & NResourceFlags::kMetadata) != 0; } + bool IsEmpty() const { return (UnpackSize == 0); } +}; + +namespace NHeaderFlags +{ + const UInt32 kCompression = 2; + const UInt32 kSpanned = 8; + const UInt32 kRpFix = 0x80; + const UInt32 kXPRESS = 0x20000; + const UInt32 kLZX = 0x40000; +} + +struct CHeader +{ + UInt32 Flags; + UInt32 Version; + // UInt32 ChunkSize; + UInt16 PartNumber; + UInt16 NumParts; + UInt32 NumImages; + Byte Guid[16]; + CResource OffsetResource; + CResource XmlResource; + CResource MetadataResource; + /* + CResource IntegrityResource; + UInt32 BootIndex; + */ + bool IsCompressed() const { return (Flags & NHeaderFlags::kCompression) != 0; } + bool IsSupported() const { return (!IsCompressed() || (Flags & NHeaderFlags::kLZX) != 0); } + bool IsSpanned() const { return (!IsCompressed() || (Flags & NHeaderFlags::kSpanned) != 0); } + + bool IsNewVersion()const { return (Version > 0x010C00); } + + bool AreFromOnArchive(const CHeader &h) + { + return (memcmp(Guid, h.Guid, sizeof(Guid)) == 0) && (h.NumParts == NumParts); + } +}; + +const UInt32 kHashSize = 20; +const UInt32 kStreamInfoSize = 24 + 2 + 4 + kHashSize; + +struct CStreamInfo +{ + CResource Resource; + UInt16 PartNumber; + UInt32 RefCount; + BYTE Hash[kHashSize]; +}; + +struct CItem +{ + UString Name; + UInt32 Attributes; + // UInt32 SecurityId; + BYTE Hash[kHashSize]; + FILETIME CreationTime; + FILETIME LastAccessTime; + FILETIME LastWriteTime; + // UInt32 ReparseTag; + // UInt64 HardLink; + // UInt16 NumStreams; + // UInt16 ShortNameLen; + int StreamIndex; + bool HasMetadata; + CItem(): HasMetadata(true), StreamIndex(-1) {} + bool IsDirectory() const { return HasMetadata && ((Attributes & 0x10) != 0); } + bool HasStream() const + { + for (int i = 0; i < kHashSize; i++) + if (Hash[i] != 0) + return true; + return false; + } +}; + +struct CDatabase +{ + CRecordVector<CStreamInfo> Streams; + CObjectVector<CItem> Items; + void Clear() + { + Streams.Clear(); + Items.Clear(); + } +}; + +HRESULT ReadHeader(IInStream *inStream, CHeader &header); +HRESULT OpenArchive(IInStream *inStream, const CHeader &header, CByteBuffer &xml, CDatabase &database); +HRESULT SortDatabase(CDatabase &database); + +class CUnpacker +{ + NCompress::CCopyCoder *copyCoderSpec; + CMyComPtr<ICompressCoder> copyCoder; + + NCompress::NLzx::CDecoder *lzxDecoderSpec; + CMyComPtr<ICompressCoder> lzxDecoder; + + CByteBuffer sizesBuf; + HRESULT Unpack(IInStream *inStream, const CResource &res, + ISequentialOutStream *outStream, ICompressProgressInfo *progress); +public: + HRESULT Unpack(IInStream *inStream, const CResource &res, + ISequentialOutStream *outStream, ICompressProgressInfo *progress, Byte *digest); +}; + +}} + +#endif |