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 @@
+