diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml index 35b58cce0..db3549e2c 100644 --- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml +++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml @@ -1326,6 +1326,7 @@ + diff --git a/DiscImageChef.Filesystems/AppleHFS/Consts.cs b/DiscImageChef.Filesystems/AppleHFS/Consts.cs index 412a3a645..cc69096f2 100644 --- a/DiscImageChef.Filesystems/AppleHFS/Consts.cs +++ b/DiscImageChef.Filesystems/AppleHFS/Consts.cs @@ -40,5 +40,16 @@ namespace DiscImageChef.Filesystems const ushort HFS_MAGIC = 0x4244; /// "H+", HFS+ magic const ushort HFSP_MAGIC = 0x482B; + + /// Parent ID of the root directory. + const uint kRootParentCnid = 1; + /// Directory ID of the root directory. + const uint kRootCnid = 2; + /// File number of the extents file. + const uint kExtentsFileCnid = 3; + /// File number of the catalog file. + const uint kCatalogFileCnid = 4; + /// File number of the bad allocation block file. + const uint kBadBlocksFileCnid = 5; } } \ No newline at end of file diff --git a/DiscImageChef.Filesystems/AppleHFS/Enums.cs b/DiscImageChef.Filesystems/AppleHFS/Enums.cs new file mode 100644 index 000000000..93920071f --- /dev/null +++ b/DiscImageChef.Filesystems/AppleHFS/Enums.cs @@ -0,0 +1,115 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : AppleHFS.cs +// Author(s) : Natalia Portillo +// +// Component : Apple Hierarchical File System plugin. +// +// --[ Description ] ---------------------------------------------------------- +// +// Identifies the Apple Hierarchical File System and shows information. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2020 Natalia Portillo +// ****************************************************************************/ + +using System; + +namespace DiscImageChef.Filesystems +{ + internal enum NodeType : sbyte + { + /// Index node + ndIndxNode = 0, + /// Header node + ndHdrNode = 1, + /// Map node + ndMapNode = 2, + /// Leaf node + ndLeafNode = -1 + } + + internal enum CatDataType : sbyte + { + /// Directory record + cdrDirRec = 1, + /// File record + cdrFilRec = 2, + /// Directory thread record + cdrThdRec = 3, + /// File thread record + cdrFThdRec = 4 + } + + internal enum ForkType : sbyte + { + Data = 0, Resource = -1 + } + + [Flags] + internal enum FinderFlags : ushort + { + /// Is on desktop. + kIsOnDesk = 0x0001, + /// Color mask. + kColor = 0x000E, kRequireSwitchLaunch = 0x0020, + /// If clear, the application needs to write to its resource fork, and therefore cannot be shared on a server. + kIsShared = 0x0040, + /// Extension or control panel with no INIT entries in resource fork. + kHasNoINITs = 0x0080, + /// + /// Clear if the file contains desktop database resources ('BNDL', 'FREF', 'open', 'kind'...) that have not been + /// added yet. Set only by the Finder. Reserved for folders - make sure this bit is cleared for folders. + /// + kHasBeenInited = 0x0100, + /// PowerTalk + kAOCE = 0x200, + /// Has a custom icon in the resource fork. + kHasCustomIcon = 0x0400, + /// Is a stationery. + kIsStationery = 0x0800, + /// Cannot be renamed. + kNameLocked = 0x1000, + /// Indicates that a file has a BNDL resource or that a folder is displayed as a package. + kHasBundle = 0x2000, + /// Hidden. + kIsInvisible = 0x4000, + /// Is an alias + kIsAlias = 0x8000 + } + + [Flags] + internal enum ExtendedFinderFlags : ushort + { + /// If set the other extended flags are ignored. + kExtendedFlagsAreInvalid = 0x8000, + /// Set if the file or folder has a badge resource. + kExtendedFlagHasCustomBadge = 0x0100, + /// Set if the object is marked as busy/incomplete. + kExtendedFlagObjectIsBusy = 0x0080, + /// Set if the file contains routing info resource. + kExtendedFlagHasRoutingInfo = 0x0004 + } + + internal enum FinderFolder : short + { + fTrash = -3, fDesktop = -2, fDisk = 0 + } +} \ No newline at end of file diff --git a/DiscImageChef.Filesystems/AppleHFS/Structs.cs b/DiscImageChef.Filesystems/AppleHFS/Structs.cs index 34f879c4d..307de9504 100644 --- a/DiscImageChef.Filesystems/AppleHFS/Structs.cs +++ b/DiscImageChef.Filesystems/AppleHFS/Structs.cs @@ -32,6 +32,9 @@ using System.Runtime.InteropServices; +// ReSharper disable IdentifierTypo +// ReSharper disable MemberCanBePrivate.Local + namespace DiscImageChef.Filesystems { // Information from Inside Macintosh @@ -126,5 +129,271 @@ namespace DiscImageChef.Filesystems /// 0x092, Bytes in the catalog B-Tree 3 HFS extents following, 32 bits each public readonly uint drCTFlSize; } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct NodeDescriptor + { + /// A link to the next node of this type, or null if this is the last one. + public readonly uint ndFLink; + /// A link to the previous node of this type, or null if this is the first one. + public readonly uint ndBLink; + /// The type of this node. + public readonly NodeType ndType; + /// The depth of this node in the B*-tree hierarchy. Maximum depth is apparently 8. + public readonly sbyte ndNHeight; + /// The number of records contained in this node. + public readonly ushort ndNRecs; + /// Reserved, should be 0. + public readonly ushort ndResv2; + } + + /// B*-tree header + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct BTHdrRed + { + /// Current depth of tree. + public readonly ushort bthDepth; + /// Number of root node. + public readonly uint bthRoot; + /// Number of leaf records in tree. + public readonly uint bthNRecs; + /// Number of first leaf node. + public readonly uint bthFNode; + /// Number of last leaf node. + public readonly uint bthLNode; + /// Size of a node. + public readonly ushort bthNodeSize; + /// Maximum length of a key. + public readonly ushort bthKeyLen; + /// Total number of nodes in tree. + public readonly uint bthNNodes; + /// Number of free nodes. + public readonly uint bthFree; + /// Reserved + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 76)] + public readonly sbyte[] bthResv; + } + + /// Catalog key record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CatKeyRec + { + /// Key length. + public readonly sbyte ckrKeyLen; + /// Reserved. + public readonly sbyte ckrResrv1; + /// Parent directory ID. + public readonly uint ckrParID; + /// Catalog node name. Full 32 bytes in index nodes but only the needed bytes, padded to word, in leaf nodes. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public readonly byte[] ckrCName; + } + + /// Catalog data record header + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CatDataRec + { + public readonly CatDataType cdrType; + public readonly sbyte cdrResvr2; + } + + /// Directory record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CdrDirRec + { + public readonly CatDataRec dirHdr; + /// Directory flags. + public readonly ushort dirFlags; + /// Directory valence. + public readonly ushort dirVal; + /// Directory ID. + public readonly uint dirDirID; + /// Date and time of creation. + public readonly uint dirCrDat; + /// Date and time of last modification. + public readonly uint dirMdDat; + /// Date and time of last backup. + public readonly uint dirBkDat; + /// Finder information. + public readonly DInfo dirUsrInfo; + /// Additional Finder information. + public readonly DXInfo dirFndrInfo; + /// Reserved + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public readonly uint[] dirResrv; + } + + /// File record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CdrFilRec + { + public readonly CatDataRec filHdr; + /// File flags. + public readonly sbyte filFlags; + /// File type. + public readonly sbyte filType; + /// Finder information. + public readonly FInfo filUsrWds; + /// File ID. + public readonly uint filFlNum; + /// First allocation block of data fork. + public readonly ushort filStBlk; + /// Logical EOF of data fork. + public readonly uint filLgLen; + /// Physical EOF of data fork. + public readonly uint filPyLen; + /// First allocation block of resource fork. + public readonly ushort filRStBlk; + /// Logical EOF of resource fork. + public readonly uint filRLgLen; + /// Physical EOF of resource fork. + public readonly uint filRPyLen; + /// Date and time of creation. + public readonly uint filCrDat; + /// Date and time of last modification. + public readonly uint filMdDat; + /// Date and time of last backup. + public readonly uint filBkDat; + /// Additional Finder information. + public readonly FXInfo filFndrInfo; + /// File clump size. + public readonly ushort filClpSize; + /// First data fork extent record. + public readonly ExtDataRec filExtRec; + /// First resource fork extent record. + public readonly ExtDataRec filRExtRec; + /// Reserved + public readonly uint filResrv; + } + + /// Directory thread record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CdrThdRec + { + public readonly CatDataRec thdHdr; + /// Reserved. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public readonly uint[] thdResrv; + /// Parent ID for this directory. + public readonly uint thdParID; + /// Name of this directory. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public readonly byte[] thdCName; + } + + /// File thread record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CdrFThdRec + { + public readonly CatDataRec fthdHdr; + /// Reserved. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public readonly uint[] fthdResrv; + /// Parent ID for this file. + public readonly uint fthdParID; + /// Name of this file. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public readonly byte[] fthdCName; + } + + /// Extent descriptor + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct ExtDescriptor + { + /// First allocation block + public readonly ushort xdrStABN; + /// Number of allocation blocks + public readonly ushort xdrNumABlks; + } + + /// Extent data record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct ExtDataRec + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public readonly ExtDescriptor[] xdr; + } + + /// Extent key record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct ExtKeyRec + { + /// Key length. + public readonly sbyte xkrKeyLen; + /// Fork type. + public readonly ForkType xkrFkType; + /// File number. + public readonly uint xkrFNum; + /// Starting file allocation block. + public readonly ushort xkrFABN; + } + + struct Point + { + public ushort v; + public ushort h; + } + + struct Rect + { + public ushort top; + public ushort left; + public ushort bottom; + public ushort right; + } + + struct FInfo + { + /// The type of the file. + public uint fdType; + /// The file's creator. + public uint fdCreator; + /// Flags. + public FinderFlags fdFlags; + /// File's location in the folder. + public Point fdLocation; + /// Folder file belongs to (used only in flat filesystems like MFS). + public FinderFolder fdFldr; + } + + struct FXInfo + { + /// Resource fork ID of file icon. + public ushort fdIconID; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] fdUnused; + /// Extended flags. If high-bit is set, most significant byte is script code and least significant byte are flags. + public ExtendedFinderFlags fdXFlags; + /// Resource fork ID of directory comment if high bit is clear. + public ushort fdComment; + /// Put away folder ID. + public uint fdPutAway; + } + + struct DInfo + { + /// Position and dimensions of the folder's window. + public Rect frRect; + /// Flags. + public FinderFlags frFlags; + /// Folder's location in the parent folder. + public Point frLocation; + /// Finder view selected for folder. + public ushort frView; + } + + struct DXInfo + { + /// Scroll position for icon views. + public Point frScroll; + /// Directory ID chain of open folders. + public uint frOpenChain; + /// Extended flags. If high-bit is set, most significant byte is script code and least significant byte are flags. + public ExtendedFinderFlags frXFlags; + /// Resource fork ID of directory comment if high bit is clear. + public ushort frComment; + /// Put away folder ID. + public uint frPutAway; + } } } \ No newline at end of file diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj index 6c850d72a..c95f4aa9b 100644 --- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj +++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj @@ -60,6 +60,7 @@ +