diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/FileSystem/Associations/Apple/HFS/HFSDataFormat.xml b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/FileSystem/Associations/Apple/HFS/HFSDataFormat.xml
new file mode 100644
index 00000000..4ea05f0b
--- /dev/null
+++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/FileSystem/Associations/Apple/HFS/HFSDataFormat.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+ *.hfs
+ *.hfv
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
index 26920841..a5558fcc 100644
--- a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
+++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
@@ -100,6 +100,7 @@
+
@@ -657,10 +658,10 @@
-
+
-
+
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSDataFormat.cs
new file mode 100644
index 00000000..48dd8ce1
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSDataFormat.cs
@@ -0,0 +1,405 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using UniversalEditor.IO;
+
+using UniversalEditor.ObjectModels.FileSystem;
+
+using UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal;
+using UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal.CatalogRecords;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS
+{
+ public class HFSDataFormat : DataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ protected override DataFormatReference MakeReferenceInternal()
+ {
+ if (_dfr == null)
+ {
+ _dfr = base.MakeReferenceInternal();
+ _dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
+ _dfr.ExportOptions.Add(new CustomOptionText("VolumeName", "Volume &name"));
+ _dfr.ExportOptions.Add(new CustomOptionNumber("VolumeBackupSequenceNumber", "&Backup sequence number", 0, Int16.MinValue, Int16.MaxValue));
+ _dfr.ExportOptions.Add(new CustomOptionNumber("VolumeWriteCount", "Volume &write count"));
+ _dfr.Sources.Add("https://developer.apple.com/legacy/library/documentation/mac/Files/Files-102.html");
+ _dfr.Sources.Add("http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/fs/hfs/hfs.h");
+ _dfr.Sources.Add("www.fenestrated.net/~macman/mirrors/Apple Technotes (As of 2002)/tn/tn1150.html");
+ }
+ return _dfr;
+ }
+
+ private string mvarVolumeName = String.Empty;
+ public string VolumeName { get { return mvarVolumeName; } set { mvarVolumeName = value; } }
+
+ private short mvarVolumeBackupSequenceNumber = 0;
+ public short VolumeBackupSequenceNumber { get { return mvarVolumeBackupSequenceNumber; } set { mvarVolumeBackupSequenceNumber = value; } }
+
+ private int mvarVolumeWriteCount = 0;
+ public int VolumeWriteCount { get { return mvarVolumeWriteCount; } set { mvarVolumeWriteCount = value; } }
+
+ private const int LOGICAL_BLOCK_SIZE = 512;
+ public void SeekToLogicalBlock(long index)
+ {
+ long offset = (LOGICAL_BLOCK_SIZE * index);
+ base.Accessor.Seek(offset, IO.SeekOrigin.Begin);
+ }
+
+ protected override void LoadInternal(ref ObjectModel objectModel)
+ {
+ FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
+ if (fsom == null) throw new ObjectModelNotSupportedException();
+
+ Reader reader = base.Accessor.Reader;
+ reader.Seek(0, SeekOrigin.Begin); // debug only, remove when finished
+
+ // let's not forget that Mac OS legacy filesystems are big-endian
+ reader.Endianness = Endianness.BigEndian;
+
+ // Logical blocks 0 and 1 of the volume are the Boot blocks which contain system
+ // startup information. For example, the names of the System and Shell (usually
+ // the Finder) files which are loaded at startup.
+
+ HFSMasterDirectoryBlock _mdb = new HFSMasterDirectoryBlock();
+ #region Master Directory Block
+ {
+ // Logical block 2 contains the Master Directory Block (MDB). This defines a wide
+ // variety of data about the volume itself, for example date & time stamps for when the
+ // volume was created, the location of the other volume structures such as the Volume
+ // Bitmap or the size of logical structures such as allocation blocks. There is also a
+ // duplicate of the MDB called the Alternate Master Directory Block (aka Alternate MDB)
+ // located at the opposite end of the volume in the second to last logical block. This
+ // is intended mainly for use by disk utilities and is only updated when either the
+ // Catalog File or Extents Overflow File grow in size.
+ SeekToLogicalBlock(2);
+
+ byte[] signature = reader.ReadBytes(2);
+ if (signature.Match(new byte[] { 0x42, 0x44 }))
+ {
+ // HFS volume
+ }
+ else if (signature.Match(new byte[] { 0xD2, 0xD7 }))
+ {
+ // obsolete flat MFS volume
+ throw new InvalidDataFormatException("MFS volume not supported yet");
+ }
+ else
+ {
+ throw new InvalidDataFormatException("File does not contain 'BD' at logical block 2");
+ }
+
+ _mdb.creationTimestamp = reader.ReadInt32();
+ _mdb.modificationTimestamp = reader.ReadInt32();
+ _mdb.volumeAttributes = (HFSVolumeAttributes)reader.ReadInt16();
+ _mdb.rootDirectoryFileCount = reader.ReadUInt16();
+ _mdb.volumeBitmapFirstBlockIndex = reader.ReadUInt16();
+ _mdb.nextAllocationSearchStart = reader.ReadInt16();
+ _mdb.allocationBlockCount = reader.ReadUInt16();
+ _mdb.allocationBlockSize = reader.ReadInt32();
+
+ // allocation block sanity check - must be a multiple of 512 bytes
+ if ((_mdb.allocationBlockSize % 512) != 0) throw new InvalidDataFormatException("Allocation block size is not a multiple of 512");
+
+ _mdb.defaultClumpSize = reader.ReadInt32();
+ _mdb.firstAllocationBlockIndex = reader.ReadInt16();
+ _mdb.nextUnusedCatalogNodeID = reader.ReadInt32();
+ _mdb.unusedAllocationBlockCount = reader.ReadUInt16();
+
+ mvarVolumeName = ReadHFSName(reader, 27);
+
+ _mdb.lastBackupTimestamp = reader.ReadInt32();
+ mvarVolumeBackupSequenceNumber = reader.ReadInt16();
+ mvarVolumeWriteCount = reader.ReadInt32();
+ _mdb.clumpSizeForExtentsOverflowFile = reader.ReadInt32();
+ _mdb.clumpSizeForCatalogFile = reader.ReadInt32();
+ _mdb.rootDirectoryDirectoryCount = reader.ReadUInt16();
+ _mdb.totalFileCount = reader.ReadInt32();
+ _mdb.totalDirectoryCount =reader.ReadInt32();
+ _mdb.finderInfo = reader.ReadInt32Array(8); // information used by the Finder
+ _mdb.volumeCacheBlockCount = reader.ReadUInt16();
+ _mdb.volumeBitmapCacheBlockCount = reader.ReadUInt16();
+ _mdb.commonVolumeCacheBlockCount = reader.ReadUInt16();
+
+ // ExtDataRec: ARRAY[3] of ExtDescriptor
+ int extentsOverflowFileSize = reader.ReadInt32();
+ _mdb.extentRecordsForExtentsOverflowFile = ReadHFSExtentDescriptorArray(reader, 3);
+
+ int catalogFileSize = reader.ReadInt32();
+ _mdb.extentRecordsForCatalogFile = ReadHFSExtentDescriptorArray(reader, 3);
+
+ int irgs = _mdb.extentRecordsForCatalogFile[0].firstAllocationBlockIndex;
+ int crgs = _mdb.extentRecordsForCatalogFile[0].allocationBlockCount;
+
+ reader.Seek(13815, SeekOrigin.Begin);
+ HFSCatalogRecord hfscr = ReadHFSCatalogRecord(reader);
+ }
+ #endregion
+
+ #region Volume bitmap
+ {
+ SeekToLogicalBlock(_mdb.volumeBitmapFirstBlockIndex);
+
+ }
+ #endregion
+ #region
+ #endregion
+
+ }
+
+ private string ReadHFSName(Reader reader, int length = 31)
+ {
+ byte nameLength = reader.ReadByte();
+ string name = reader.ReadFixedLengthString(length);
+ if (nameLength < name.Length)
+ {
+ // clip off the rest of the unused characters for the volume name
+ name = name.Substring(0, nameLength);
+ }
+ return name;
+ }
+
+ private HFSCatalogRecord ReadHFSCatalogRecord(Reader reader)
+ {
+ HFSCatalogRecordType type = (HFSCatalogRecordType)reader.ReadInt16();
+
+ switch (type)
+ {
+ case HFSCatalogRecordType.Directory:
+ case HFSCatalogRecordType.ExtendedDirectory:
+ {
+ HFSCatalogDirectoryRecord rec = new HFSCatalogDirectoryRecord();
+ rec.type = type;
+
+ rec.flags = (HFSDirectoryFlags)reader.ReadInt16();
+ if (type == HFSCatalogRecordType.ExtendedDirectory)
+ {
+ rec.directoryValence = reader.ReadInt32();
+ }
+ else
+ {
+ rec.directoryValence = reader.ReadInt16();
+ }
+ rec.directoryID = reader.ReadInt32();
+ rec.creationTimestamp = reader.ReadInt32();
+ if (type == HFSCatalogRecordType.ExtendedDirectory)
+ {
+ rec.modificationTimestamp = reader.ReadInt32();
+ rec.attributeModificationTimestamp = reader.ReadInt32();
+ rec.lastAccessTimestamp = reader.ReadInt32();
+ }
+ else
+ {
+ rec.modificationTimestamp = reader.ReadInt32();
+ }
+ rec.lastBackupTimestamp = reader.ReadInt32();
+ if (type == HFSCatalogRecordType.ExtendedDirectory)
+ {
+ rec.permissions = ReadHFSPlusPermissions(reader);
+ }
+ rec.finderUserInformation = ReadHFSDInfo(reader);
+ rec.finderAdditionalInformation = ReadHFSDXInfo(reader);
+ if (type == HFSCatalogRecordType.ExtendedDirectory)
+ {
+ rec.textEncoding = (HFSPlusTextEncoding)reader.ReadUInt32();
+ uint reserved = reader.ReadUInt32();
+ }
+ else
+ {
+ int[] reserved = reader.ReadInt32Array(4);
+ }
+ return rec;
+ }
+ case HFSCatalogRecordType.ExtendedFile:
+ case HFSCatalogRecordType.File:
+ {
+ HFSCatalogFileRecord rec = new HFSCatalogFileRecord();
+ rec.type = type;
+ if (type == HFSCatalogRecordType.ExtendedFile)
+ {
+ rec.flags = (HFSFileFlags)reader.ReadUInt16();
+ uint reserved1 = reader.ReadUInt32();
+ rec.fileID = reader.ReadInt32();
+ rec.creationTimestamp = reader.ReadInt32();
+ rec.modificationTimestamp = reader.ReadInt32();
+ rec.attributeModificationTimestamp = reader.ReadInt32();
+ rec.lastAccessTimestamp = reader.ReadInt32();
+ rec.lastBackupTimestamp = reader.ReadInt32();
+ rec.permissions = ReadHFSPlusPermissions(reader);
+
+ rec.finderUserInformation = ReadHFSFInfo(reader);
+ rec.finderAdditionalInformation = ReadHFSFXInfo(reader);
+
+ rec.textEncoding = (HFSPlusTextEncoding)reader.ReadUInt32();
+ uint reserved2 = reader.ReadUInt32();
+
+ rec.dataFork = ReadHFSPlusForkData(reader);
+ rec.resourceFork = ReadHFSPlusForkData(reader);
+ }
+ else
+ {
+ rec.flags = (HFSFileFlags)reader.ReadSByte();
+ rec.fileType = reader.ReadSByte();
+ rec.finderUserInformation = ReadHFSFInfo(reader);
+ rec.fileID = reader.ReadInt32();
+ rec.dataForkFirstAllocationBlock = reader.ReadInt16();
+ rec.dataForkLogicalEOF = reader.ReadInt32();
+ rec.dataForkPhysicalEOF = reader.ReadInt32();
+ rec.resourceForkFirstAllocationBlock = reader.ReadInt16();
+ rec.resourceForkLogicalEOF = reader.ReadInt32();
+ rec.resourceForkPhysicalEOF = reader.ReadInt32();
+ rec.creationTimestamp = reader.ReadInt32();
+ rec.modificationTimestamp = reader.ReadInt32();
+ rec.lastBackupTimestamp = reader.ReadInt32();
+ rec.finderAdditionalInformation = ReadHFSFXInfo(reader);
+ rec.fileClumpSize = reader.ReadInt16();
+ rec.firstDataForkExtentRecord = ReadHFSExtentDescriptorArray(reader, 3);
+ rec.firstResourceForkExtentRecord = ReadHFSExtentDescriptorArray(reader, 3);
+ rec.reserved2 = reader.ReadInt32();
+ }
+ return rec;
+ }
+ case HFSCatalogRecordType.DirectoryThread:
+ {
+ HFSCatalogDirectoryThreadRecord rec = new HFSCatalogDirectoryThreadRecord();
+ rec.type = type;
+ rec.reserved2 = reader.ReadInt32Array(2);
+ rec.parentID = reader.ReadInt32();
+
+ rec.fileName = ReadHFSName(reader);
+ return rec;
+ }
+ case HFSCatalogRecordType.FileThread:
+ {
+ HFSCatalogFileThreadRecord rec = new HFSCatalogFileThreadRecord();
+ rec.type = type;
+ rec.reserved2 = reader.ReadInt32Array(2);
+ rec.parentID = reader.ReadInt32();
+
+ byte fileNameLength = reader.ReadByte();
+ rec.fileName = reader.ReadFixedLengthString(fileNameLength);
+ return rec;
+ }
+ }
+ return null;
+ }
+
+ private HFSPlusForkData ReadHFSPlusForkData(Reader reader)
+ {
+ HFSPlusForkData item = new HFSPlusForkData();
+ item.logicalSize = reader.ReadUInt64();
+ item.clumpSize = reader.ReadUInt32();
+ item.totalBlocks = reader.ReadUInt32();
+ item.extents = ReadHFSPlusExtentRecord(reader);
+ return item;
+ }
+
+ private HFSPlusExtentDescriptor[] ReadHFSPlusExtentRecord(Reader reader)
+ {
+ HFSPlusExtentDescriptor[] item = new HFSPlusExtentDescriptor[8];
+ for (int i = 0; i < 8; i++)
+ {
+ item[i] = ReadHFSPlusExtentDescriptor(reader);
+ }
+ return item;
+ }
+
+ private HFSPlusExtentDescriptor ReadHFSPlusExtentDescriptor(Reader reader)
+ {
+ HFSPlusExtentDescriptor item = new HFSPlusExtentDescriptor();
+ item.startBlock = reader.ReadUInt32();
+ item.blockCount = reader.ReadUInt32();
+ return item;
+ }
+
+ private HFSPlusPermissions ReadHFSPlusPermissions(Reader reader)
+ {
+ HFSPlusPermissions item = new HFSPlusPermissions();
+ item.ownerID = reader.ReadUInt32();
+ item.groupID = reader.ReadUInt32();
+ item.permissions = reader.ReadUInt32();
+ item.specialDevice = reader.ReadUInt32();
+ return item;
+ }
+
+ private HFSDInfo ReadHFSDInfo(Reader reader)
+ {
+ HFSDInfo item = new HFSDInfo();
+ item.rect = ReadHFSRect(reader);
+ item.flags = (HFSDInfoFlags)reader.ReadInt16();
+ item.location = ReadHFSPoint(reader);
+ item.view = reader.ReadInt16();
+ return item;
+ }
+ private HFSDXInfo ReadHFSDXInfo(Reader reader)
+ {
+ HFSDXInfo item = new HFSDXInfo();
+ item.scroll = ReadHFSPoint(reader);
+ item.openChain = reader.ReadInt32();
+ item.reserved = reader.ReadInt16();
+ item.comment = reader.ReadInt16();
+ item.putAway = reader.ReadInt32();
+ return item;
+ }
+
+ private HFSFInfo ReadHFSFInfo(Reader reader)
+ {
+ HFSFInfo item = new HFSFInfo();
+ item.type = reader.ReadFixedLengthString(4);
+ item.creator = reader.ReadFixedLengthString(4);
+ item.fdFlags = (HFSFInfoFlags)reader.ReadInt16();
+ item.location = ReadHFSPoint(reader);
+ item.parentFolderID = reader.ReadInt16();
+ return item;
+ }
+ private HFSFXInfo ReadHFSFXInfo(Reader reader)
+ {
+ HFSFXInfo item = new HFSFXInfo();
+ item.iconID = reader.ReadInt16();
+ item.reserved = reader.ReadBytes(8);
+ item.comment = reader.ReadInt16();
+ item.putAway = reader.ReadInt32();
+ return item;
+ }
+
+ private HFSRect ReadHFSRect(Reader reader)
+ {
+ HFSRect item = new HFSRect();
+ item.top = reader.ReadInt16();
+ item.bottom = reader.ReadInt16();
+ item.left = reader.ReadInt16();
+ item.right = reader.ReadInt16();
+ return item;
+ }
+ private HFSPoint ReadHFSPoint(Reader reader)
+ {
+ HFSPoint item = new HFSPoint();
+ item.x = reader.ReadInt16();
+ item.y = reader.ReadInt16();
+ return item;
+ }
+
+ private HFSExtentDescriptor[] ReadHFSExtentDescriptorArray(Reader reader, int count)
+ {
+ HFSExtentDescriptor[] items = new HFSExtentDescriptor[count];
+ for (int i = 0; i < count; i++)
+ {
+ items[i] = ReadHFSExtentDescriptor(reader);
+ }
+ return items;
+ }
+ private HFSExtentDescriptor ReadHFSExtentDescriptor(Reader reader)
+ {
+ HFSExtentDescriptor item = new HFSExtentDescriptor();
+ item.firstAllocationBlockIndex = reader.ReadInt16();
+ item.allocationBlockCount = reader.ReadInt16();
+ return item;
+ }
+
+ protected override void SaveInternal(ObjectModel objectModel)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSDirectoryFlags.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSDirectoryFlags.cs
new file mode 100644
index 00000000..13e04d17
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSDirectoryFlags.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS
+{
+ public enum HFSDirectoryFlags : short
+ {
+ None = 0
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSExtentDescriptor.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSExtentDescriptor.cs
new file mode 100644
index 00000000..439b543a
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSExtentDescriptor.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS
+{
+ public struct HFSExtentDescriptor
+ {
+ public short firstAllocationBlockIndex;
+ public short allocationBlockCount;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSFileFlags.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSFileFlags.cs
new file mode 100644
index 00000000..9f063f8f
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSFileFlags.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS
+{
+ [Flags()]
+ public enum HFSFileFlags : short
+ {
+ None = 0x00,
+ ///
+ /// If set, this file is locked and cannot be written to.
+ ///
+ Locked = 0x01,
+ ///
+ /// If set, a file thread record exists for this file.
+ ///
+ ThreadRecordExists = 0x02,
+ ///
+ /// If set, the file record is used.
+ ///
+ Used = 0x40
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSPlusTextEncoding.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSPlusTextEncoding.cs
new file mode 100644
index 00000000..79078ab0
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSPlusTextEncoding.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS
+{
+ public enum HFSPlusTextEncoding
+ {
+ MacRoman = 0,
+ MacJapanese = 1,
+ MacChineseTraditional = 2,
+ MacKorean = 3,
+ MacArabic = 4,
+ MacHebrew = 5,
+ MacGreek = 6,
+ MacCyrillic = 7,
+ MacDevanagari = 9,
+ MacGurmukhi = 10,
+ MacGujarati = 11,
+ MacOriya = 12,
+ MacBengali = 13,
+ MacTamil = 14,
+ MacTelugu = 15,
+ MacKannada = 16,
+ MacMalayalam = 17,
+ MacSinhalese = 18,
+ MacBurmese = 19,
+ MacKhmer = 20,
+ MacThai = 21,
+ MacLaotian = 22,
+ MacGeorgian = 23,
+ MacArmenian = 24,
+ MacChineseSimplified = 25,
+ MacTibetan = 26,
+ MacMongolian = 27,
+ MacEthiopic = 28,
+ MacCentralEurRoman = 29,
+ MacVietnamese = 30,
+ MacExtArabic = 31,
+ MacSymbol = 33,
+ MacDingbats = 34,
+ MacTurkish = 35,
+ MacCroatian = 36,
+ MacIcelandic = 37,
+ MacRomanian = 38,
+ MacFarsi49 = 49,
+ MacFarsi140 = 140,
+ MacUkrainian48 = 48,
+ MacUkrainian152 = 152
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSVolumeAttributes.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSVolumeAttributes.cs
new file mode 100644
index 00000000..52b149f1
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/HFSVolumeAttributes.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS
+{
+ [Flags()]
+ public enum HFSVolumeAttributes : short
+ {
+ ///
+ /// Set if the volume is locked by hardware
+ ///
+ HardwareLocked = 0x0040,
+ ///
+ /// Set if the volume was successfully unmounted
+ ///
+ SuccessfullyUnmounted = 0x0080,
+ ///
+ /// Set if the volume has had its bad blocks spared
+ ///
+ BadBlocksSpared = 0x0100,
+ ///
+ /// Set if the volume is locked by software
+ ///
+ SoftwareLocked = 0x0400
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogDirectoryRecord.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogDirectoryRecord.cs
new file mode 100644
index 00000000..66294a8e
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogDirectoryRecord.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal.CatalogRecords
+{
+ internal class HFSCatalogDirectoryRecord : HFSCatalogRecord
+ {
+ ///
+ /// Directory flags.
+ ///
+ public HFSDirectoryFlags flags;
+ ///
+ /// The directory valence (the number of files and folders directly contained by this
+ /// folder). This is equal to the number of file and folder records whose key's parentID is
+ /// equal to this folder's folderID.
+ ///
+ ///
+ /// The current Mac OS File Manager programming interfaces require folders to have a valence
+ /// less than 32,767. An implementation must enforce this restriction if it wants the volume
+ /// to be usable by Mac OS. Values of 32,768 and larger are problematic; 32,767 and smaller
+ /// are OK. It's an implementation restriction for the older Mac OS APIs; items 32,768 and
+ /// beyond would be unreachable by PBGetCatInfo. As a practical matter, many programs are
+ /// likely to fails with anywhere near that many items in a single folder. So, the volume
+ /// format allows more than 32,767 items in a folder, but it's probably not a good idea to
+ /// exceed that limit right now.
+ ///
+ public int directoryValence;
+ ///
+ /// The directory ID.
+ ///
+ public int directoryID;
+ ///
+ /// The date and time this directory was created.
+ ///
+ public int creationTimestamp;
+ ///
+ /// The date and time this directory was last modified.
+ ///
+ public int modificationTimestamp;
+ ///
+ /// HFS+ only. The date and time at which a named fork of this directory was last modified.
+ ///
+ public int attributeModificationTimestamp;
+ ///
+ /// HFS+ only.
+ ///
+ public int lastAccessTimestamp;
+ ///
+ /// The date and time this directory was last backed up.
+ ///
+ public int lastBackupTimestamp;
+ public HFSPlusPermissions permissions;
+ ///
+ /// Information used by the Finder.
+ ///
+ public HFSDInfo finderUserInformation;
+ ///
+ /// Additional information used by the Finder.
+ ///
+ public HFSDXInfo finderAdditionalInformation;
+ public HFSPlusTextEncoding textEncoding;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogDirectoryThreadRecord.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogDirectoryThreadRecord.cs
new file mode 100644
index 00000000..30427a6c
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogDirectoryThreadRecord.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal.CatalogRecords
+{
+ internal class HFSCatalogDirectoryThreadRecord : HFSCatalogRecord
+ {
+ public int[/*2*/] reserved2;
+ ///
+ /// Parent ID for this directory.
+ ///
+ public int parentID;
+ ///
+ /// File name of this directory.
+ ///
+ public string fileName;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogFileRecord.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogFileRecord.cs
new file mode 100644
index 00000000..a28b0785
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogFileRecord.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal.CatalogRecords
+{
+ internal class HFSCatalogFileRecord : HFSCatalogRecord
+ {
+ ///
+ /// File flags.
+ ///
+ public HFSFileFlags flags;
+ ///
+ /// The file type. This field should always contain 0.
+ ///
+ public sbyte fileType;
+ ///
+ /// The file's Finder information.
+ ///
+ public HFSFInfo finderUserInformation;
+ ///
+ /// The file ID.
+ ///
+ public int fileID;
+ ///
+ /// The first allocation block of the data fork.
+ ///
+ public short dataForkFirstAllocationBlock;
+ ///
+ /// The logical EOF of the data fork.
+ ///
+ public int dataForkLogicalEOF;
+ ///
+ /// The physical EOF of the data fork.
+ ///
+ public int dataForkPhysicalEOF;
+ ///
+ /// The first allocation block of the resource fork.
+ ///
+ public short resourceForkFirstAllocationBlock;
+ ///
+ /// The logical EOF of the resource fork.
+ ///
+ public int resourceForkLogicalEOF;
+ ///
+ /// The physical EOF of the resource fork.
+ ///
+ public int resourceForkPhysicalEOF;
+ ///
+ /// The date and time this file was created.
+ ///
+ public int creationTimestamp;
+ ///
+ /// The date and time this file was last modified.
+ ///
+ public int modificationTimestamp;
+ ///
+ /// HFS+ only
+ ///
+ public int attributeModificationTimestamp;
+ ///
+ /// HFS+ only
+ ///
+ public int lastAccessTimestamp;
+ ///
+ /// The date and time this file was last backed up.
+ ///
+ public int lastBackupTimestamp;
+ ///
+ /// HFS+ only
+ ///
+ public HFSPlusPermissions permissions;
+ ///
+ /// Additional information used by the Finder.
+ ///
+ public HFSFXInfo finderAdditionalInformation;
+ ///
+ /// HFS+ only
+ ///
+ public HFSPlusTextEncoding textEncoding;
+ ///
+ /// The file clump size.
+ ///
+ public short fileClumpSize;
+ ///
+ /// The first extent record of the file's data fork.
+ ///
+ public HFSExtentDescriptor[] firstDataForkExtentRecord;
+ ///
+ /// The first extent record of the file's resource fork.
+ ///
+ public HFSExtentDescriptor[] firstResourceForkExtentRecord;
+ ///
+ /// Reserved.
+ ///
+ public int reserved2;
+
+ ///
+ /// HFS+ only
+ ///
+ public HFSPlusForkData dataFork;
+ ///
+ /// HFS+ only
+ ///
+ public HFSPlusForkData resourceFork;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogFileThreadRecord.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogFileThreadRecord.cs
new file mode 100644
index 00000000..6d078e44
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/CatalogRecords/HFSCatalogFileThreadRecord.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal.CatalogRecords
+{
+ internal class HFSCatalogFileThreadRecord : HFSCatalogRecord
+ {
+ public int[/*2*/] reserved2;
+ ///
+ /// Parent ID for this file.
+ ///
+ public int parentID;
+ ///
+ /// File name of this file.
+ ///
+ public string fileName;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSCatalogRecord.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSCatalogRecord.cs
new file mode 100644
index 00000000..1ad0db66
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSCatalogRecord.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal enum HFSCatalogRecordType : short
+ {
+ ///
+ /// HFS+ folder record
+ ///
+ ExtendedDirectory = 0x0001,
+ ///
+ /// HFS+ file record
+ ///
+ ExtendedFile = 0x0002,
+ ///
+ /// HFS+ folder thread record
+ ///
+ ExtendedDirectoryThread = 0x0003,
+ ///
+ /// HFS+ file thread record
+ ///
+ ExtendedFileThread = 0x0004,
+ ///
+ /// HFS folder record
+ ///
+ Directory = 0x0100,
+ ///
+ /// HFS file record
+ ///
+ File = 0x0200,
+ ///
+ /// HFS folder thread record
+ ///
+ DirectoryThread = 0x0300,
+ ///
+ /// HFS file thread record
+ ///
+ FileThread = 0x0400
+ }
+ internal class HFSCatalogRecord
+ {
+ public HFSCatalogRecordType type;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSDInfo.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSDInfo.cs
new file mode 100644
index 00000000..ebfae974
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSDInfo.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal enum HFSDInfoFlags : short
+ {
+ Inited = 0x0100,
+ Locked = 0x1000,
+ Invisible = 0x4000
+ }
+ internal struct HFSDInfo
+ {
+ // hfs_finfo
+ public HFSRect rect;
+ public HFSDInfoFlags flags;
+ public HFSPoint location;
+ public short view;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSDXInfo.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSDXInfo.cs
new file mode 100644
index 00000000..42079b6a
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSDXInfo.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal struct HFSDXInfo
+ {
+ public HFSPoint scroll;
+ public int openChain;
+ public short reserved;
+ public short comment;
+ public int putAway;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSFInfo.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSFInfo.cs
new file mode 100644
index 00000000..a41c7d9d
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSFInfo.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal enum HFSFInfoFlags : short
+ {
+ Inited = 0x0100,
+ Locked = 0x1000,
+ Invisible = 0x4000
+ }
+ internal struct HFSFInfo
+ {
+ // hfs_finfo
+ public string type;
+ public string creator;
+ public HFSFInfoFlags fdFlags;
+ public HFSPoint location;
+ public short parentFolderID;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSFXInfo.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSFXInfo.cs
new file mode 100644
index 00000000..b684ac6c
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSFXInfo.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal struct HFSFXInfo
+ {
+ public short iconID;
+ public byte[] reserved;
+ public short comment;
+ public int putAway;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSMasterDirectoryBlock.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSMasterDirectoryBlock.cs
new file mode 100644
index 00000000..df33213d
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSMasterDirectoryBlock.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS
+{
+ internal struct HFSMasterDirectoryBlock
+ {
+ public int creationTimestamp;
+ public int modificationTimestamp;
+ public HFSVolumeAttributes volumeAttributes;
+ public ushort rootDirectoryFileCount;
+ public ushort volumeBitmapFirstBlockIndex;
+ public short nextAllocationSearchStart;
+ public ushort allocationBlockCount;
+ public int allocationBlockSize;
+ public int defaultClumpSize;
+ public short firstAllocationBlockIndex;
+ public int nextUnusedCatalogNodeID;
+ public ushort unusedAllocationBlockCount;
+ public int lastBackupTimestamp;
+ public int clumpSizeForExtentsOverflowFile;
+ public int clumpSizeForCatalogFile;
+ public ushort rootDirectoryDirectoryCount;
+ public int totalFileCount;
+ public int totalDirectoryCount;
+ public int[] finderInfo;
+ public ushort volumeCacheBlockCount;
+ public ushort volumeBitmapCacheBlockCount;
+ public ushort commonVolumeCacheBlockCount;
+ public HFSExtentDescriptor[] extentRecordsForExtentsOverflowFile;
+ public HFSExtentDescriptor[] extentRecordsForCatalogFile;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusExtentDescriptor.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusExtentDescriptor.cs
new file mode 100644
index 00000000..cf757096
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusExtentDescriptor.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal struct HFSPlusExtentDescriptor
+ {
+ public uint startBlock;
+ public uint blockCount;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusForkData.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusForkData.cs
new file mode 100644
index 00000000..386076cf
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusForkData.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal struct HFSPlusForkData
+ {
+ public ulong logicalSize;
+ public uint clumpSize;
+ public uint totalBlocks;
+ public HFSPlusExtentDescriptor[] extents;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusPermissions.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusPermissions.cs
new file mode 100644
index 00000000..3829dd05
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPlusPermissions.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal struct HFSPlusPermissions
+ {
+ public uint ownerID;
+ public uint groupID;
+ public uint permissions;
+ public uint specialDevice;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPoint.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPoint.cs
new file mode 100644
index 00000000..8c262c8e
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSPoint.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal struct HFSPoint
+ {
+ public short x;
+ public short y;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSRect.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSRect.cs
new file mode 100644
index 00000000..c0283021
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/Apple/HFS/Internal/HFSRect.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.FileSystem.Apple.HFS.Internal
+{
+ internal struct HFSRect
+ {
+ public short top;
+ public short bottom;
+ public short left;
+ public short right;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj
index 19b596e1..5b4381b6 100644
--- a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/UniversalEditor.Plugins.FileSystem.csproj
@@ -44,6 +44,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+