chore: initial commit (extracted from Launchers monorepo)
Plugin: ns7zip v2.0.0 Architectures: x86-ansi, x86-unicode, amd64-unicode License: LGPL-2.1-or-later
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
// MubHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../C/CpuArch.h"
|
||||
#include "../../../C/SwapBytes.h"
|
||||
|
||||
#include "../../Common/ComTry.h"
|
||||
#include "../../Common/IntToString.h"
|
||||
#include "../../Common/MyString.h"
|
||||
|
||||
#include "../../Windows/PropVariant.h"
|
||||
|
||||
#include "../Common/RegisterArc.h"
|
||||
#include "../Common/StreamUtils.h"
|
||||
|
||||
#include "HandlerCont.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NMub {
|
||||
|
||||
#define MACH_CPU_ARCH_ABI64 ((UInt32)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_TYPE_ARM64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_ARM)
|
||||
|
||||
#define MACH_CPU_SUBTYPE_LIB64 ((UInt32)1 << 31)
|
||||
|
||||
#define MACH_CPU_SUBTYPE_I386_ALL 3
|
||||
|
||||
struct CItem
|
||||
{
|
||||
UInt32 Type;
|
||||
UInt32 SubType;
|
||||
UInt32 Offset;
|
||||
UInt32 Size;
|
||||
UInt32 Align;
|
||||
};
|
||||
|
||||
static const UInt32 kNumFilesMax = 6;
|
||||
|
||||
Z7_class_CHandler_final: public CHandlerCont
|
||||
{
|
||||
Z7_IFACE_COM7_IMP(IInArchive_Cont)
|
||||
|
||||
// UInt64 _startPos;
|
||||
UInt64 _phySize;
|
||||
UInt32 _numItems;
|
||||
bool _bigEndian;
|
||||
CItem _items[kNumFilesMax];
|
||||
|
||||
HRESULT Open2(IInStream *stream);
|
||||
|
||||
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override
|
||||
{
|
||||
const CItem &item = _items[index];
|
||||
pos = item.Offset;
|
||||
size = item.Size;
|
||||
return NExtract::NOperationResult::kOK;
|
||||
}
|
||||
};
|
||||
|
||||
static const Byte kArcProps[] =
|
||||
{
|
||||
kpidBigEndian
|
||||
};
|
||||
|
||||
static const Byte kProps[] =
|
||||
{
|
||||
kpidPath,
|
||||
kpidSize,
|
||||
kpidOffset,
|
||||
kpidClusterSize // Align
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||
{
|
||||
PropVariant_Clear(value);
|
||||
switch (propID)
|
||||
{
|
||||
case kpidBigEndian: PropVarEm_Set_Bool(value, _bigEndian); break;
|
||||
case kpidPhySize: PropVarEm_Set_UInt64(value, _phySize); break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Z7_COM7F_IMF(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 = NULL;
|
||||
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_AMD64: ext = "x64"; break;
|
||||
case MACH_CPU_TYPE_ARM64: ext = "arm64"; break;
|
||||
case MACH_CPU_TYPE_PPC64: ext = "ppc64"; break;
|
||||
default:
|
||||
temp[0] = 'c';
|
||||
temp[1] = 'p';
|
||||
temp[2] = 'u';
|
||||
char *p = ConvertUInt32ToString(item.Type & ~MACH_CPU_ARCH_ABI64, temp + 3);
|
||||
if (item.Type & MACH_CPU_ARCH_ABI64)
|
||||
MyStringCopy(p, "_64");
|
||||
break;
|
||||
}
|
||||
if (ext)
|
||||
MyStringCopy(temp, ext);
|
||||
if (item.SubType != 0)
|
||||
if ((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;
|
||||
case kpidOffset:
|
||||
PropVarEm_Set_UInt64(value, item.Offset);
|
||||
break;
|
||||
case kpidClusterSize:
|
||||
PropVarEm_Set_UInt32(value, (UInt32)1 << item.Align);
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CHandler::Open2(IInStream *stream)
|
||||
{
|
||||
// RINOK(InStream_GetPos(stream, _startPos));
|
||||
|
||||
const UInt32 kHeaderSize = 2;
|
||||
const UInt32 kRecordSize = 5;
|
||||
const UInt32 kBufSize = kHeaderSize + kNumFilesMax * kRecordSize;
|
||||
UInt32 buf[kBufSize];
|
||||
size_t processed = kBufSize * 4;
|
||||
RINOK(ReadStream(stream, buf, &processed))
|
||||
processed >>= 2;
|
||||
if (processed < kHeaderSize)
|
||||
return S_FALSE;
|
||||
|
||||
bool be;
|
||||
switch (buf[0])
|
||||
{
|
||||
case Z7_CONV_BE_TO_NATIVE_CONST32(0xCAFEBABE): be = true; break;
|
||||
case Z7_CONV_BE_TO_NATIVE_CONST32(0xB9FAF10E): be = false; break;
|
||||
default: return S_FALSE;
|
||||
}
|
||||
_bigEndian = be;
|
||||
if (
|
||||
#if defined(MY_CPU_BE)
|
||||
!
|
||||
#endif
|
||||
be)
|
||||
z7_SwapBytes4(&buf[1], processed - 1);
|
||||
const UInt32 num = buf[1];
|
||||
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 UInt32 *p = buf + kHeaderSize + i * kRecordSize;
|
||||
CItem &sb = _items[i];
|
||||
sb.Type = p[0];
|
||||
sb.SubType = p[1];
|
||||
sb.Offset = p[2];
|
||||
sb.Size = p[3];
|
||||
const UInt32 align = p[4];
|
||||
sb.Align = align;
|
||||
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;
|
||||
|
||||
const UInt64 endPos = (UInt64)sb.Offset + sb.Size;
|
||||
if (endPosMax < endPos)
|
||||
endPosMax = endPos;
|
||||
}
|
||||
_numItems = num;
|
||||
_phySize = endPosMax;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Z7_COM7F_IMF(CHandler::Open(IInStream *inStream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback * /* openArchiveCallback */))
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
Close();
|
||||
try
|
||||
{
|
||||
if (Open2(inStream) != S_OK)
|
||||
return S_FALSE;
|
||||
_stream = inStream;
|
||||
}
|
||||
catch(...) { return S_FALSE; }
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
Z7_COM7F_IMF(CHandler::Close())
|
||||
{
|
||||
_stream.Release();
|
||||
_numItems = 0;
|
||||
_phySize = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
|
||||
{
|
||||
*numItems = _numItems;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
namespace NBe {
|
||||
|
||||
static const Byte k_Signature[] = {
|
||||
7, 0xCA, 0xFE, 0xBA, 0xBE, 0, 0, 0,
|
||||
4, 0xB9, 0xFA, 0xF1, 0x0E };
|
||||
|
||||
REGISTER_ARC_I(
|
||||
"Mub", "mub", NULL, 0xE2,
|
||||
k_Signature,
|
||||
0,
|
||||
NArcInfoFlags::kMultiSignature,
|
||||
NULL)
|
||||
|
||||
}
|
||||
|
||||
}}
|
||||
Reference in New Issue
Block a user