diff options
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/Hfs/HfsIn.cpp')
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Hfs/HfsIn.cpp | 480 |
1 files changed, 0 insertions, 480 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Hfs/HfsIn.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Hfs/HfsIn.cpp deleted file mode 100644 index 8391dd936..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Hfs/HfsIn.cpp +++ /dev/null @@ -1,480 +0,0 @@ -// HfsIn.cpp - -#include "StdAfx.h" - -#include "../../Common/StreamUtils.h" -#include "Common/IntToString.h" - -#include "HfsIn.h" - -#include "../../../../C/CpuArch.h" - -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) -#define Get64(p) GetBe64(p) - -namespace NArchive { -namespace NHfs { - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -static int CompareIdToIndex(const CIdIndexPair *p1, const CIdIndexPair *p2, void * /* param */) -{ - RINOZ(MyCompare(p1->ID, p2->ID)); - return MyCompare(p1->Index, p2->Index); -} - -bool operator< (const CIdIndexPair &a1, const CIdIndexPair &a2) { return (a1.ID < a2.ID); } -bool operator> (const CIdIndexPair &a1, const CIdIndexPair &a2) { return (a1.ID > a2.ID); } -bool operator==(const CIdIndexPair &a1, const CIdIndexPair &a2) { return (a1.ID == a2.ID); } -bool operator!=(const CIdIndexPair &a1, const CIdIndexPair &a2) { return (a1.ID != a2.ID); } - -static UString GetSpecName(const UString &name, UInt32 /* id */) -{ - UString name2 = name; - name2.Trim(); - if (name2.IsEmpty()) - { - /* - wchar_t s[32]; - ConvertUInt64ToString(id, s); - return L"[" + (UString)s + L"]"; - */ - return L"[]"; - } - return name; -} - -UString CDatabase::GetItemPath(int index) const -{ - const CItem *item = &Items[index]; - UString name = GetSpecName(item->Name, item->ID); - - for (int i = 0; i < 1000; i++) - { - if (item->ParentID < 16 && item->ParentID != 2) - { - if (item->ParentID != 1) - break; - return name; - } - CIdIndexPair pair; - pair.ID = item->ParentID; - pair.Index = 0; - int indexInMap = IdToIndexMap.FindInSorted(pair); - if (indexInMap < 0) - break; - item = &Items[IdToIndexMap[indexInMap].Index]; - name = GetSpecName(item->Name, item->ID) + WCHAR_PATH_SEPARATOR + name; - } - return (UString)L"Unknown" + WCHAR_PATH_SEPARATOR + name; -} - -void CFork::Parse(const Byte *p) -{ - Size = Get64(p); - // ClumpSize = Get32(p + 8); - NumBlocks = Get32(p + 0xC); - for (int i = 0; i < 8; i++) - { - CExtent &e = Extents[i]; - e.Pos = Get32(p + 0x10 + i * 8); - e.NumBlocks = Get32(p + 0x10 + i * 8 + 4); - } -} - -static HRESULT ReadExtent(int blockSizeLog, IInStream *inStream, Byte *buf, const CExtent &e) -{ - RINOK(inStream->Seek((UInt64)e.Pos << blockSizeLog, STREAM_SEEK_SET, NULL)); - return ReadStream_FALSE(inStream, buf, (size_t)e.NumBlocks << blockSizeLog); -} - -HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inStream) -{ - if (fork.NumBlocks >= Header.NumBlocks) - return S_FALSE; - size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog; - if ((totalSize >> Header.BlockSizeLog) != fork.NumBlocks) - return S_FALSE; - buf.SetCapacity(totalSize); - UInt32 curBlock = 0; - for (int i = 0; i < 8; i++) - { - if (curBlock >= fork.NumBlocks) - break; - const CExtent &e = fork.Extents[i]; - if (fork.NumBlocks - curBlock < e.NumBlocks || e.Pos >= Header.NumBlocks) - return S_FALSE; - RINOK(ReadExtent(Header.BlockSizeLog, inStream, - (Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog), e)); - curBlock += e.NumBlocks; - } - return S_OK; -} - -struct CNodeDescriptor -{ - UInt32 fLink; - UInt32 bLink; - Byte Kind; - Byte Height; - UInt16 NumRecords; - // UInt16 Reserved; - void Parse(const Byte *p); -}; - -void CNodeDescriptor::Parse(const Byte *p) -{ - fLink = Get32(p); - bLink = Get32(p + 4); - Kind = p[8]; - Height = p[9]; - NumRecords = Get16(p + 10); -} - -struct CHeaderRec -{ - // UInt16 TreeDepth; - // UInt32 RootNode; - // UInt32 LeafRecords; - UInt32 FirstLeafNode; - // UInt32 LastLeafNode; - int NodeSizeLog; - // UInt16 MaxKeyLength; - UInt32 TotalNodes; - // UInt32 FreeNodes; - // UInt16 Reserved1; - // UInt32 ClumpSize; - // Byte BtreeType; - // Byte KeyCompareType; - // UInt32 Attributes; - // UInt32 Reserved3[16]; - - HRESULT Parse(const Byte *p); -}; - -HRESULT CHeaderRec::Parse(const Byte *p) -{ - // TreeDepth = Get16(p); - // RootNode = Get32(p + 2); - // LeafRecords = Get32(p + 6); - FirstLeafNode = Get32(p + 0xA); - // LastLeafNode = Get32(p + 0xE); - UInt32 nodeSize = Get16(p + 0x12); - - int i; - for (i = 9; ((UInt32)1 << i) != nodeSize; i++) - if (i == 16) - return S_FALSE; - NodeSizeLog = i; - - // MaxKeyLength = Get16(p + 0x14); - TotalNodes = Get32(p + 0x16); - // FreeNodes = Get32(p + 0x1A); - // Reserved1 = Get16(p + 0x1E); - // ClumpSize = Get32(p + 0x20); - // BtreeType = p[0x24]; - // KeyCompareType = p[0x25]; - // Attributes = Get32(p + 0x26); - /* - for (int i = 0; i < 16; i++) - Reserved3[i] = Get32(p + 0x2A + i * 4); - */ - return S_OK; -} - - -enum ENodeType -{ - NODE_TYPE_LEAF = 0xFF, - NODE_TYPE_INDEX = 0, - NODE_TYPE_HEADER = 1, - NODE_TYPE_MODE = 2 -}; - -HRESULT CDatabase::LoadExtentFile(IInStream *inStream) -{ - // FileExtents.Clear(); - // ResExtents.Clear(); - - CByteBuffer extents; - RINOK(ReadFile(Header.ExtentsFile, extents, inStream)); - - const Byte *p = (const Byte *)extents; - - // CNodeDescriptor nodeDesc; - // nodeDesc.Parse(p); - CHeaderRec hr; - RINOK(hr.Parse(p + 14)); - - UInt32 node = hr.FirstLeafNode; - if (node != 0) - return S_FALSE; - /* - while (node != 0) - { - size_t nodeOffset = node * hr.NodeSize; - if ((node + 1)* hr.NodeSize > CatalogBuf.GetCapacity()) - return S_FALSE; - CNodeDescriptor desc; - desc.Parse(p + nodeOffset); - if (desc.Kind != NODE_TYPE_LEAF) - return S_FALSE; - UInt32 ptr = hr.NodeSize; - for (int i = 0; i < desc.NumRecords; i++) - { - UInt32 offs = Get16(p + nodeOffset + hr.NodeSize - (i + 1) * 2); - UInt32 offsNext = Get16(p + nodeOffset + hr.NodeSize - (i + 2) * 2); - - const Byte *r = p + nodeOffset + offs; - int keyLength = Get16(r); - Byte forkType = r[2]; - UInt32 id = Get16(r + 4); - UInt32 startBlock = Get16(r + 4); - CObjectVector<CIdExtents> *extents = (forkType == 0) ? &FileExtents : &ResExtents; - if (extents->Size() == 0) - extents->Add(CIdExtents()); - else - { - CIdExtents &e = extents->Back(); - if (e.ID != id) - { - if (e.ID > id) - return S_FALSE; - extents->Add(CIdExtents()); - } - } - CIdExtents &e = extents->Back(); - for (UInt32 k = offs + 10 + 2; k + 8 <= offsNext; k += 8) - { - CExtent ee; - ee.Pos = Get32(p + nodeOffset + k); - ee.NumBlocks = Get32(p + nodeOffset + k * 4); - e.Extents.Add(ee); - } - } - node = desc.fLink; - } - */ - return S_OK; -} - - -HRESULT CDatabase::LoadCatalog(IInStream *inStream, CProgressVirt *progress) -{ - Items.Clear(); - IdToIndexMap.ClearAndFree(); - - CByteBuffer catalogBuf; - RINOK(ReadFile(Header.CatalogFile, catalogBuf, inStream)); - const Byte *p = (const Byte *)catalogBuf; - - // CNodeDescriptor nodeDesc; - // nodeDesc.Parse(p); - CHeaderRec hr; - hr.Parse(p + 14); - - // CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC); - - if ((catalogBuf.GetCapacity() >> hr.NodeSizeLog) < hr.TotalNodes) - return S_FALSE; - - CByteBuffer usedBuf; - usedBuf.SetCapacity(hr.TotalNodes); - for (UInt32 i = 0; i < hr.TotalNodes; i++) - usedBuf[i] = 0; - - UInt32 node = hr.FirstLeafNode; - while (node != 0) - { - if (node >= hr.TotalNodes) - return S_FALSE; - if (usedBuf[node]) - return S_FALSE; - usedBuf[node] = 1; - size_t nodeOffset = (size_t)node << hr.NodeSizeLog; - CNodeDescriptor desc; - desc.Parse(p + nodeOffset); - if (desc.Kind != NODE_TYPE_LEAF) - return S_FALSE; - for (int i = 0; i < desc.NumRecords; i++) - { - UInt32 nodeSize = (1 << hr.NodeSizeLog); - UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2); - UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2); - UInt32 recSize = offsNext - offs; - if (offsNext >= nodeSize || offsNext < offs || recSize < 6) - return S_FALSE; - - CItem item; - - const Byte *r = p + nodeOffset + offs; - UInt32 keyLength = Get16(r); - item.ParentID = Get32(r + 2); - UString name; - if (keyLength < 6 || (keyLength & 1) != 0 || keyLength + 2 > recSize) - return S_FALSE; - r += 6; - recSize -= 6; - keyLength -= 6; - - int nameLength = Get16(r); - if (nameLength * 2 != (int)keyLength) - return S_FALSE; - r += 2; - recSize -= 2; - - wchar_t *pp = name.GetBuffer(nameLength + 1); - - int j; - for (j = 0; j < nameLength; j++) - pp[j] = ((wchar_t)r[j * 2] << 8) | r[j * 2 + 1]; - pp[j] = 0; - name.ReleaseBuffer(); - r += j * 2; - recSize -= j * 2; - - if (recSize < 2) - return S_FALSE; - item.Type = Get16(r); - - if (item.Type != RECORD_TYPE_FOLDER && item.Type != RECORD_TYPE_FILE) - continue; - if (recSize < 0x58) - return S_FALSE; - - // item.Flags = Get16(r + 2); - // item.Valence = Get32(r + 4); - item.ID = Get32(r + 8); - item.CTime = Get32(r + 0xC); - item.MTime = Get32(r + 0x10); - // item.AttrMTime = Get32(r + 0x14); - item.ATime = Get32(r + 0x18); - // item.BackupDate = Get32(r + 0x1C); - - /* - item.OwnerID = Get32(r + 0x20); - item.GroupID = Get32(r + 0x24); - item.AdminFlags = r[0x28]; - item.OwnerFlags = r[0x29]; - item.FileMode = Get16(r + 0x2A); - item.special.iNodeNum = Get16(r + 0x2C); - */ - - item.Name = name; - - if (item.IsDir()) - { - CIdIndexPair pair; - pair.ID = item.ID; - pair.Index = Items.Size(); - IdToIndexMap.Add(pair); - } - else - { - CFork fd; - recSize -= 0x58; - r += 0x58; - if (recSize < 0x50 * 2) - return S_FALSE; - fd.Parse(r); - item.Size = fd.Size; - item.NumBlocks = fd.NumBlocks; - UInt32 curBlock = 0; - for (int j = 0; j < 8; j++) - { - if (curBlock >= fd.NumBlocks) - break; - const CExtent &e = fd.Extents[j]; - item.Extents.Add(e); - curBlock += e.NumBlocks; - } - } - Items.Add(item); - if (progress && Items.Size() % 100 == 0) - { - RINOK(progress->SetCompleted(Items.Size())); - } - } - node = desc.fLink; - } - IdToIndexMap.Sort(CompareIdToIndex, NULL); - return S_OK; -} - -HRESULT CDatabase::Open(IInStream *inStream, CProgressVirt *progress) -{ - static const UInt32 kHeaderSize = 1024 + 512; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); - int i; - for (i = 0; i < 1024; i++) - if (buf[i] != 0) - return S_FALSE; - const Byte *p = buf + 1024; - CVolHeader &h = Header; - - h.Header[0] = p[0]; - h.Header[1] = p[1]; - if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) - return S_FALSE; - h.Version = Get16(p + 2); - if (h.Version < 4 || h.Version > 5) - return S_FALSE; - - // h.Attr = Get32(p + 4); - // h.LastMountedVersion = Get32(p + 8); - // h.JournalInfoBlock = Get32(p + 0xC); - - h.CTime = Get32(p + 0x10); - h.MTime = Get32(p + 0x14); - // h.BackupTime = Get32(p + 0x18); - // h.CheckedTime = Get32(p + 0x1C); - - // h.NumFiles = Get32(p + 0x20); - // h.NumFolders = Get32(p + 0x24); - - UInt32 numFiles = Get32(p + 0x20); - UInt32 numFolders = Get32(p + 0x24);; - if (progress) - { - RINOK(progress->SetTotal(numFolders + numFiles)); - } - - UInt32 blockSize = Get32(p + 0x28); - - for (i = 9; ((UInt32)1 << i) != blockSize; i++) - if (i == 31) - return S_FALSE; - h.BlockSizeLog = i; - - h.NumBlocks = Get32(p + 0x2C); - h.NumFreeBlocks = Get32(p + 0x30); - - /* - h.WriteCount = Get32(p + 0x44); - for (i = 0; i < 6; i++) - h.FinderInfo[i] = Get32(p + 0x50 + i * 4); - h.VolID = Get64(p + 0x68); - */ - - UInt64 endPos; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - if ((endPos >> h.BlockSizeLog) < h.NumBlocks) - return S_FALSE; - - // h.AllocationFile.Parse(p + 0x70 + 0x50 * 0); - h.ExtentsFile.Parse( p + 0x70 + 0x50 * 1); - h.CatalogFile.Parse( p + 0x70 + 0x50 * 2); - // h.AttributesFile.Parse(p + 0x70 + 0x50 * 3); - // h.StartupFile.Parse( p + 0x70 + 0x50 * 4); - - RINOK(LoadExtentFile(inStream)); - RINOK(LoadCatalog(inStream, progress)); - - // if (Header.NumFiles + Header.NumFolders != (UInt32)Items.Size()) return S_OK; - - return S_OK; -} - -}} |