1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
// HfsIn.h
#ifndef __ARCHIVE_HFS_IN_H
#define __ARCHIVE_HFS_IN_H
#include "Common/MyString.h"
#include "Common/Buffer.h"
namespace NArchive {
namespace NHfs {
struct CExtent
{
UInt32 Pos;
UInt32 NumBlocks;
};
struct CFork
{
UInt64 Size;
// UInt32 ClumpSize;
UInt32 NumBlocks;
CExtent Extents[8];
void Parse(const Byte *p);
};
struct CVolHeader
{
Byte Header[2];
UInt16 Version;
// UInt32 Attr;
// UInt32 LastMountedVersion;
// UInt32 JournalInfoBlock;
UInt32 CTime;
UInt32 MTime;
// UInt32 BackupTime;
// UInt32 CheckedTime;
// UInt32 NumFiles;
// UInt32 NumFolders;
int BlockSizeLog;
UInt32 NumBlocks;
UInt32 NumFreeBlocks;
// UInt32 WriteCount;
// UInt32 FinderInfo[8];
// UInt64 VolID;
// CFork AllocationFile;
CFork ExtentsFile;
CFork CatalogFile;
// CFork AttributesFile;
// CFork StartupFile;
bool IsHfsX() const { return Version > 4; }
};
inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft)
{
UInt64 v = ((UInt64)3600 * 24 * (365 * 303 + 24 * 3) + hfsTime) * 10000000;
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
enum ERecordType
{
RECORD_TYPE_FOLDER = 1,
RECORD_TYPE_FILE = 2,
RECORD_TYPE_FOLDER_THREAD = 3,
RECORD_TYPE_FILE_THREAD = 4
};
struct CItem
{
UString Name;
UInt32 ParentID;
UInt16 Type;
// UInt16 Flags;
// UInt32 Valence;
UInt32 ID;
UInt32 CTime;
UInt32 MTime;
// UInt32 AttrMTime;
UInt32 ATime;
// UInt32 BackupDate;
/*
UInt32 OwnerID;
UInt32 GroupID;
Byte AdminFlags;
Byte OwnerFlags;
UInt16 FileMode;
union
{
UInt32 iNodeNum;
UInt32 LinkCount;
UInt32 RawDevice;
} special;
*/
UInt64 Size;
UInt32 NumBlocks;
CRecordVector<CExtent> Extents;
bool IsDir() const { return Type == RECORD_TYPE_FOLDER; }
CItem(): Size(0), NumBlocks(0) {}
};
struct CIdIndexPair
{
UInt32 ID;
int Index;
};
struct CProgressVirt
{
virtual HRESULT SetTotal(UInt64 numFiles) PURE;
virtual HRESULT SetCompleted(UInt64 numFiles) PURE;
};
class CDatabase
{
// CObjectVector<CIdExtents> FileExtents;
// CObjectVector<CIdExtents> ResExtents;
CRecordVector<CIdIndexPair> IdToIndexMap;
HRESULT LoadExtentFile(IInStream *inStream);
HRESULT LoadCatalog(IInStream *inStream, CProgressVirt *progress);
HRESULT ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inStream);
public:
CVolHeader Header;
CObjectVector<CItem> Items;
// bool CaseSensetive;
void Clear()
{
// CaseSensetive = false;
Items.Clear();
// FileExtents.Clear();
// ResExtents.Clear();
IdToIndexMap.Clear();
}
UString GetItemPath(int index) const;
HRESULT Open(IInStream *inStream, CProgressVirt *progress);
};
}}
#endif
|