Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Archive/MubHandler.cpp')
-rw-r--r--[-rwxr-xr-x]CPP/7zip/Archive/MubHandler.cpp180
1 files changed, 110 insertions, 70 deletions
diff --git a/CPP/7zip/Archive/MubHandler.cpp b/CPP/7zip/Archive/MubHandler.cpp
index 5ebda099..39f8de27 100755..100644
--- a/CPP/7zip/Archive/MubHandler.cpp
+++ b/CPP/7zip/Archive/MubHandler.cpp
@@ -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
};
-IMP_IInArchive_Props
-IMP_IInArchive_ArcProps_NO
+static const Byte kProps[] =
+{
+ kpidSize
+};
-#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
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps
-#define MACH_MACHINE_PPC64 (MACH_MACHINE_PPC | MACH_ARCH_ABI64)
-#define MACH_MACHINE_AMD64 (MACH_MACHINE_386 | MACH_ARCH_ABI64)
+STDMETHODIMP 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;
+}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
- NWindows::NCOM::CPropVariant prop;
+ PropVariant_Clear(value);
const CItem &item = _items[index];
- switch(propID)
+ switch (propID)
{
case kpidExtension:
{
- const wchar_t *ext;
- if (item.IsTail)
- ext = L"tail";
- else
+ char temp[32];
+ const char *ext = 0;
+ switch (item.Type)
{
- 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;
- }
+ 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;
}
- prop = ext;
- 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:
- prop = (UInt64)item.Size;
+ PropVarEm_Set_UInt64(value, item.Size);
break;
}
- prop.Detach(value);
return S_OK;
}
-#define MACH_TYPE_ABI64 (1 << 24)
-#define MACH_SUBTYPE_ABI64 (1 << 31)
-
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)
+}
+
}}