diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml
index 1ab96201..283708d5 100644
--- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml
+++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml
@@ -509,6 +509,7 @@
+
@@ -824,6 +825,7 @@
+
diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
index d0e1efef..936891b4 100644
--- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
+++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
@@ -41,6 +41,7 @@
+
diff --git a/DiscImageChef.Filesystems/HPOFS.cs b/DiscImageChef.Filesystems/HPOFS.cs
new file mode 100644
index 00000000..49d9a7f8
--- /dev/null
+++ b/DiscImageChef.Filesystems/HPOFS.cs
@@ -0,0 +1,361 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : HPOFS.cs
+// Author(s) : Natalia Portillo
+//
+// Component : High Performance Optical File System plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies the High Performance Optical 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-2018 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using DiscImageChef.CommonTypes;
+using DiscImageChef.Console;
+using DiscImageChef.DiscImages;
+using Schemas;
+
+namespace DiscImageChef.Filesystems
+{
+ // Information from test floppy images created with OS/2 HPOFS 2.0
+ // Need to get IBM document GA32-0224 -> IBM 3995 Optical Library Dataserver Products: Optical Disk Format
+ public class HPOFS : IFilesystem
+ {
+ readonly byte[] hpofsType = {0x48, 0x50, 0x4F, 0x46, 0x53, 0x00, 0x00, 0x00};
+ readonly byte[] medinfoSignature = {0x4D, 0x45, 0x44, 0x49, 0x4E, 0x46, 0x4F, 0x20};
+ readonly byte[] volinfoSignature = {0x56, 0x4F, 0x4C, 0x49, 0x4E, 0x46, 0x4F, 0x20};
+
+ public FileSystemType XmlFsType { get; private set; }
+ public Encoding Encoding { get; private set; }
+ public string Name => "High Performance Optical File System";
+ public Guid Id => new Guid("1b72dcd5-d031-4757-8a9f-8d2fb18c59e2");
+
+ public bool Identify(IMediaImage imagePlugin, Partition partition)
+ {
+ if(16 + partition.Start >= partition.End) return false;
+
+ byte[] hpofsBpbSector =
+ imagePlugin.ReadSector(0 + partition.Start); // Seek to BIOS parameter block, on logical sector 0
+
+ IntPtr bpbPtr = Marshal.AllocHGlobal(512);
+ Marshal.Copy(hpofsBpbSector, 0, bpbPtr, 512);
+ BiosParameterBlock bpb = (BiosParameterBlock)Marshal.PtrToStructure(bpbPtr, typeof(BiosParameterBlock));
+ Marshal.FreeHGlobal(bpbPtr);
+
+ return bpb.fs_type.SequenceEqual(hpofsType);
+ }
+
+ public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
+ Encoding encoding)
+ {
+ Encoding = encoding ?? Encoding.GetEncoding("ibm850");
+ information = "";
+
+ StringBuilder sb = new StringBuilder();
+
+ byte[] hpofsBpbSector =
+ imagePlugin.ReadSector(0 + partition.Start); // Seek to BIOS parameter block, on logical sector 0
+ byte[] medInfoSector =
+ imagePlugin.ReadSector(13 + partition.Start); // Seek to media information block, on logical sector 13
+ byte[] volInfoSector =
+ imagePlugin.ReadSector(14 + partition.Start); // Seek to volume information block, on logical sector 14
+
+ IntPtr bpbPtr = Marshal.AllocHGlobal(512);
+ Marshal.Copy(hpofsBpbSector, 0, bpbPtr, 512);
+ BiosParameterBlock bpb = (BiosParameterBlock)Marshal.PtrToStructure(bpbPtr, typeof(BiosParameterBlock));
+ Marshal.FreeHGlobal(bpbPtr);
+
+ MediaInformationBlock mib =
+ BigEndianMarshal.ByteArrayToStructureBigEndian(medInfoSector);
+ VolumeInformationBlock vib =
+ BigEndianMarshal.ByteArrayToStructureBigEndian(volInfoSector);
+
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.oem_name = \"{0}\"",
+ StringHandlers.CToString(bpb.oem_name));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.bps = {0}", bpb.bps);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.spc = {0}", bpb.spc);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.rsectors = {0}", bpb.rsectors);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.fats_no = {0}", bpb.fats_no);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.root_ent = {0}", bpb.root_ent);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.sectors = {0}", bpb.sectors);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.media = 0x{0:X2}", bpb.media);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.spfat = {0}", bpb.spfat);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.sptrk = {0}", bpb.sptrk);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.heads = {0}", bpb.heads);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.hsectors = {0}", bpb.hsectors);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.big_sectors = {0}", bpb.big_sectors);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.drive_no = 0x{0:X2}", bpb.drive_no);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.nt_flags = {0}", bpb.nt_flags);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.signature = 0x{0:X2}", bpb.signature);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.serial_no = 0x{0:X8}", bpb.serial_no);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.volume_label = \"{0}\"",
+ StringHandlers.SpacePaddedToString(bpb.volume_label));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.fs_type = \"{0}\"", StringHandlers.CToString(bpb.fs_type));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.boot_code is empty? = {0}",
+ ArrayHelpers.ArrayIsNullOrEmpty(bpb.boot_code));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.unknown = {0}", bpb.unknown);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.unknown2 = {0}", bpb.unknown2);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "bpb.signature2 = {0}", bpb.signature2);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.blockId = \"{0}\"", StringHandlers.CToString(mib.blockId));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.volumeLabel = \"{0}\"",
+ StringHandlers.SpacePaddedToString(mib.volumeLabel));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.comment = \"{0}\"",
+ StringHandlers.SpacePaddedToString(mib.comment));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.serial = 0x{0:X8}", mib.serial);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.creationTimestamp = {0}",
+ DateHandlers.DosToDateTime(mib.creationDate, mib.creationTime));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.codepageType = {0}", mib.codepageType);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.codepage = {0}", mib.codepage);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.rps = {0}", mib.rps);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.bps = {0}", mib.bps);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.bpc = {0}", mib.bpc);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown2 = {0}", mib.unknown2);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.sectors = {0}", mib.sectors);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown3 = {0}", mib.unknown3);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown4 = {0}", mib.unknown4);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.major = {0}", mib.major);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.minor = {0}", mib.minor);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown5 = {0}", mib.unknown5);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown6 = {0}", mib.unknown6);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "mib.filler is empty? = {0}",
+ ArrayHelpers.ArrayIsNullOrEmpty(mib.filler));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.blockId = \"{0}\"", StringHandlers.CToString(vib.blockId));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown = {0}", vib.unknown);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown2 = {0}", vib.unknown2);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown3 is empty? = {0}",
+ ArrayHelpers.ArrayIsNullOrEmpty(vib.unknown3));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown4 = \"{0}\"",
+ StringHandlers.SpacePaddedToString(vib.unknown4));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.owner = \"{0}\"",
+ StringHandlers.SpacePaddedToString(vib.owner));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown5 = \"{0}\"",
+ StringHandlers.SpacePaddedToString(vib.unknown5));
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown6 = {0}", vib.unknown6);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.percentFull = {0}", vib.percentFull);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown7 = {0}", vib.unknown7);
+ DicConsole.DebugWriteLine("HPOFS Plugin", "vib.filler is empty? = {0}",
+ ArrayHelpers.ArrayIsNullOrEmpty(vib.filler));
+
+ sb.AppendLine("High Performance Optical File System");
+ sb.AppendFormat("OEM name: {0}", StringHandlers.SpacePaddedToString(bpb.oem_name))
+ .AppendLine();
+ sb.AppendFormat("{0} bytes per sector", bpb.bps).AppendLine();
+ sb.AppendFormat("{0} sectors per cluster", bpb.spc).AppendLine();
+ sb.AppendFormat("Media descriptor: 0x{0:X2}", bpb.media).AppendLine();
+ sb.AppendFormat("{0} sectors per track", bpb.sptrk).AppendLine();
+ sb.AppendFormat("{0} heads", bpb.heads).AppendLine();
+ sb.AppendFormat("{0} sectors hidden before BPB", bpb.hsectors).AppendLine();
+ sb.AppendFormat("{0} sectors on volume ({1} bytes)", mib.sectors, mib.sectors * bpb.bps).AppendLine();
+ sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", bpb.drive_no).AppendLine();
+ sb.AppendFormat("Serial number: 0x{0:X8}", mib.serial).AppendLine();
+ sb.AppendFormat("Volume label: {0}",
+ StringHandlers.SpacePaddedToString(mib.volumeLabel, Encoding))
+ .AppendLine();
+ sb.AppendFormat("Volume comment: {0}", StringHandlers.SpacePaddedToString(mib.comment, Encoding))
+ .AppendLine();
+ sb.AppendFormat("Volume owner: {0}", StringHandlers.SpacePaddedToString(vib.owner, Encoding))
+ .AppendLine();
+ sb.AppendFormat("Volume created on {0}", DateHandlers.DosToDateTime(mib.creationDate, mib.creationTime))
+ .AppendLine();
+ sb.AppendFormat("Volume uses {0} codepage {1}", mib.codepageType > 0 && mib.codepageType < 3
+ ? mib.codepageType == 2
+ ? "EBCDIC"
+ : "ASCII"
+ : "Unknown", mib.codepage).AppendLine();
+ sb.AppendFormat("RPS level: {0}", mib.rps).AppendLine();
+ sb.AppendFormat("Filesystem version: {0}.{1}", mib.major, mib.minor).AppendLine();
+ sb.AppendFormat("Volume can be filled up to {0}%", vib.percentFull).AppendLine();
+
+ XmlFsType = new FileSystemType
+ {
+ Clusters = mib.sectors / bpb.spc,
+ ClusterSize = bpb.bps * bpb.spc,
+ CreationDate = DateHandlers.DosToDateTime(mib.creationDate, mib.creationTime),
+ CreationDateSpecified = true,
+ DataPreparerIdentifier = StringHandlers.SpacePaddedToString(vib.owner, Encoding),
+ Type = "HPOFS",
+ VolumeName = StringHandlers.SpacePaddedToString(mib.volumeLabel, Encoding),
+ VolumeSerial = $"{mib.serial:X8}",
+ SystemIdentifier = StringHandlers.SpacePaddedToString(bpb.oem_name)
+ };
+
+ information = sb.ToString();
+ }
+
+ ///
+ /// BIOS Parameter Block, at sector 0, little-endian
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct BiosParameterBlock
+ {
+ /// 0x000, Jump to boot code
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public byte[] jump;
+ /// 0x003, OEM Name, 8 bytes, space-padded
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] oem_name;
+ /// 0x00B, Bytes per sector
+ public ushort bps;
+ /// 0x00D, Sectors per cluster
+ public byte spc;
+ /// 0x00E, Reserved sectors between BPB and... does it have sense in HPFS?
+ public ushort rsectors;
+ /// 0x010, Number of FATs... seriously?
+ public byte fats_no;
+ /// 0x011, Number of entries on root directory... ok
+ public ushort root_ent;
+ /// 0x013, Sectors in volume... doubt it
+ public ushort sectors;
+ /// 0x015, Media descriptor
+ public byte media;
+ /// 0x016, Sectors per FAT... again
+ public ushort spfat;
+ /// 0x018, Sectors per track... you're kidding
+ public ushort sptrk;
+ /// 0x01A, Heads... stop!
+ public ushort heads;
+ /// 0x01C, Hidden sectors before BPB
+ public uint hsectors;
+ /// 0x024, Sectors in volume if > 65535...
+ public uint big_sectors;
+ /// 0x028, Drive number
+ public byte drive_no;
+ /// 0x029, Volume flags?
+ public byte nt_flags;
+ /// 0x02A, EPB signature, 0x29
+ public byte signature;
+ /// 0x02B, Volume serial number
+ public uint serial_no;
+ /// 0x02F, Volume label, 11 bytes, space-padded
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
+ public byte[] volume_label;
+ /// 0x03A, Filesystem type, 8 bytes, space-padded ("HPFS ")
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] fs_type;
+ /// Boot code.
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 442)]
+ public byte[] boot_code;
+ /// 0x1F8, Unknown
+ public uint unknown;
+ /// 0x1FC, Unknown
+ public ushort unknown2;
+ /// 0x1FE, 0xAA55
+ public ushort signature2;
+ }
+
+ ///
+ /// Media Information Block, at sector 13, big-endian
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct MediaInformationBlock
+ {
+ /// Block identifier "MEDINFO "
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] blockId;
+ /// Volume label
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ public byte[] volumeLabel;
+ /// Volume comment
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 160)]
+ public byte[] comment;
+ /// Volume serial number
+ public uint serial;
+ /// Volume creation date, DOS format
+ public ushort creationDate;
+ /// Volume creation time, DOS format
+ public ushort creationTime;
+ ///
+ /// Codepage type: 1 ASCII, 2 EBCDIC
+ ///
+ public ushort codepageType;
+ /// Codepage
+ public ushort codepage;
+ /// RPS level
+ public uint rps;
+ /// Coincides with bytes per sector, and bytes per cluster, need more media
+ public ushort bps;
+ /// Coincides with bytes per sector, and bytes per cluster, need more media
+ public ushort bpc;
+ /// Unknown, empty
+ public uint unknown2;
+ /// Sectors (or clusters)
+ public uint sectors;
+ /// Unknown, coincides with bps but changing it makes nothing
+ public uint unknown3;
+ /// Empty?
+ public ulong unknown4;
+ /// Format major version
+ public ushort major;
+ /// Format minor version
+ public ushort minor;
+ /// Empty?
+ public uint unknown5;
+ /// Unknown, non-empty
+ public uint unknown6;
+ /// Empty
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)]
+ public byte[] filler;
+ }
+
+ ///
+ /// Volume Information Block, at sector 14, big-endian
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct VolumeInformationBlock
+ {
+ /// Block identifier "VOLINFO "
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] blockId;
+ /// Unknown
+ public uint unknown;
+ /// Unknown
+ public uint unknown2;
+ /// Unknown
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
+ public byte[] unknown3;
+ /// Unknown, space-padded string
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ public byte[] unknown4;
+ /// Owner, space-padded string
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ public byte[] owner;
+ /// Unknown, space-padded string
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ public byte[] unknown5;
+ /// Unknown, empty?
+ public uint unknown6;
+ /// Maximum percent full
+ public ushort percentFull;
+ /// Unknown, empty?
+ public ushort unknown7;
+ /// Empty
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 384)]
+ public byte[] filler;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DiscImageChef.Tests/DiscImageChef.Tests.csproj b/DiscImageChef.Tests/DiscImageChef.Tests.csproj
index 6d343ef8..10efbc40 100644
--- a/DiscImageChef.Tests/DiscImageChef.Tests.csproj
+++ b/DiscImageChef.Tests/DiscImageChef.Tests.csproj
@@ -52,6 +52,7 @@
+
diff --git a/DiscImageChef.Tests/Filesystems/HPOFS.cs b/DiscImageChef.Tests/Filesystems/HPOFS.cs
new file mode 100644
index 00000000..19998412
--- /dev/null
+++ b/DiscImageChef.Tests/Filesystems/HPOFS.cs
@@ -0,0 +1,91 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : HPOFS.cs
+// Author(s) : Natalia Portillo
+//
+// Component : DiscImageChef unit testing.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2018 Natalia Portillo
+// ****************************************************************************/
+
+using System.IO;
+using DiscImageChef.CommonTypes;
+using DiscImageChef.DiscImages;
+using DiscImageChef.Filesystems;
+using DiscImageChef.Filters;
+using NUnit.Framework;
+
+namespace DiscImageChef.Tests.Filesystems
+{
+ [TestFixture]
+ public class Hpofs
+ {
+ readonly string[] testfiles = {"rid1.img.lz", "rid10.img.lz", "rid66percent.img.lz", "rid266.img.lz"};
+
+ readonly MediaType[] mediatypes =
+ {MediaType.DOS_35_HD, MediaType.DOS_35_HD, MediaType.DOS_35_HD, MediaType.DOS_35_HD};
+
+ readonly ulong[] sectors = {2880, 2880, 2880, 2880};
+
+ readonly uint[] sectorsize = {512, 512, 512, 512};
+
+ readonly long[] clusters = {2880, 2880, 2880, 2880};
+
+ readonly int[] clustersize = {512, 512, 512, 512};
+
+ readonly string[] volumename = {"VOLUME LABEL", "VOLUME LABEL", "VOLUME LABEL", "VOLUME LABEL"};
+
+ readonly string[] volumeserial = {"AC226814", "AC160814", "AC306C14", "ABEF2C14"};
+
+ readonly string[] oemid = {"IBM 10.2", "IBM 10.2", "IBM 10.2", "IBM 10.2"};
+
+ [Test]
+ public void Test()
+ {
+ for(int i = 0; i < testfiles.Length; i++)
+ {
+ string location = Path.Combine(Consts.TestFilesRoot, "filesystems", "hpofs", testfiles[i]);
+ IFilter filter = new LZip();
+ filter.Open(location);
+ IMediaImage image = new ZZZRawImage();
+ Assert.AreEqual(true, image.Open(filter), testfiles[i]);
+ Assert.AreEqual(mediatypes[i], image.Info.MediaType, testfiles[i]);
+ Assert.AreEqual(sectors[i], image.Info.Sectors, testfiles[i]);
+ Assert.AreEqual(sectorsize[i], image.Info.SectorSize, testfiles[i]);
+ IFilesystem fs = new HPOFS();
+ Partition wholePart = new Partition
+ {
+ Name = "Whole device",
+ Length = image.Info.Sectors,
+ Size = image.Info.Sectors * image.Info.SectorSize
+ };
+ Assert.AreEqual(true, fs.Identify(image, wholePart), testfiles[i]);
+ fs.GetInformation(image, wholePart, out _, null);
+ Assert.AreEqual(clusters[i], fs.XmlFsType.Clusters, testfiles[i]);
+ Assert.AreEqual(clustersize[i], fs.XmlFsType.ClusterSize, testfiles[i]);
+ Assert.AreEqual("HPOFS", fs.XmlFsType.Type, testfiles[i]);
+ Assert.AreEqual(volumename[i], fs.XmlFsType.VolumeName, testfiles[i]);
+ Assert.AreEqual(volumeserial[i], fs.XmlFsType.VolumeSerial, testfiles[i]);
+ Assert.AreEqual(oemid[i], fs.XmlFsType.SystemIdentifier, testfiles[i]);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 704a25bd..93f6d7e5 100644
--- a/README.md
+++ b/README.md
@@ -162,6 +162,7 @@ Supported file systems for identification and information only
* Flash-Friendly File System (F2FS)
* Fossil file system (from Plan9)
* HAMMER file system
+* High Performance Optical File System (HPOFS)
* High Sierra Format
* HP Logical Interchange Format
* IBM Journaling File System (JFS)