mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-01-31 20:24:05 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
Executable → Regular
+73
-40
@@ -4,11 +4,12 @@
|
||||
|
||||
#include "../../../C/CpuArch.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "../../Common/ComTry.h"
|
||||
#include "../../Common/Defs.h"
|
||||
#include "../../Common/IntToString.h"
|
||||
#include "../../Common/MyString.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../Windows/PropVariant.h"
|
||||
|
||||
#include "../Common/LimitedStreams.h"
|
||||
#include "../Common/ProgressUtils.h"
|
||||
@@ -25,6 +26,9 @@ using namespace NWindows;
|
||||
namespace NArchive {
|
||||
namespace NApm {
|
||||
|
||||
static const Byte kSig0 = 'E';
|
||||
static const Byte kSig1 = 'R';
|
||||
|
||||
struct CItem
|
||||
{
|
||||
UInt32 StartBlock;
|
||||
@@ -45,13 +49,13 @@ struct CItem
|
||||
|
||||
bool Parse(const Byte *p, UInt32 &numBlocksInMap)
|
||||
{
|
||||
if (p[0] != 0x50 || p[1] != 0x4D || p[2] != 0 || p[3] != 0)
|
||||
return false;
|
||||
numBlocksInMap = Get32(p + 4);
|
||||
StartBlock = Get32(p + 8);
|
||||
NumBlocks = Get32(p + 0xC);
|
||||
memcpy(Name, p + 0x10, 32);
|
||||
memcpy(Type, p + 0x30, 32);
|
||||
if (p[0] != 0x50 || p[1] != 0x4D || p[2] != 0 || p[3] != 0)
|
||||
return false;
|
||||
/*
|
||||
DataStartBlock = Get32(p + 0x50);
|
||||
NumDataBlocks = Get32(p + 0x54);
|
||||
@@ -76,42 +80,56 @@ class CHandler:
|
||||
public IInArchiveGetStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<IInStream> _stream;
|
||||
CRecordVector<CItem> _items;
|
||||
|
||||
int _blockSizeLog;
|
||||
CMyComPtr<IInStream> _stream;
|
||||
unsigned _blockSizeLog;
|
||||
UInt32 _numBlocks;
|
||||
UInt64 _phySize;
|
||||
bool _isArc;
|
||||
|
||||
HRESULT ReadTables(IInStream *stream);
|
||||
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
|
||||
UInt64 GetItemSize(const CItem &item) { return BlocksToBytes(item.NumBlocks); }
|
||||
UInt64 GetItemSize(const CItem &item) const { return BlocksToBytes(item.NumBlocks); }
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
|
||||
INTERFACE_IInArchive(;)
|
||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
||||
};
|
||||
|
||||
static inline int GetLog(UInt32 num)
|
||||
static const UInt32 kSectorSize = 512;
|
||||
|
||||
API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size)
|
||||
{
|
||||
for (int i = 0; i < 31; i++)
|
||||
if (((UInt32)1 << i) == num)
|
||||
return i;
|
||||
return -1;
|
||||
if (size < kSectorSize)
|
||||
return k_IsArc_Res_NEED_MORE;
|
||||
if (p[0] != kSig0 || p[1] != kSig1)
|
||||
return k_IsArc_Res_NO;
|
||||
unsigned i;
|
||||
for (i = 8; i < 16; i++)
|
||||
if (p[i] != 0)
|
||||
return k_IsArc_Res_NO;
|
||||
UInt32 blockSize = Get16(p + 2);
|
||||
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
|
||||
if (i >= 12)
|
||||
return k_IsArc_Res_NO;
|
||||
return k_IsArc_Res_YES;
|
||||
}
|
||||
|
||||
HRESULT CHandler::ReadTables(IInStream *stream)
|
||||
{
|
||||
const UInt32 kSectorSize = 512;
|
||||
Byte buf[kSectorSize];
|
||||
{
|
||||
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
|
||||
if (buf[0] != 0x45 || buf[1] != 0x52)
|
||||
return S_FALSE;
|
||||
_blockSizeLog = GetLog(Get16(buf + 2));
|
||||
if (_blockSizeLog < 9 || _blockSizeLog > 14)
|
||||
if (buf[0] != kSig0 || buf[1] != kSig1)
|
||||
return S_FALSE;
|
||||
UInt32 blockSize = Get16(buf + 2);
|
||||
unsigned i;
|
||||
for (i = 9; ((UInt32)1 << i) != blockSize; i++)
|
||||
if (i >= 12)
|
||||
return S_FALSE;
|
||||
_blockSizeLog = i;
|
||||
_numBlocks = Get32(buf + 4);
|
||||
for (int i = 8; i < 16; i++)
|
||||
for (i = 8; i < 16; i++)
|
||||
if (buf[i] != 0)
|
||||
return S_FALSE;
|
||||
}
|
||||
@@ -123,13 +141,14 @@ HRESULT CHandler::ReadTables(IInStream *stream)
|
||||
}
|
||||
|
||||
UInt32 numBlocksInMap = 0;
|
||||
|
||||
for (unsigned i = 0;;)
|
||||
{
|
||||
RINOK(ReadStream_FALSE(stream, buf, kSectorSize));
|
||||
|
||||
CItem item;
|
||||
|
||||
UInt32 numBlocksInMap2;
|
||||
UInt32 numBlocksInMap2 = 0;
|
||||
if (!item.Parse(buf, numBlocksInMap2))
|
||||
return S_FALSE;
|
||||
if (i == 0)
|
||||
@@ -154,12 +173,13 @@ HRESULT CHandler::ReadTables(IInStream *stream)
|
||||
if (++i == numBlocksInMap)
|
||||
break;
|
||||
}
|
||||
|
||||
_phySize = BlocksToBytes(_numBlocks);
|
||||
_isArc = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
Close();
|
||||
@@ -171,22 +191,23 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_isArc = false;
|
||||
_phySize = 0;
|
||||
_items.Clear();
|
||||
_stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
static const Byte kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidOffset, VT_UI8}
|
||||
kpidPath,
|
||||
kpidSize,
|
||||
kpidOffset
|
||||
};
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
static const Byte kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidClusterSize, VT_UI4},
|
||||
{ NULL, kpidPhySize, VT_UI8}
|
||||
kpidClusterSize
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
@@ -195,7 +216,7 @@ IMP_IInArchive_ArcProps
|
||||
static AString GetString(const char *s)
|
||||
{
|
||||
AString res;
|
||||
for (int i = 0; i < 32 && s[i] != 0; i++)
|
||||
for (unsigned i = 0; i < 32 && s[i] != 0; i++)
|
||||
res += s[i];
|
||||
return res;
|
||||
}
|
||||
@@ -204,12 +225,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
switch (propID)
|
||||
{
|
||||
case kpidMainSubfile:
|
||||
{
|
||||
int mainIndex = -1;
|
||||
for (int i = 0; i < _items.Size(); i++)
|
||||
FOR_VECTOR (i, _items)
|
||||
{
|
||||
AString s = GetString(_items[i].Type);
|
||||
if (s != "Apple_Free" &&
|
||||
@@ -228,7 +249,15 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
break;
|
||||
}
|
||||
case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break;
|
||||
case kpidPhySize: prop = BlocksToBytes(_numBlocks); break;
|
||||
case kpidPhySize: prop = _phySize; break;
|
||||
|
||||
case kpidErrorFlags:
|
||||
{
|
||||
UInt32 v = 0;
|
||||
if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
|
||||
prop = v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
@@ -246,7 +275,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
const CItem &item = _items[index];
|
||||
switch(propID)
|
||||
switch (propID)
|
||||
{
|
||||
case kpidPath:
|
||||
{
|
||||
@@ -283,7 +312,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == (UInt32)-1);
|
||||
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if (numItems == 0)
|
||||
@@ -346,10 +375,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
IMP_CreateArcIn
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"APM", L"", 0, 0xD4, { 0x50, 0x4D, 0, 0, 0, 0, 0 }, 7, false, CreateArc, 0 };
|
||||
{ "APM", "apm", 0, 0xD4,
|
||||
2, { kSig0, kSig1 },
|
||||
0,
|
||||
0,
|
||||
CreateArc, NULL, IsArc_Apm };
|
||||
|
||||
REGISTER_ARC(Apm)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user