Files
easy7zip/CPP/7zip/Archive/Wim/WimIn.h
Igor Pavlov 051769bbc5 4.53 beta
2016-05-28 00:15:54 +01:00

157 lines
3.5 KiB
C++
Executable File

// 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;
UInt64 GetUnpackSize() const
{
UInt64 res = 0;
for (int i = 0; i < Streams.Size(); i++)
res += Streams[i].Resource.UnpackSize;
return res;
}
UInt64 GetPackSize() const
{
UInt64 res = 0;
for (int i = 0; i < Streams.Size(); i++)
res += Streams[i].Resource.PackSize;
return res;
}
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