mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-01-31 22:24:08 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
Executable → Regular
+120
-80
@@ -4,9 +4,11 @@
|
||||
|
||||
#include "../../../C/CpuArch.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "../../Common/ComTry.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"
|
||||
@@ -15,32 +17,50 @@
|
||||
|
||||
#include "../Compress/CopyCoder.h"
|
||||
|
||||
static UInt32 Get32(const Byte *p, int be) { if (be) return GetBe32(p); return GetUi32(p); }
|
||||
static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); }
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NMub {
|
||||
|
||||
#define MACH_CPU_ARCH_ABI64 (1 << 24)
|
||||
#define MACH_CPU_TYPE_386 7
|
||||
#define MACH_CPU_TYPE_ARM 12
|
||||
#define MACH_CPU_TYPE_SPARC 14
|
||||
#define MACH_CPU_TYPE_PPC 18
|
||||
|
||||
#define MACH_CPU_TYPE_PPC64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_PPC)
|
||||
#define MACH_CPU_TYPE_AMD64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_386)
|
||||
|
||||
#define MACH_CPU_SUBTYPE_LIB64 (1 << 31)
|
||||
|
||||
#define MACH_CPU_SUBTYPE_I386_ALL 3
|
||||
|
||||
struct CItem
|
||||
{
|
||||
UInt32 Type;
|
||||
UInt32 SubType;
|
||||
UInt64 Offset;
|
||||
UInt64 Size;
|
||||
UInt32 Align;
|
||||
bool IsTail;
|
||||
UInt32 Offset;
|
||||
UInt32 Size;
|
||||
// UInt32 Align;
|
||||
};
|
||||
|
||||
const UInt32 kNumFilesMax = 10;
|
||||
static const UInt32 kNumFilesMax = 10;
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public IInArchiveGetStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt64 _startPos;
|
||||
CMyComPtr<IInStream> _stream;
|
||||
// UInt64 _startPos;
|
||||
UInt64 _phySize;
|
||||
UInt32 _numItems;
|
||||
CItem _items[kNumFilesMax + 1];
|
||||
bool _bigEndian;
|
||||
CItem _items[kNumFilesMax];
|
||||
|
||||
HRESULT Open2(IInStream *stream);
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
|
||||
@@ -48,65 +68,79 @@ public:
|
||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
||||
};
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
static const Byte kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidSize, VT_UI8}
|
||||
kpidBigEndian
|
||||
};
|
||||
|
||||
static const Byte kProps[] =
|
||||
{
|
||||
kpidSize
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
#define MACH_ARCH_ABI64 0x1000000
|
||||
#define MACH_MACHINE_386 7
|
||||
#define MACH_MACHINE_ARM 12
|
||||
#define MACH_MACHINE_SPARC 14
|
||||
#define MACH_MACHINE_PPC 18
|
||||
|
||||
#define MACH_MACHINE_PPC64 (MACH_MACHINE_PPC | MACH_ARCH_ABI64)
|
||||
#define MACH_MACHINE_AMD64 (MACH_MACHINE_386 | MACH_ARCH_ABI64)
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItem &item = _items[index];
|
||||
switch(propID)
|
||||
PropVariant_Clear(value);
|
||||
switch (propID)
|
||||
{
|
||||
case kpidExtension:
|
||||
{
|
||||
const wchar_t *ext;
|
||||
if (item.IsTail)
|
||||
ext = L"tail";
|
||||
else
|
||||
{
|
||||
switch(item.Type)
|
||||
{
|
||||
case MACH_MACHINE_386: ext = L"86"; break;
|
||||
case MACH_MACHINE_ARM: ext = L"arm"; break;
|
||||
case MACH_MACHINE_SPARC: ext = L"sparc"; break;
|
||||
case MACH_MACHINE_PPC: ext = L"ppc"; break;
|
||||
case MACH_MACHINE_PPC64: ext = L"ppc64"; break;
|
||||
case MACH_MACHINE_AMD64: ext = L"x64"; break;
|
||||
default: ext = L"unknown"; break;
|
||||
}
|
||||
}
|
||||
prop = ext;
|
||||
break;
|
||||
}
|
||||
case kpidSize:
|
||||
case kpidPackSize:
|
||||
prop = (UInt64)item.Size;
|
||||
break;
|
||||
case kpidBigEndian: PropVarEm_Set_Bool(value, _bigEndian); break;
|
||||
case kpidPhySize: PropVarEm_Set_UInt64(value, _phySize); break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#define MACH_TYPE_ABI64 (1 << 24)
|
||||
#define MACH_SUBTYPE_ABI64 (1 << 31)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
PropVariant_Clear(value);
|
||||
const CItem &item = _items[index];
|
||||
switch (propID)
|
||||
{
|
||||
case kpidExtension:
|
||||
{
|
||||
char temp[32];
|
||||
const char *ext = 0;
|
||||
switch (item.Type)
|
||||
{
|
||||
case MACH_CPU_TYPE_386: ext = "x86"; break;
|
||||
case MACH_CPU_TYPE_ARM: ext = "arm"; break;
|
||||
case MACH_CPU_TYPE_SPARC: ext = "sparc"; break;
|
||||
case MACH_CPU_TYPE_PPC: ext = "ppc"; break;
|
||||
case MACH_CPU_TYPE_PPC64: ext = "ppc64"; break;
|
||||
case MACH_CPU_TYPE_AMD64: ext = "x64"; break;
|
||||
default:
|
||||
temp[0] = 'c';
|
||||
temp[1] = 'p';
|
||||
temp[2] = 'u';
|
||||
ConvertUInt32ToString(item.Type, temp + 3);
|
||||
break;
|
||||
}
|
||||
if (ext)
|
||||
strcpy(temp, ext);
|
||||
if (item.SubType != 0 && (
|
||||
item.Type != MACH_CPU_TYPE_386 &&
|
||||
item.Type != MACH_CPU_TYPE_AMD64 ||
|
||||
(item.SubType & ~(UInt32)MACH_CPU_SUBTYPE_LIB64) != MACH_CPU_SUBTYPE_I386_ALL))
|
||||
{
|
||||
unsigned pos = MyStringLen(temp);
|
||||
temp[pos++] = '-';
|
||||
ConvertUInt32ToString(item.SubType, temp + pos);
|
||||
}
|
||||
return PropVarEm_Set_Str(value, temp);
|
||||
}
|
||||
case kpidSize:
|
||||
case kpidPackSize:
|
||||
PropVarEm_Set_UInt64(value, item.Size);
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CHandler::Open2(IInStream *stream)
|
||||
{
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_SET, &_startPos));
|
||||
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos));
|
||||
|
||||
const UInt32 kHeaderSize = 8;
|
||||
const UInt32 kRecordSize = 5 * 4;
|
||||
@@ -124,44 +158,37 @@ HRESULT CHandler::Open2(IInStream *stream)
|
||||
case 0xB9FAF10E: be = false; break;
|
||||
default: return S_FALSE;
|
||||
}
|
||||
_bigEndian = be;
|
||||
UInt32 num = Get32(buf + 4, be);
|
||||
if (num > kNumFilesMax || processed < kHeaderSize + num * kRecordSize)
|
||||
return S_FALSE;
|
||||
if (num == 0)
|
||||
return S_FALSE;
|
||||
UInt64 endPosMax = kHeaderSize;
|
||||
|
||||
for (UInt32 i = 0; i < num; i++)
|
||||
{
|
||||
const Byte *p = buf + kHeaderSize + i * kRecordSize;
|
||||
CItem &sb = _items[i];
|
||||
sb.IsTail = false;
|
||||
sb.Type = Get32(p, be);
|
||||
sb.SubType = Get32(p + 4, be);
|
||||
sb.Offset = Get32(p + 8, be);
|
||||
sb.Size = Get32(p + 12, be);
|
||||
sb.Align = Get32(p + 16, be);
|
||||
|
||||
if ((sb.Type & ~MACH_TYPE_ABI64) >= 0x100 ||
|
||||
(sb.SubType & ~MACH_SUBTYPE_ABI64) >= 0x100 ||
|
||||
sb.Align > 31)
|
||||
UInt32 align = Get32(p + 16, be);
|
||||
if (align > 31)
|
||||
return S_FALSE;
|
||||
if (sb.Offset < kHeaderSize + num * kRecordSize)
|
||||
return S_FALSE;
|
||||
if ((sb.Type & ~MACH_CPU_ARCH_ABI64) >= 0x100 ||
|
||||
(sb.SubType & ~MACH_CPU_SUBTYPE_LIB64) >= 0x100)
|
||||
return S_FALSE;
|
||||
|
||||
UInt64 endPos = (UInt64)sb.Offset + sb.Size;
|
||||
if (endPos > endPosMax)
|
||||
if (endPosMax < endPos)
|
||||
endPosMax = endPos;
|
||||
}
|
||||
UInt64 fileSize;
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));
|
||||
fileSize -= _startPos;
|
||||
_numItems = num;
|
||||
if (fileSize > endPosMax)
|
||||
{
|
||||
CItem &sb = _items[_numItems++];
|
||||
sb.IsTail = true;
|
||||
sb.Type = 0;
|
||||
sb.SubType = 0;
|
||||
sb.Offset = endPosMax;
|
||||
sb.Size = fileSize - endPosMax;
|
||||
sb.Align = 0;
|
||||
}
|
||||
_phySize = endPosMax;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -186,6 +213,7 @@ STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_stream.Release();
|
||||
_numItems = 0;
|
||||
_phySize = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -199,7 +227,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 = _numItems;
|
||||
if (numItems == 0)
|
||||
@@ -244,7 +272,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
RINOK(_stream->Seek(_startPos + item.Offset, STREAM_SEEK_SET, NULL));
|
||||
RINOK(_stream->Seek(/* _startPos + */ item.Offset, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(item.Size);
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
@@ -260,15 +288,27 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
const CItem &item = _items[index];
|
||||
return CreateLimitedInStream(_stream, _startPos + item.Offset, item.Size, stream);
|
||||
return CreateLimitedInStream(_stream, /* _startPos + */ item.Offset, item.Size, stream);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static IInArchive *CreateArc() { return new CHandler; }
|
||||
IMP_CreateArcIn
|
||||
|
||||
namespace NBe {
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Mub", L"", 0, 0xE2, { 0xCA, 0xFE, 0xBA, 0xBE, 0, 0, 0 }, 7, false, CreateArc, 0 };
|
||||
{ "Mub", "mub", 0, 0xE2,
|
||||
2 + 7 + 4,
|
||||
{
|
||||
7, 0xCA, 0xFE, 0xBA, 0xBE, 0, 0, 0,
|
||||
4, 0xB9, 0xFA, 0xF1, 0x0E
|
||||
},
|
||||
0,
|
||||
NArcInfoFlags::kMultiSignature,
|
||||
CreateArc };
|
||||
|
||||
REGISTER_ARC(Mub)
|
||||
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user