mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-15 08:11:46 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
@@ -50,13 +50,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
@@ -68,20 +68,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -98,7 +98,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
|
||||
UINT64 numFiles = m_Items.Size();
|
||||
UInt64 numFiles = m_Items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
|
||||
@@ -114,10 +114,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
if (!filled)
|
||||
break;
|
||||
m_Items.Add(itemInfo);
|
||||
archive.SkeepDataRecords(itemInfo.Size, itemInfo.OldHeader);
|
||||
archive.SkeepDataRecords(itemInfo.Size, itemInfo.Align);
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
UINT64 numFiles = m_Items.Size();
|
||||
UInt64 numFiles = m_Items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
}
|
||||
@@ -142,13 +142,13 @@ STDMETHODIMP CHandler::Close()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = m_Items.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
@@ -194,23 +194,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
INT32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == UINT32(-1));
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = m_Items.Size();
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
UINT64 totalSize = 0;
|
||||
for(UINT32 i = 0; i < numItems; i++)
|
||||
UInt64 totalSize = 0;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
totalSize += m_Items[allFilesMode ? i : indices[i]].Size;
|
||||
extractCallback->SetTotal(totalSize);
|
||||
|
||||
UINT64 currentTotalSize = 0;
|
||||
UINT64 currentItemSize;
|
||||
UInt64 currentTotalSize = 0;
|
||||
UInt64 currentItemSize;
|
||||
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
|
||||
@@ -218,10 +219,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
|
||||
{
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
INT32 askMode;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
INT32 index = allFilesMode ? i : indices[i];
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &itemInfo = m_Items[index];
|
||||
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Archive/cpio/Handler.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CPIO_HANDLER_H
|
||||
#define __ARCHIVE_CPIO_HANDLER_H
|
||||
|
||||
@@ -21,22 +19,22 @@ public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Open)(IInStream *stream,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
STDMETHOD(Close)();
|
||||
STDMETHOD(GetNumberOfItems)(UINT32 *numItems);
|
||||
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems,
|
||||
INT32 testMode, IArchiveExtractCallback *extractCallback);
|
||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
|
||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback);
|
||||
|
||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
||||
|
||||
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UINT32 index,
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
|
||||
private:
|
||||
|
||||
@@ -12,10 +12,11 @@ namespace NFileHeader {
|
||||
{
|
||||
extern const char *kMagic1 = "070701";
|
||||
extern const char *kMagic2 = "070702";
|
||||
extern const char *kMagic3 = "070707";
|
||||
extern const char *kEndName = "TRAILER!!!";
|
||||
|
||||
extern unsigned short kMagicForRecord2 = 0x71C7;
|
||||
extern unsigned short kMagicForRecord2BE = 0xC771;
|
||||
const Byte kMagicForRecord2[2] = { 0xC7, 0x71 };
|
||||
// unsigned short kMagicForRecord2BE = 0xC771;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Archive/cpio/Header.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CPIO_HEADER_H
|
||||
#define __ARCHIVE_CPIO_HEADER_H
|
||||
|
||||
@@ -10,20 +8,19 @@
|
||||
namespace NArchive {
|
||||
namespace NCpio {
|
||||
|
||||
#pragma pack( push, PragmacpioHeaders)
|
||||
#pragma pack( push, 1)
|
||||
|
||||
namespace NFileHeader
|
||||
{
|
||||
namespace NMagic
|
||||
{
|
||||
extern const char *kMagic1;
|
||||
extern const char *kMagic2;
|
||||
extern const char *kMagic3;
|
||||
extern const char *kEndName;
|
||||
extern unsigned short kMagicForRecord2;
|
||||
extern unsigned short kMagicForRecord2BE;
|
||||
extern const Byte kMagicForRecord2[2];
|
||||
}
|
||||
|
||||
const UInt32 kRecord2Size = 26;
|
||||
/*
|
||||
struct CRecord2
|
||||
{
|
||||
unsigned short c_magic;
|
||||
@@ -38,31 +35,35 @@ namespace NFileHeader
|
||||
unsigned short c_namesize;
|
||||
unsigned short c_filesizes[2];
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
const UInt32 kRecordSize = 110;
|
||||
/*
|
||||
struct CRecord
|
||||
{
|
||||
char Magic[6]; /* "070701" for "new" portable format, "070702" for CRC format */
|
||||
char Magic[6]; // "070701" for "new" portable format, "070702" for CRC format
|
||||
char inode[8];
|
||||
char Mode[8];
|
||||
char UID[8];
|
||||
char GID[8];
|
||||
char nlink[8];
|
||||
char mtime[8];
|
||||
char Size[8]; /* must be 0 for FIFOs and directories */
|
||||
char Size[8]; // must be 0 for FIFOs and directories
|
||||
char DevMajor[8];
|
||||
char DevMinor[8];
|
||||
char RDevMajor[8]; /*only valid for chr and blk special files*/
|
||||
char RDevMinor[8]; /*only valid for chr and blk special files*/
|
||||
char NameSize[8]; /*count includes terminating NUL in pathname*/
|
||||
char ChkSum[8]; /* 0 for "new" portable format; for CRC format the sum of all the bytes in the file */
|
||||
bool CheckMagic()
|
||||
char RDevMajor[8]; //only valid for chr and blk special files
|
||||
char RDevMinor[8]; //only valid for chr and blk special files
|
||||
char NameSize[8]; // count includes terminating NUL in pathname
|
||||
char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file
|
||||
bool CheckMagic() const
|
||||
{ return memcmp(Magic, NMagic::kMagic1, 6) == 0 ||
|
||||
memcmp(Magic, NMagic::kMagic2, 6) == 0; };
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack(pop, PragmacpioHeaders)
|
||||
const UInt32 kOctRecordSize = 76;
|
||||
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -11,13 +11,42 @@
|
||||
namespace NArchive {
|
||||
namespace NCpio {
|
||||
|
||||
HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
|
||||
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
|
||||
{
|
||||
RINOK(m_Stream->Read(data, size, &processedSize));
|
||||
m_Position += processedSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Byte CInArchive::ReadByte()
|
||||
{
|
||||
if (_blockPos >= _blockSize)
|
||||
throw "Incorrect cpio archive";
|
||||
return _block[_blockPos++];
|
||||
}
|
||||
|
||||
UInt16 CInArchive::ReadUInt16()
|
||||
{
|
||||
UInt16 value = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Byte b = ReadByte();
|
||||
value |= (UInt16(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
UInt32 CInArchive::ReadUInt32()
|
||||
{
|
||||
UInt32 value = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Byte b = ReadByte();
|
||||
value |= (UInt32(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Open(IInStream *inStream)
|
||||
{
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
|
||||
@@ -25,12 +54,12 @@ HRESULT CInArchive::Open(IInStream *inStream)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static bool HexStringToNumber(const char *s, UINT32 &resultValue)
|
||||
bool CInArchive::ReadNumber(UInt32 &resultValue)
|
||||
{
|
||||
resultValue = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
char c = s[i];
|
||||
char c = char(ReadByte());
|
||||
int d;
|
||||
if (c >= '0' && c <= '9')
|
||||
d = c - '0';
|
||||
@@ -46,9 +75,23 @@ static bool HexStringToNumber(const char *s, UINT32 &resultValue)
|
||||
return true;
|
||||
}
|
||||
|
||||
#define GetFromHex(x, y) { if (!HexStringToNumber((x), (y))) return E_FAIL; }
|
||||
bool CInArchive::ReadOctNumber(int size, UInt32 &resultValue)
|
||||
{
|
||||
char s[32];
|
||||
int i;
|
||||
for (i = 0; i < size && i < 32; i++)
|
||||
s[i] = char(ReadByte());
|
||||
s[i] = 0;
|
||||
char *endPtr;
|
||||
resultValue = strtoul(s, &endPtr, 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline unsigned short ConvertValue(
|
||||
#define GetFromHex(y) { if (!ReadNumber(y)) return E_FAIL; }
|
||||
#define GetFromOct6(y) { if (!ReadOctNumber(6, y)) return E_FAIL; }
|
||||
#define GetFromOct11(y) { if (!ReadOctNumber(11, y)) return E_FAIL; }
|
||||
|
||||
static unsigned short ConvertValue(
|
||||
unsigned short value, bool convert)
|
||||
{
|
||||
if (!convert)
|
||||
@@ -56,83 +99,135 @@ static inline unsigned short ConvertValue(
|
||||
return (((unsigned short)(value & 0xFF)) << 8) | (value >> 8);
|
||||
}
|
||||
|
||||
static UInt32 GetAlignedSize(UInt32 size, UInt32 align)
|
||||
{
|
||||
while ((size & (align - 1)) != 0)
|
||||
size++;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
{
|
||||
/*
|
||||
union
|
||||
{
|
||||
NFileHeader::CRecord record;
|
||||
NFileHeader::CRecord2 record2;
|
||||
};
|
||||
*/
|
||||
filled = false;
|
||||
|
||||
UINT32 processedSize;
|
||||
UInt32 processedSize;
|
||||
item.HeaderPosition = m_Position;
|
||||
|
||||
RINOK(ReadBytes(&record2, 2, processedSize));
|
||||
_blockSize = kMaxBlockSize;
|
||||
RINOK(ReadBytes(_block, 2, processedSize));
|
||||
if (processedSize != 2)
|
||||
return S_FALSE;
|
||||
_blockPos = 0;
|
||||
|
||||
UINT32 nameSize;
|
||||
UInt32 nameSize;
|
||||
|
||||
unsigned short signature = *(unsigned short *)&record;
|
||||
bool oldBE = (signature == NFileHeader::NMagic::kMagicForRecord2BE);
|
||||
bool oldBE =
|
||||
_block[0] == NFileHeader::NMagic::kMagicForRecord2[1] &&
|
||||
_block[1] == NFileHeader::NMagic::kMagicForRecord2[0];
|
||||
|
||||
if (signature == NFileHeader::NMagic::kMagicForRecord2 || oldBE)
|
||||
bool binMode = (_block[0] == NFileHeader::NMagic::kMagicForRecord2[0] &&
|
||||
_block[1] == NFileHeader::NMagic::kMagicForRecord2[1]) ||
|
||||
oldBE;
|
||||
|
||||
if (binMode)
|
||||
{
|
||||
RINOK(ReadBytes((BYTE *)(&record2) + 2,
|
||||
sizeof(record2) - 2, processedSize));
|
||||
if (processedSize != sizeof(record2) - 2)
|
||||
RINOK(ReadBytes(_block + 2, NFileHeader::kRecord2Size - 2, processedSize));
|
||||
if (processedSize != NFileHeader::kRecord2Size - 2)
|
||||
return S_FALSE;
|
||||
|
||||
item.inode = ConvertValue(record2.c_ino, oldBE);
|
||||
item.Mode = ConvertValue(record2.c_mode, oldBE);
|
||||
item.UID = ConvertValue(record2.c_uid, oldBE);
|
||||
item.GID = ConvertValue(record2.c_gid, oldBE);
|
||||
item.Size =
|
||||
(UINT32(ConvertValue(record2.c_filesizes[0], oldBE)) << 16)
|
||||
+ ConvertValue(record2.c_filesizes[1], oldBE);
|
||||
item.ModificationTime =
|
||||
(UINT32(ConvertValue(record2.c_mtimes[0], oldBE)) << 16) +
|
||||
ConvertValue(record2.c_mtimes[1], oldBE);
|
||||
item.NumLinks = ConvertValue(record2.c_nlink, oldBE);
|
||||
item.Align = 2;
|
||||
_blockPos = 2;
|
||||
item.DevMajor = 0;
|
||||
item.DevMinor = ConvertValue(record2.c_dev, oldBE);
|
||||
item.DevMinor = ConvertValue(ReadUInt16(), oldBE);
|
||||
item.inode = ConvertValue(ReadUInt16(), oldBE);
|
||||
item.Mode = ConvertValue(ReadUInt16(), oldBE);
|
||||
item.UID = ConvertValue(ReadUInt16(), oldBE);
|
||||
item.GID = ConvertValue(ReadUInt16(), oldBE);
|
||||
item.NumLinks = ConvertValue(ReadUInt16(), oldBE);
|
||||
item.RDevMajor =0;
|
||||
item.RDevMinor = ConvertValue(record2.c_rdev, oldBE);
|
||||
item.RDevMinor = ConvertValue(ReadUInt16(), oldBE);
|
||||
UInt16 timeHigh = ConvertValue(ReadUInt16(), oldBE);
|
||||
UInt16 timeLow = ConvertValue(ReadUInt16(), oldBE);
|
||||
item.ModificationTime = (UInt32(timeHigh) << 16) + timeLow;
|
||||
nameSize = ConvertValue(ReadUInt16(), oldBE);
|
||||
UInt16 sizeHigh = ConvertValue(ReadUInt16(), oldBE);
|
||||
UInt16 sizeLow = ConvertValue(ReadUInt16(), oldBE);
|
||||
item.Size = (UInt32(sizeHigh) << 16) + sizeLow;
|
||||
|
||||
item.ChkSum = 0;
|
||||
nameSize = ConvertValue(record2.c_namesize, oldBE);
|
||||
item.HeaderSize =
|
||||
(((nameSize + sizeof(NFileHeader::CRecord2) - 1) / 2) + 1) * 2; /* 4 byte padding for ("new cpio header" + "filename") */
|
||||
// nameSize + sizeof(NFileHeader::CRecord2);
|
||||
nameSize = item.HeaderSize - sizeof(NFileHeader::CRecord2);
|
||||
item.OldHeader = true;
|
||||
item.HeaderSize = GetAlignedSize(
|
||||
nameSize + NFileHeader::kRecord2Size, item.Align);
|
||||
nameSize = item.HeaderSize - NFileHeader::kRecord2Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(ReadBytes((BYTE *)(&record) + 2, sizeof(record) - 2, processedSize));
|
||||
if (processedSize != sizeof(record) - 2)
|
||||
RINOK(ReadBytes(_block + 2, 4, processedSize));
|
||||
if (processedSize != 4)
|
||||
return S_FALSE;
|
||||
|
||||
if (!record.CheckMagic())
|
||||
return S_FALSE;
|
||||
|
||||
GetFromHex(record.inode, item.inode);
|
||||
GetFromHex(record.Mode, item.Mode);
|
||||
GetFromHex(record.UID, item.UID);
|
||||
GetFromHex(record.GID, item.GID);
|
||||
GetFromHex(record.nlink, item.NumLinks);
|
||||
GetFromHex(record.mtime, *(UINT32 *)&item.ModificationTime);
|
||||
GetFromHex(record.Size, item.Size);
|
||||
GetFromHex(record.DevMajor, item.DevMajor);
|
||||
GetFromHex(record.DevMinor, item.DevMinor);
|
||||
GetFromHex(record.RDevMajor, item.RDevMajor);
|
||||
GetFromHex(record.RDevMinor, item.RDevMinor);
|
||||
GetFromHex(record.ChkSum, item.ChkSum);
|
||||
GetFromHex(record.NameSize, nameSize)
|
||||
item.HeaderSize =
|
||||
(((nameSize + sizeof(NFileHeader::CRecord) - 1) / 4) + 1) * 4; /* 4 byte padding for ("new cpio header" + "filename") */
|
||||
nameSize = item.HeaderSize - sizeof(NFileHeader::CRecord);
|
||||
item.OldHeader = false;
|
||||
|
||||
bool magicOK =
|
||||
memcmp(_block, NFileHeader::NMagic::kMagic1, 6) == 0 ||
|
||||
memcmp(_block, NFileHeader::NMagic::kMagic2, 6) == 0;
|
||||
_blockPos = 6;
|
||||
if (magicOK)
|
||||
{
|
||||
RINOK(ReadBytes(_block + 6, NFileHeader::kRecordSize - 6, processedSize));
|
||||
if (processedSize != NFileHeader::kRecordSize - 6)
|
||||
return S_FALSE;
|
||||
item.Align = 4;
|
||||
|
||||
GetFromHex(item.inode);
|
||||
GetFromHex(item.Mode);
|
||||
GetFromHex(item.UID);
|
||||
GetFromHex(item.GID);
|
||||
GetFromHex(item.NumLinks);
|
||||
UInt32 modificationTime;
|
||||
GetFromHex(modificationTime);
|
||||
item.ModificationTime = modificationTime;
|
||||
GetFromHex(item.Size);
|
||||
GetFromHex(item.DevMajor);
|
||||
GetFromHex(item.DevMinor);
|
||||
GetFromHex(item.RDevMajor);
|
||||
GetFromHex(item.RDevMinor);
|
||||
GetFromHex(nameSize);
|
||||
GetFromHex(item.ChkSum);
|
||||
item.HeaderSize = GetAlignedSize(
|
||||
nameSize + NFileHeader::kRecordSize, item.Align);
|
||||
nameSize = item.HeaderSize - NFileHeader::kRecordSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!memcmp(_block, NFileHeader::NMagic::kMagic3, 6) == 0)
|
||||
return S_FALSE;
|
||||
RINOK(ReadBytes(_block + 6, NFileHeader::kOctRecordSize - 6, processedSize));
|
||||
if (processedSize != NFileHeader::kOctRecordSize - 6)
|
||||
return S_FALSE;
|
||||
item.Align = 1;
|
||||
item.DevMajor = 0;
|
||||
GetFromOct6(item.DevMinor);
|
||||
GetFromOct6(item.inode);
|
||||
GetFromOct6(item.Mode);
|
||||
GetFromOct6(item.UID);
|
||||
GetFromOct6(item.GID);
|
||||
GetFromOct6(item.NumLinks);
|
||||
item.RDevMajor = 0;
|
||||
GetFromOct6(item.RDevMinor);
|
||||
UInt32 modificationTime;
|
||||
GetFromOct11(modificationTime);
|
||||
item.ModificationTime = modificationTime;
|
||||
GetFromOct6(nameSize);
|
||||
GetFromOct11(item.Size); // ?????
|
||||
item.HeaderSize = GetAlignedSize(
|
||||
nameSize + NFileHeader::kOctRecordSize, item.Align);
|
||||
nameSize = item.HeaderSize - NFileHeader::kOctRecordSize;
|
||||
}
|
||||
}
|
||||
if (nameSize == 0 || nameSize >= (1 << 27))
|
||||
return E_FAIL;
|
||||
@@ -141,27 +236,27 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
||||
if (processedSize != nameSize)
|
||||
return E_FAIL;
|
||||
item.Name.ReleaseBuffer();
|
||||
if (item.Name == NFileHeader::NMagic::kEndName)
|
||||
if (strcmp(item.Name, NFileHeader::NMagic::kEndName) == 0)
|
||||
return S_OK;
|
||||
filled = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Skeep(UINT64 aNumBytes)
|
||||
HRESULT CInArchive::Skeep(UInt64 numBytes)
|
||||
{
|
||||
UINT64 aNewPostion;
|
||||
RINOK(m_Stream->Seek(aNumBytes, STREAM_SEEK_CUR, &aNewPostion));
|
||||
m_Position += aNumBytes;
|
||||
if (m_Position != aNewPostion)
|
||||
UInt64 newPostion;
|
||||
RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
|
||||
m_Position += numBytes;
|
||||
if (m_Position != newPostion)
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::SkeepDataRecords(UINT64 aDataSize, bool OldHeader)
|
||||
HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize, UInt32 align)
|
||||
{
|
||||
if (OldHeader)
|
||||
return Skeep((aDataSize + 1) & 0xFFFFFFFFFFFFFFFE);
|
||||
return Skeep((aDataSize + 3) & 0xFFFFFFFFFFFFFFFC);
|
||||
while ((dataSize & (align - 1)) != 0)
|
||||
dataSize++;
|
||||
return Skeep(dataSize);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,29 +1,39 @@
|
||||
// CpioIn.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CPIO_IN_H
|
||||
#define __ARCHIVE_CPIO_IN_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Types.h"
|
||||
#include "../../IStream.h"
|
||||
#include "CpioItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCpio {
|
||||
|
||||
const UInt32 kMaxBlockSize = NFileHeader::kRecordSize;
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
CMyComPtr<IInStream> m_Stream;
|
||||
UInt64 m_Position;
|
||||
|
||||
UInt16 _blockSize;
|
||||
Byte _block[kMaxBlockSize];
|
||||
UInt32 _blockPos;
|
||||
Byte ReadByte();
|
||||
UInt16 ReadUInt16();
|
||||
UInt32 ReadUInt32();
|
||||
|
||||
UINT64 m_Position;
|
||||
|
||||
HRESULT ReadBytes(void *data, UINT32 size, UINT32 &aProcessedSize);
|
||||
bool ReadNumber(UInt32 &resultValue);
|
||||
bool ReadOctNumber(int size, UInt32 &resultValue);
|
||||
|
||||
HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
|
||||
public:
|
||||
HRESULT Open(IInStream *inStream);
|
||||
HRESULT GetNextItem(bool &filled, CItemEx &anItemInfo);
|
||||
HRESULT Skeep(UINT64 aNumBytes);
|
||||
HRESULT SkeepDataRecords(UINT64 aDataSize, bool OldHeader);
|
||||
HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
|
||||
HRESULT Skeep(UInt64 numBytes);
|
||||
HRESULT SkeepDataRecords(UInt64 dataSize, UInt32 align);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Archive/cpio/ItemInfo.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVE_CPIO_ITEMINFO_H
|
||||
#define __ARCHIVE_CPIO_ITEMINFO_H
|
||||
|
||||
@@ -17,35 +15,39 @@ namespace NCpio {
|
||||
struct CItem
|
||||
{
|
||||
AString Name;
|
||||
UINT32 inode;
|
||||
UINT32 Mode;
|
||||
UINT32 UID;
|
||||
UINT32 GID;
|
||||
UINT32 Size;
|
||||
time_t ModificationTime;
|
||||
UInt32 inode;
|
||||
UInt32 Mode;
|
||||
UInt32 UID;
|
||||
UInt32 GID;
|
||||
UInt32 Size;
|
||||
UInt32 ModificationTime;
|
||||
|
||||
// char LinkFlag;
|
||||
// AString LinkName; ?????
|
||||
char Magic[8];
|
||||
UINT32 NumLinks;
|
||||
UINT32 DevMajor;
|
||||
UINT32 DevMinor;
|
||||
UINT32 RDevMajor;
|
||||
UINT32 RDevMinor;
|
||||
UINT32 ChkSum;
|
||||
UInt32 NumLinks;
|
||||
UInt32 DevMajor;
|
||||
UInt32 DevMinor;
|
||||
UInt32 RDevMajor;
|
||||
UInt32 RDevMinor;
|
||||
UInt32 ChkSum;
|
||||
|
||||
bool OldHeader;
|
||||
UInt32 Align;
|
||||
|
||||
bool IsDirectory() const
|
||||
#ifdef _WIN32
|
||||
{ return (Mode & _S_IFMT) == _S_IFDIR; }
|
||||
#else
|
||||
{ return (Mode & S_IFMT) == S_IFDIR; }
|
||||
#endif
|
||||
};
|
||||
|
||||
class CItemEx: public CItem
|
||||
{
|
||||
public:
|
||||
UINT64 HeaderPosition;
|
||||
UINT32 HeaderSize;
|
||||
UINT64 GetDataPosition() const { return HeaderPosition + HeaderSize; };
|
||||
UInt64 HeaderPosition;
|
||||
UInt32 HeaderSize;
|
||||
UInt64 GetDataPosition() const { return HeaderPosition + HeaderSize; };
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "CpioHandler.h"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -126,6 +126,14 @@ SOURCE=.\StdAfx.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -134,6 +142,10 @@ SOURCE=..\..\..\Common\NewHandler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\String.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "cpio.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEVERSION 4,11,0,0
|
||||
PRODUCTVERSION 4,11,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -94,14 +94,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "cpio Plugin for 7-Zip\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "FileVersion", "4, 11, 0, 0\0"
|
||||
VALUE "InternalName", "cpio\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "cpio .dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "ProductVersion", "4, 11, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user