diff options
Diffstat (limited to 'src/libs/7zip/unix/CPP/7zip/Archive/ApmHandler.cpp')
-rw-r--r-- | src/libs/7zip/unix/CPP/7zip/Archive/ApmHandler.cpp | 356 |
1 files changed, 0 insertions, 356 deletions
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/ApmHandler.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/ApmHandler.cpp deleted file mode 100644 index a3b5e19b9..000000000 --- a/src/libs/7zip/unix/CPP/7zip/Archive/ApmHandler.cpp +++ /dev/null @@ -1,356 +0,0 @@ -// ApmHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "Common/ComTry.h" -#include "Common/IntToString.h" -#include "Common/MyString.h" - -#include "Windows/PropVariant.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" - -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) - -using namespace NWindows; - -namespace NArchive { -namespace NApm { - -struct CItem -{ - UInt32 StartBlock; - UInt32 NumBlocks; - char Name[32]; - char Type[32]; - /* - UInt32 DataStartBlock; - UInt32 NumDataBlocks; - UInt32 Status; - UInt32 BootStartBlock; - UInt32 BootSize; - UInt32 BootAddr; - UInt32 BootEntry; - UInt32 BootChecksum; - char Processor[16]; - */ - - 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); - /* - DataStartBlock = Get32(p + 0x50); - NumDataBlocks = Get32(p + 0x54); - Status = Get32(p + 0x58); - BootStartBlock = Get32(p + 0x5C); - BootSize = Get32(p + 0x60); - BootAddr = Get32(p + 0x64); - if (Get32(p + 0x68) != 0) - return false; - BootEntry = Get32(p + 0x6C); - if (Get32(p + 0x70) != 0) - return false; - BootChecksum = Get32(p + 0x74); - memcpy(Processor, p + 0x78, 16); - */ - return true; - } -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CMyComPtr<IInStream> _stream; - CRecordVector<CItem> _items; - - int _blockSizeLog; - UInt32 _numBlocks; - - HRESULT ReadTables(IInStream *stream); - UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; } - UInt64 GetItemSize(const CItem &item) { return BlocksToBytes(item.NumBlocks); } -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -static inline int GetLog(UInt32 num) -{ - for (int i = 0; i < 31; i++) - if (((UInt32)1 << i) == num) - return i; - return -1; -} - -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) - return S_FALSE; - _numBlocks = Get32(buf + 4); - for (int i = 8; i < 16; i++) - if (buf[i] != 0) - return S_FALSE; - } - - unsigned numSkips = (unsigned)1 << (_blockSizeLog - 9); - for (unsigned j = 1; j < numSkips; j++) - { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - } - - UInt32 numBlocksInMap = 0; - for (unsigned i = 0;;) - { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - - CItem item; - - UInt32 numBlocksInMap2; - if (!item.Parse(buf, numBlocksInMap2)) - return S_FALSE; - if (i == 0) - { - numBlocksInMap = numBlocksInMap2; - if (numBlocksInMap > (1 << 8)) - return S_FALSE; - } - else if (numBlocksInMap2 != numBlocksInMap) - return S_FALSE; - - UInt32 finish = item.StartBlock + item.NumBlocks; - if (finish < item.StartBlock) - return S_FALSE; - _numBlocks = MyMax(_numBlocks, finish); - - _items.Add(item); - for (unsigned j = 1; j < numSkips; j++) - { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - } - if (++i == numBlocksInMap) - break; - } - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - RINOK(ReadTables(stream)); - _stream = stream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _items.Clear(); - _stream.Release(); - return S_OK; -} - -STATPROPSTG kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidOffset, VT_UI8} -}; - -STATPROPSTG kArcProps[] = -{ - { NULL, kpidClusterSize, VT_UI4}, - { NULL, kpidPhySize, VT_UI8} -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -static AString GetString(const char *s) -{ - AString res; - for (int i = 0; i < 32 && s[i] != 0; i++) - res += s[i]; - return res; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch(propID) - { - case kpidMainSubfile: - { - int mainIndex = -1; - for (int i = 0; i < _items.Size(); i++) - { - AString s = GetString(_items[i].Type); - if (s != "Apple_Free" && - s != "Apple_partition_map") - { - if (mainIndex >= 0) - { - mainIndex = -1; - break; - } - mainIndex = i; - } - } - if (mainIndex >= 0) - prop = (UInt32)mainIndex; - break; - } - case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break; - case kpidPhySize: prop = BlocksToBytes(_numBlocks); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - const CItem &item = _items[index]; - switch(propID) - { - case kpidPath: - { - AString s = GetString(item.Name); - if (s.IsEmpty()) - { - char s2[32]; - ConvertUInt32ToString(index, s2); - s = s2; - } - AString type = GetString(item.Type); - if (type == "Apple_HFS") - type = "hfs"; - if (!type.IsEmpty()) - { - s += '.'; - s += type; - } - prop = s; - break; - } - case kpidSize: - case kpidPackSize: - prop = GetItemSize(item); - break; - case kpidOffset: prop = BlocksToBytes(item.StartBlock); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)-1); - if (allFilesMode) - numItems = _items.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += GetItemSize(_items[allFilesMode ? i : indices[i]]); - extractCallback->SetTotal(totalSize); - - totalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++) - { - lps->InSize = totalSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr<ISequentialOutStream> outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[index]; - - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - UInt64 size = GetItemSize(item); - totalSize += size; - if (!testMode && !outStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - RINOK(_stream->Seek(BlocksToBytes(item.StartBlock), STREAM_SEEK_SET, NULL)); - streamSpec->Init(size); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - outStream.Release(); - RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == size ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - const CItem &item = _items[index]; - return CreateLimitedInStream(_stream, BlocksToBytes(item.StartBlock), GetItemSize(item), stream); - COM_TRY_END -} - -static IInArchive *CreateArc() { return new CHandler; } - -static CArcInfo g_ArcInfo = - { L"APM", L"", 0, 0xD4, { 0x50, 0x4D, 0, 0, 0, 0, 0 }, 7, false, CreateArc, 0 }; - -REGISTER_ARC(Apm) - -}} |