mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 00:07:00 -06:00
Initialer Commit
This commit is contained in:
739
CPP/7zip/Archive/RpmHandler.cpp
Normal file
739
CPP/7zip/Archive/RpmHandler.cpp
Normal file
@@ -0,0 +1,739 @@
|
||||
// RpmHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../C/CpuArch.h"
|
||||
|
||||
#include "../../Common/MyBuffer.h"
|
||||
#include "../../Common/ComTry.h"
|
||||
#include "../../Common/IntToString.h"
|
||||
#include "../../Common/StringConvert.h"
|
||||
#include "../../Common/UTFConvert.h"
|
||||
|
||||
#include "../../Windows/PropVariant.h"
|
||||
#include "../../Windows/TimeUtils.h"
|
||||
|
||||
#include "../Common/RegisterArc.h"
|
||||
#include "../Common/StreamUtils.h"
|
||||
|
||||
#include "HandlerCont.h"
|
||||
|
||||
// #define _SHOW_RPM_METADATA
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
#define Get16(p) GetBe16(p)
|
||||
#define Get32(p) GetBe32(p)
|
||||
|
||||
namespace NArchive {
|
||||
namespace NRpm {
|
||||
|
||||
static const unsigned kNameSize = 66;
|
||||
static const unsigned kLeadSize = kNameSize + 30;
|
||||
static const unsigned k_HeaderSig_Size = 16;
|
||||
static const unsigned k_Entry_Size = 16;
|
||||
|
||||
#define RPMSIG_NONE 0 // Old signature
|
||||
#define RPMSIG_PGP262_1024 1 // Old signature
|
||||
#define RPMSIG_HEADERSIG 5 // New signature
|
||||
|
||||
enum
|
||||
{
|
||||
kRpmType_Bin = 0,
|
||||
kRpmType_Src = 1
|
||||
};
|
||||
|
||||
// There are two sets of TAGs: signature tags and header tags
|
||||
|
||||
// ----- Signature TAGs -----
|
||||
|
||||
#define RPMSIGTAG_SIZE 1000 // Header + Payload size (32bit)
|
||||
|
||||
// ----- Header TAGs -----
|
||||
|
||||
#define RPMTAG_NAME 1000
|
||||
#define RPMTAG_VERSION 1001
|
||||
#define RPMTAG_RELEASE 1002
|
||||
#define RPMTAG_BUILDTIME 1006
|
||||
#define RPMTAG_OS 1021 // string (old version used int?)
|
||||
#define RPMTAG_ARCH 1022 // string (old version used int?)
|
||||
#define RPMTAG_PAYLOADFORMAT 1124
|
||||
#define RPMTAG_PAYLOADCOMPRESSOR 1125
|
||||
// #define RPMTAG_PAYLOADFLAGS 1126
|
||||
|
||||
enum
|
||||
{
|
||||
k_EntryType_NULL,
|
||||
k_EntryType_CHAR,
|
||||
k_EntryType_INT8,
|
||||
k_EntryType_INT16,
|
||||
k_EntryType_INT32,
|
||||
k_EntryType_INT64,
|
||||
k_EntryType_STRING,
|
||||
k_EntryType_BIN,
|
||||
k_EntryType_STRING_ARRAY,
|
||||
k_EntryType_I18NSTRING
|
||||
};
|
||||
|
||||
static const char * const k_CPUs[] =
|
||||
{
|
||||
"noarch"
|
||||
, "i386"
|
||||
, "alpha"
|
||||
, "sparc"
|
||||
, "mips"
|
||||
, "ppc"
|
||||
, "m68k"
|
||||
, "sgi"
|
||||
, "rs6000"
|
||||
, "ia64"
|
||||
, "sparc64" // 10 ???
|
||||
, "mipsel"
|
||||
, "arm"
|
||||
, "m68kmint"
|
||||
, "s390"
|
||||
, "s390x"
|
||||
, "ppc64"
|
||||
, "sh"
|
||||
, "xtensa"
|
||||
, "aarch64" // 19
|
||||
};
|
||||
|
||||
static const char * const k_OS[] =
|
||||
{
|
||||
"0"
|
||||
, "Linux"
|
||||
, "Irix"
|
||||
, "solaris"
|
||||
, "SunOS"
|
||||
, "AmigaOS" // AIX
|
||||
, "HP-UX"
|
||||
, "osf"
|
||||
, "FreeBSD"
|
||||
, "SCO_SV"
|
||||
, "Irix64"
|
||||
, "NextStep"
|
||||
, "bsdi"
|
||||
, "machten"
|
||||
, "cygwin32-NT"
|
||||
, "cygwin32-95"
|
||||
, "MP_RAS"
|
||||
, "MiNT"
|
||||
, "OS/390"
|
||||
, "VM/ESA"
|
||||
, "Linux/390" // "Linux/ESA"
|
||||
, "Darwin" // "MacOSX" 21
|
||||
};
|
||||
|
||||
struct CLead
|
||||
{
|
||||
unsigned char Major;
|
||||
unsigned char Minor;
|
||||
UInt16 Type;
|
||||
UInt16 Cpu;
|
||||
UInt16 Os;
|
||||
UInt16 SignatureType;
|
||||
char Name[kNameSize];
|
||||
// char Reserved[16];
|
||||
|
||||
void Parse(const Byte *p)
|
||||
{
|
||||
Major = p[4];
|
||||
Minor = p[5];
|
||||
Type = Get16(p + 6);
|
||||
Cpu= Get16(p + 8);
|
||||
memcpy(Name, p + 10, kNameSize);
|
||||
p += 10 + kNameSize;
|
||||
Os = Get16(p);
|
||||
SignatureType = Get16(p + 2);
|
||||
}
|
||||
|
||||
bool IsSupported() const { return Major >= 3 && Type <= 1; }
|
||||
};
|
||||
|
||||
struct CEntry
|
||||
{
|
||||
UInt32 Tag;
|
||||
UInt32 Type;
|
||||
UInt32 Offset;
|
||||
UInt32 Count;
|
||||
|
||||
void Parse(const Byte *p)
|
||||
{
|
||||
Tag = Get32(p + 0);
|
||||
Type = Get32(p + 4);
|
||||
Offset = Get32(p + 8);
|
||||
Count = Get32(p + 12);
|
||||
}
|
||||
};
|
||||
|
||||
class CHandler: public CHandlerCont
|
||||
{
|
||||
UInt64 _headersSize; // is equal to start offset of payload data
|
||||
UInt64 _payloadSize;
|
||||
UInt64 _size;
|
||||
// _size = _payloadSize, if (_payloadSize_Defined)
|
||||
// _size = (fileSize - _headersSize), if (!_payloadSize_Defined)
|
||||
UInt64 _phySize; // _headersSize + _payloadSize, if (_phySize_Defined)
|
||||
UInt32 _headerPlusPayload_Size;
|
||||
UInt32 _buildTime;
|
||||
|
||||
bool _payloadSize_Defined;
|
||||
bool _phySize_Defined;
|
||||
bool _headerPlusPayload_Size_Defined;
|
||||
bool _time_Defined;
|
||||
|
||||
Byte _payloadSig[6]; // start data of payload
|
||||
|
||||
AString _name; // p7zip
|
||||
AString _version; // 9.20.1
|
||||
AString _release; // 8.1.1
|
||||
AString _arch; // x86_64
|
||||
AString _os; // linux
|
||||
|
||||
AString _format; // cpio
|
||||
AString _compressor; // xz, gzip, bzip2
|
||||
|
||||
CLead _lead;
|
||||
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
AString _metadata;
|
||||
#endif
|
||||
|
||||
void SetTime(NCOM::CPropVariant &prop) const
|
||||
{
|
||||
if (_time_Defined && _buildTime != 0)
|
||||
{
|
||||
FILETIME ft;
|
||||
if (NTime::UnixTime64ToFileTime(_buildTime, ft))
|
||||
prop = ft;
|
||||
}
|
||||
}
|
||||
|
||||
void SetStringProp(const AString &s, NCOM::CPropVariant &prop) const
|
||||
{
|
||||
UString us;
|
||||
if (!ConvertUTF8ToUnicode(s, us))
|
||||
us = GetUnicodeString(s);
|
||||
if (!us.IsEmpty())
|
||||
prop = us;
|
||||
}
|
||||
|
||||
void AddCPU(AString &s) const;
|
||||
AString GetBaseName() const;
|
||||
void AddSubFileExtension(AString &res) const;
|
||||
|
||||
HRESULT ReadHeader(ISequentialInStream *stream, bool isMainHeader);
|
||||
HRESULT Open2(ISequentialInStream *stream);
|
||||
|
||||
virtual int GetItem_ExtractInfo(UInt32 /* index */, UInt64 &pos, UInt64 &size) const
|
||||
{
|
||||
pos = _headersSize;
|
||||
size = _size;
|
||||
return NExtract::NOperationResult::kOK;
|
||||
}
|
||||
|
||||
public:
|
||||
INTERFACE_IInArchive_Cont(;)
|
||||
};
|
||||
|
||||
static const Byte kArcProps[] =
|
||||
{
|
||||
kpidHeadersSize,
|
||||
kpidCpu,
|
||||
kpidHostOS,
|
||||
kpidCTime
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
, kpidComment
|
||||
#endif
|
||||
};
|
||||
|
||||
static const Byte kProps[] =
|
||||
{
|
||||
kpidPath,
|
||||
kpidSize,
|
||||
kpidCTime
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
void CHandler::AddCPU(AString &s) const
|
||||
{
|
||||
if (!_arch.IsEmpty())
|
||||
s += _arch;
|
||||
else
|
||||
{
|
||||
if (_lead.Type == kRpmType_Bin)
|
||||
{
|
||||
char temp[16];
|
||||
const char *p;
|
||||
if (_lead.Cpu < ARRAY_SIZE(k_CPUs))
|
||||
p = k_CPUs[_lead.Cpu];
|
||||
else
|
||||
{
|
||||
ConvertUInt32ToString(_lead.Cpu, temp);
|
||||
p = temp;
|
||||
}
|
||||
s += p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AString CHandler::GetBaseName() const
|
||||
{
|
||||
AString s;
|
||||
if (!_name.IsEmpty())
|
||||
{
|
||||
s = _name;
|
||||
if (!_version.IsEmpty())
|
||||
{
|
||||
s += '-';
|
||||
s += _version;
|
||||
}
|
||||
if (!_release.IsEmpty())
|
||||
{
|
||||
s += '-';
|
||||
s += _release;
|
||||
}
|
||||
}
|
||||
else
|
||||
s.SetFrom_CalcLen(_lead.Name, kNameSize);
|
||||
|
||||
s += '.';
|
||||
if (_lead.Type == kRpmType_Src)
|
||||
s += "src";
|
||||
else
|
||||
AddCPU(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
void CHandler::AddSubFileExtension(AString &res) const
|
||||
{
|
||||
if (!_format.IsEmpty())
|
||||
res += _format;
|
||||
else
|
||||
res += "cpio";
|
||||
res += '.';
|
||||
|
||||
const char *s;
|
||||
|
||||
if (!_compressor.IsEmpty())
|
||||
{
|
||||
s = _compressor;
|
||||
if (_compressor == "bzip2")
|
||||
s = "bz2";
|
||||
else if (_compressor == "gzip")
|
||||
s = "gz";
|
||||
}
|
||||
else
|
||||
{
|
||||
const Byte *p = _payloadSig;
|
||||
if (p[0] == 0x1F && p[1] == 0x8B)
|
||||
s = "gz";
|
||||
else if (p[0] == 0xFD && p[1] == '7' && p[2] == 'z' && p[3] == 'X' && p[4] == 'Z' && p[5] == 0)
|
||||
s = "xz";
|
||||
else if (p[0] == 'B' && p[1] == 'Z' && p[2] == 'h' && p[3] >= '1' && p[3] <= '9')
|
||||
s = "bz2";
|
||||
else
|
||||
s = "lzma";
|
||||
}
|
||||
|
||||
res += s;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
switch (propID)
|
||||
{
|
||||
case kpidMainSubfile: prop = (UInt32)0; break;
|
||||
|
||||
case kpidHeadersSize: prop = _headersSize; break;
|
||||
case kpidPhySize: if (_phySize_Defined) prop = _phySize; break;
|
||||
|
||||
case kpidMTime:
|
||||
case kpidCTime:
|
||||
SetTime(prop);
|
||||
break;
|
||||
|
||||
case kpidCpu:
|
||||
{
|
||||
AString s;
|
||||
AddCPU(s);
|
||||
/*
|
||||
if (_lead.Type == kRpmType_Src)
|
||||
s = "src";
|
||||
*/
|
||||
SetStringProp(s, prop);
|
||||
break;
|
||||
}
|
||||
|
||||
case kpidHostOS:
|
||||
{
|
||||
if (!_os.IsEmpty())
|
||||
SetStringProp(_os, prop);
|
||||
else
|
||||
{
|
||||
char temp[16];
|
||||
const char *p;
|
||||
if (_lead.Os < ARRAY_SIZE(k_OS))
|
||||
p = k_OS[_lead.Os];
|
||||
else
|
||||
{
|
||||
ConvertUInt32ToString(_lead.Os, temp);
|
||||
p = temp;
|
||||
}
|
||||
prop = p;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
case kpidComment: SetStringProp(_metadata, prop); break;
|
||||
#endif
|
||||
|
||||
case kpidName:
|
||||
{
|
||||
AString s = GetBaseName();
|
||||
s += ".rpm";
|
||||
SetStringProp(s, prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch (propID)
|
||||
{
|
||||
case kpidSize:
|
||||
case kpidPackSize:
|
||||
prop = _size;
|
||||
break;
|
||||
|
||||
case kpidMTime:
|
||||
case kpidCTime:
|
||||
SetTime(prop);
|
||||
break;
|
||||
|
||||
case kpidPath:
|
||||
{
|
||||
AString s = GetBaseName();
|
||||
s += '.';
|
||||
AddSubFileExtension(s);
|
||||
SetStringProp(s, prop);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
case kpidExtension:
|
||||
{
|
||||
prop = GetSubFileExtension();
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
static inline char GetHex(unsigned value)
|
||||
{
|
||||
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader)
|
||||
{
|
||||
UInt32 numEntries;
|
||||
UInt32 dataLen;
|
||||
{
|
||||
char buf[k_HeaderSig_Size];
|
||||
RINOK(ReadStream_FALSE(stream, buf, k_HeaderSig_Size));
|
||||
if (Get32(buf) != 0x8EADE801) // buf[3] = 0x01 - is version
|
||||
return S_FALSE;
|
||||
// reserved = Get32(buf + 4);
|
||||
numEntries = Get32(buf + 8);
|
||||
dataLen = Get32(buf + 12);
|
||||
if (numEntries >= 1 << 24)
|
||||
return S_FALSE;
|
||||
}
|
||||
size_t indexSize = (size_t)numEntries * k_Entry_Size;
|
||||
size_t headerSize = indexSize + dataLen;
|
||||
if (headerSize < dataLen)
|
||||
return S_FALSE;
|
||||
CByteBuffer buffer(headerSize);
|
||||
RINOK(ReadStream_FALSE(stream, buffer, headerSize));
|
||||
|
||||
for (UInt32 i = 0; i < numEntries; i++)
|
||||
{
|
||||
CEntry entry;
|
||||
|
||||
entry.Parse(buffer + (size_t)i * k_Entry_Size);
|
||||
if (entry.Offset > dataLen)
|
||||
return S_FALSE;
|
||||
|
||||
const Byte *p = buffer + indexSize + entry.Offset;
|
||||
size_t rem = dataLen - entry.Offset;
|
||||
|
||||
if (!isMainHeader)
|
||||
{
|
||||
if (entry.Tag == RPMSIGTAG_SIZE &&
|
||||
entry.Type == k_EntryType_INT32)
|
||||
{
|
||||
if (rem < 4 || entry.Count != 1)
|
||||
return S_FALSE;
|
||||
_headerPlusPayload_Size = Get32(p);
|
||||
_headerPlusPayload_Size_Defined = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
{
|
||||
char temp[16];
|
||||
ConvertUInt32ToString(entry.Tag, temp);
|
||||
|
||||
_metadata += temp;
|
||||
_metadata += ": ";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (entry.Type == k_EntryType_STRING)
|
||||
{
|
||||
if (entry.Count != 1)
|
||||
return S_FALSE;
|
||||
size_t j;
|
||||
for (j = 0; j < rem && p[j] != 0; j++);
|
||||
if (j == rem)
|
||||
return S_FALSE;
|
||||
AString s = (const char *)p;
|
||||
switch (entry.Tag)
|
||||
{
|
||||
case RPMTAG_NAME: _name = s; break;
|
||||
case RPMTAG_VERSION: _version = s; break;
|
||||
case RPMTAG_RELEASE: _release = s; break;
|
||||
case RPMTAG_ARCH: _arch = s; break;
|
||||
case RPMTAG_OS: _os = s; break;
|
||||
case RPMTAG_PAYLOADFORMAT: _format = s; break;
|
||||
case RPMTAG_PAYLOADCOMPRESSOR: _compressor = s; break;
|
||||
}
|
||||
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
_metadata += s;
|
||||
#endif
|
||||
}
|
||||
else if (entry.Type == k_EntryType_INT32)
|
||||
{
|
||||
if (rem / 4 < entry.Count)
|
||||
return S_FALSE;
|
||||
if (entry.Tag == RPMTAG_BUILDTIME)
|
||||
{
|
||||
if (entry.Count != 1)
|
||||
return S_FALSE;
|
||||
_buildTime = Get32(p);
|
||||
_time_Defined = true;
|
||||
}
|
||||
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
for (UInt32 t = 0; t < entry.Count; t++)
|
||||
{
|
||||
if (t != 0)
|
||||
_metadata.Add_Space();
|
||||
char temp[16];
|
||||
ConvertUInt32ToString(Get32(p + t * 4), temp);
|
||||
_metadata += temp;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
|
||||
else if (
|
||||
entry.Type == k_EntryType_STRING_ARRAY ||
|
||||
entry.Type == k_EntryType_I18NSTRING)
|
||||
{
|
||||
const Byte *p2 = p;
|
||||
size_t rem2 = rem;
|
||||
for (UInt32 t = 0; t < entry.Count; t++)
|
||||
{
|
||||
if (rem2 == 0)
|
||||
return S_FALSE;
|
||||
if (t != 0)
|
||||
_metadata += '\n';
|
||||
size_t j;
|
||||
for (j = 0; j < rem2 && p2[j] != 0; j++);
|
||||
if (j == rem2)
|
||||
return S_FALSE;
|
||||
_metadata += (const char *)p2;
|
||||
j++;
|
||||
p2 += j;
|
||||
rem2 -= j;
|
||||
}
|
||||
}
|
||||
else if (entry.Type == k_EntryType_INT16)
|
||||
{
|
||||
if (rem / 2 < entry.Count)
|
||||
return S_FALSE;
|
||||
for (UInt32 t = 0; t < entry.Count; t++)
|
||||
{
|
||||
if (t != 0)
|
||||
_metadata.Add_Space();
|
||||
char temp[16];
|
||||
ConvertUInt32ToString(Get16(p + t * 2), temp);
|
||||
_metadata += temp;
|
||||
}
|
||||
}
|
||||
else if (entry.Type == k_EntryType_BIN)
|
||||
{
|
||||
if (rem < entry.Count)
|
||||
return S_FALSE;
|
||||
for (UInt32 t = 0; t < entry.Count; t++)
|
||||
{
|
||||
const unsigned b = p[t];
|
||||
_metadata += GetHex((b >> 4) & 0xF);
|
||||
_metadata += GetHex(b & 0xF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// p = p;
|
||||
}
|
||||
_metadata += '\n';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
headerSize += k_HeaderSig_Size;
|
||||
_headersSize += headerSize;
|
||||
if (isMainHeader && _headerPlusPayload_Size_Defined)
|
||||
{
|
||||
if (_headerPlusPayload_Size < headerSize)
|
||||
return S_FALSE;
|
||||
_payloadSize = _headerPlusPayload_Size - headerSize;
|
||||
_size = _payloadSize;
|
||||
_phySize = _headersSize + _payloadSize;
|
||||
_payloadSize_Defined = true;
|
||||
_phySize_Defined = true;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CHandler::Open2(ISequentialInStream *stream)
|
||||
{
|
||||
{
|
||||
Byte buf[kLeadSize];
|
||||
RINOK(ReadStream_FALSE(stream, buf, kLeadSize));
|
||||
if (Get32(buf) != 0xEDABEEDB)
|
||||
return S_FALSE;
|
||||
_lead.Parse(buf);
|
||||
if (!_lead.IsSupported())
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
_headersSize = kLeadSize;
|
||||
|
||||
if (_lead.SignatureType == RPMSIG_NONE)
|
||||
{
|
||||
;
|
||||
}
|
||||
else if (_lead.SignatureType == RPMSIG_PGP262_1024)
|
||||
{
|
||||
Byte temp[256];
|
||||
RINOK(ReadStream_FALSE(stream, temp, sizeof(temp)));
|
||||
}
|
||||
else if (_lead.SignatureType == RPMSIG_HEADERSIG)
|
||||
{
|
||||
RINOK(ReadHeader(stream, false));
|
||||
unsigned pos = (unsigned)_headersSize & 7;
|
||||
if (pos != 0)
|
||||
{
|
||||
Byte temp[8];
|
||||
unsigned num = 8 - pos;
|
||||
RINOK(ReadStream_FALSE(stream, temp, num));
|
||||
_headersSize += num;
|
||||
}
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
|
||||
return ReadHeader(stream, true);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
{
|
||||
Close();
|
||||
RINOK(Open2(inStream));
|
||||
|
||||
// start of payload is allowed to be unaligned
|
||||
RINOK(ReadStream_FALSE(inStream, _payloadSig, sizeof(_payloadSig)));
|
||||
|
||||
if (!_payloadSize_Defined)
|
||||
{
|
||||
UInt64 endPos;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
|
||||
_size = endPos - _headersSize;
|
||||
}
|
||||
_stream = inStream;
|
||||
return S_OK;
|
||||
}
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_headersSize = 0;
|
||||
_payloadSize = 0;
|
||||
_size = 0;
|
||||
_phySize = 0;
|
||||
_headerPlusPayload_Size = 0;
|
||||
|
||||
_payloadSize_Defined = false;
|
||||
_phySize_Defined = false;
|
||||
_headerPlusPayload_Size_Defined = false;
|
||||
_time_Defined = false;
|
||||
|
||||
_name.Empty();
|
||||
_version.Empty();
|
||||
_release.Empty();
|
||||
_arch.Empty();
|
||||
_os.Empty();
|
||||
|
||||
_format.Empty();
|
||||
_compressor.Empty();
|
||||
|
||||
#ifdef _SHOW_RPM_METADATA
|
||||
_metadata.Empty();
|
||||
#endif
|
||||
|
||||
_stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const Byte k_Signature[] = { 0xED, 0xAB, 0xEE, 0xDB};
|
||||
|
||||
REGISTER_ARC_I(
|
||||
"Rpm", "rpm", 0, 0xEB,
|
||||
k_Signature,
|
||||
0,
|
||||
0,
|
||||
NULL)
|
||||
|
||||
}}
|
||||
Reference in New Issue
Block a user