From 7ac5e40965c7c92168d942243fcf7a2ac9643216 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Wed, 19 Feb 2020 00:12:15 +0000 Subject: [PATCH] Move common Apple boot block information and structs to its own class. --- .../.idea/contentModel.xml | 5 + .../AppleCommon/Consts.cs | 42 ++++++++ DiscImageChef.Filesystems/AppleCommon/Info.cs | 99 +++++++++++++++++++ .../AppleCommon/Structs.cs | 92 +++++++++++++++++ DiscImageChef.Filesystems/AppleHFS/Consts.cs | 2 - DiscImageChef.Filesystems/AppleHFS/Info.cs | 49 +-------- DiscImageChef.Filesystems/AppleHFS/Structs.cs | 51 ---------- DiscImageChef.Filesystems/AppleMFS/Consts.cs | 2 - DiscImageChef.Filesystems/AppleMFS/Info.cs | 69 +------------ DiscImageChef.Filesystems/AppleMFS/Structs.cs | 39 -------- DiscImageChef.Filesystems/AppleMFS/Super.cs | 84 +++++++++++----- .../DiscImageChef.Filesystems.csproj | 3 + 12 files changed, 309 insertions(+), 228 deletions(-) create mode 100644 DiscImageChef.Filesystems/AppleCommon/Consts.cs create mode 100644 DiscImageChef.Filesystems/AppleCommon/Info.cs create mode 100644 DiscImageChef.Filesystems/AppleCommon/Structs.cs diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml index a70108dd6..062826aa8 100644 --- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml +++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml @@ -1308,6 +1308,11 @@ + + + + + diff --git a/DiscImageChef.Filesystems/AppleCommon/Consts.cs b/DiscImageChef.Filesystems/AppleCommon/Consts.cs new file mode 100644 index 000000000..dab9253d9 --- /dev/null +++ b/DiscImageChef.Filesystems/AppleCommon/Consts.cs @@ -0,0 +1,42 @@ +// /*************************************************************************** +// 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 +// ****************************************************************************/ + +namespace DiscImageChef.Filesystems +{ + // Information from Inside Macintosh + // https://developer.apple.com/legacy/library/documentation/mac/pdf/Files/File_Manager.pdf + internal static partial class AppleCommon + { + /// "LK", HFS bootblock magic + internal const ushort BB_MAGIC = 0x4C4B; + } +} \ No newline at end of file diff --git a/DiscImageChef.Filesystems/AppleCommon/Info.cs b/DiscImageChef.Filesystems/AppleCommon/Info.cs new file mode 100644 index 000000000..faa0e3fe9 --- /dev/null +++ b/DiscImageChef.Filesystems/AppleCommon/Info.cs @@ -0,0 +1,99 @@ +// /*************************************************************************** +// 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.Text; +using DiscImageChef.Helpers; + +namespace DiscImageChef.Filesystems +{ + // Information from Inside Macintosh + // https://developer.apple.com/legacy/library/documentation/mac/pdf/Files/File_Manager.pdf + internal static partial class AppleCommon + { + internal static string GetBootBlockInformation(byte[] bbSector, Encoding Encoding) + { + if(bbSector is null || + bbSector.Length < 0x100) + return null; + + BootBlock bb = Marshal.ByteArrayToStructureBigEndian(bbSector); + + if(bb.bbID != BB_MAGIC) + return null; + + var sb = new StringBuilder(); + sb.AppendLine("Boot Block:"); + + if((bb.bbPageFlags & 0x40) == 0x40) + sb.AppendLine("Boot block should be executed."); + + if((bb.bbPageFlags & 0x80) == 0x80) + sb.AppendLine("Boot block is in new unknown format."); + else + { + if(bb.bbPageFlags > 0) + sb.AppendLine("Allocate secondary sound buffer at boot."); + else if(bb.bbPageFlags < 0) + sb.AppendLine("Allocate secondary sound and video buffers at boot."); + + sb.AppendFormat("System filename: {0}", StringHandlers.PascalToString(bb.bbSysName, Encoding)). + AppendLine(); + + sb.AppendFormat("Finder filename: {0}", StringHandlers.PascalToString(bb.bbShellName, Encoding)). + AppendLine(); + + sb.AppendFormat("Debugger filename: {0}", StringHandlers.PascalToString(bb.bbDbg1Name, Encoding)). + AppendLine(); + + sb.AppendFormat("Disassembler filename: {0}", StringHandlers.PascalToString(bb.bbDbg2Name, Encoding)). + AppendLine(); + + sb.AppendFormat("Startup screen filename: {0}", + StringHandlers.PascalToString(bb.bbScreenName, Encoding)).AppendLine(); + + sb.AppendFormat("First program to execute at boot: {0}", + StringHandlers.PascalToString(bb.bbHelloName, Encoding)).AppendLine(); + + sb.AppendFormat("Clipboard filename: {0}", StringHandlers.PascalToString(bb.bbScrapName, Encoding)). + AppendLine(); + + sb.AppendFormat("Maximum opened files: {0}", bb.bbCntFCBs * 4).AppendLine(); + sb.AppendFormat("Event queue size: {0}", bb.bbCntEvts).AppendLine(); + sb.AppendFormat("Heap size with 128KiB of RAM: {0} bytes", bb.bb128KSHeap).AppendLine(); + sb.AppendFormat("Heap size with 256KiB of RAM: {0} bytes", bb.bb256KSHeap).AppendLine(); + sb.AppendFormat("Heap size with 512KiB of RAM or more: {0} bytes", bb.bbSysHeapSize).AppendLine(); + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/DiscImageChef.Filesystems/AppleCommon/Structs.cs b/DiscImageChef.Filesystems/AppleCommon/Structs.cs new file mode 100644 index 000000000..9d125bfba --- /dev/null +++ b/DiscImageChef.Filesystems/AppleCommon/Structs.cs @@ -0,0 +1,92 @@ +// /*************************************************************************** +// 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.Runtime.InteropServices; + +namespace DiscImageChef.Filesystems +{ + // Information from Inside Macintosh + // https://developer.apple.com/legacy/library/documentation/mac/pdf/Files/File_Manager.pdf + internal static partial class AppleCommon + { + /// Should be sectors 0 and 1 in volume, followed by boot code + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct BootBlock // Should be sectors 0 and 1 in volume + { + /// 0x000, Signature, 0x4C4B if bootable + public readonly ushort bbID; + /// 0x002, Branch + public readonly uint bbEntry; + /// 0x007, Boot block version + public readonly ushort bbVersion; + /// 0x006, Boot block flags + public readonly short bbPageFlags; + /// 0x00A, System file name (16 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public readonly byte[] bbSysName; + /// 0x01A, Finder file name (16 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public readonly byte[] bbShellName; + /// 0x02A, Debugger file name (16 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public readonly byte[] bbDbg1Name; + /// 0x03A, Disassembler file name (16 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public readonly byte[] bbDbg2Name; + /// 0x04A, Startup screen file name (16 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public readonly byte[] bbScreenName; + /// 0x05A, First program to execute on boot (16 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public readonly byte[] bbHelloName; + /// 0x06A, Clipboard file name (16 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public readonly byte[] bbScrapName; + /// 0x07A, 1/4 of maximum opened at a time files + public readonly ushort bbCntFCBs; + /// 0x07C, Event queue size + public readonly ushort bbCntEvts; + /// 0x07E, Heap size on a Mac with 128KiB of RAM + public readonly uint bb128KSHeap; + /// 0x082, Heap size on a Mac with 256KiB of RAM + public readonly uint bb256KSHeap; + /// 0x086, Heap size on a Mac with 512KiB of RAM or more + public readonly uint bbSysHeapSize; + /// 0x08A, Padding + public readonly ushort filler; + /// 0x08C, Additional system heap space + public readonly uint bbSysHeapExtra; + /// 0x090, Fraction of RAM for system heap + public readonly uint bbSysHeapFract; + } + } +} \ No newline at end of file diff --git a/DiscImageChef.Filesystems/AppleHFS/Consts.cs b/DiscImageChef.Filesystems/AppleHFS/Consts.cs index 028e7cc64..412a3a645 100644 --- a/DiscImageChef.Filesystems/AppleHFS/Consts.cs +++ b/DiscImageChef.Filesystems/AppleHFS/Consts.cs @@ -40,7 +40,5 @@ namespace DiscImageChef.Filesystems const ushort HFS_MAGIC = 0x4244; /// "H+", HFS+ magic const ushort HFSP_MAGIC = 0x482B; - /// "LK", HFS bootblock magic - const ushort HFSBB_MAGIC = 0x4C4B; } } \ No newline at end of file diff --git a/DiscImageChef.Filesystems/AppleHFS/Info.cs b/DiscImageChef.Filesystems/AppleHFS/Info.cs index ca21a51b8..7f9f1ab09 100644 --- a/DiscImageChef.Filesystems/AppleHFS/Info.cs +++ b/DiscImageChef.Filesystems/AppleHFS/Info.cs @@ -146,7 +146,6 @@ namespace DiscImageChef.Filesystems } HfsMasterDirectoryBlock mdb = Marshal.ByteArrayToStructureBigEndian(mdbSector); - HfsBootBlock bb = Marshal.ByteArrayToStructureBigEndian(bbSector); sb.AppendLine("Apple Hierarchical File System"); sb.AppendLine(); @@ -238,51 +237,13 @@ namespace DiscImageChef.Filesystems sb.AppendFormat("{0} blocks in volume common cache", mdb.drCtlCSize).AppendLine(); } - if(bb.bbID == HFSBB_MAGIC) + string bootBlockInfo = AppleCommon.GetBootBlockInformation(bbSector, Encoding); + + if(bootBlockInfo != null) { sb.AppendLine("Volume is bootable."); sb.AppendLine(); - sb.AppendLine("Boot Block:"); - - if((bb.bbPageFlags & 0x40) == 0x40) - sb.AppendLine("Boot block should be executed."); - - if((bb.bbPageFlags & 0x80) == 0x80) - sb.AppendLine("Boot block is in new unknown format."); - else - { - if(bb.bbPageFlags > 0) - sb.AppendLine("Allocate secondary sound buffer at boot."); - else if(bb.bbPageFlags < 0) - sb.AppendLine("Allocate secondary sound and video buffers at boot."); - - sb.AppendFormat("System filename: {0}", StringHandlers.PascalToString(bb.bbSysName, Encoding)). - AppendLine(); - - sb.AppendFormat("Finder filename: {0}", StringHandlers.PascalToString(bb.bbShellName, Encoding)). - AppendLine(); - - sb.AppendFormat("Debugger filename: {0}", StringHandlers.PascalToString(bb.bbDbg1Name, Encoding)). - AppendLine(); - - sb.AppendFormat("Disassembler filename: {0}", - StringHandlers.PascalToString(bb.bbDbg2Name, Encoding)).AppendLine(); - - sb.AppendFormat("Startup screen filename: {0}", - StringHandlers.PascalToString(bb.bbScreenName, Encoding)).AppendLine(); - - sb.AppendFormat("First program to execute at boot: {0}", - StringHandlers.PascalToString(bb.bbHelloName, Encoding)).AppendLine(); - - sb.AppendFormat("Clipboard filename: {0}", StringHandlers.PascalToString(bb.bbScrapName, Encoding)). - AppendLine(); - - sb.AppendFormat("Maximum opened files: {0}", bb.bbCntFCBs * 4).AppendLine(); - sb.AppendFormat("Event queue size: {0}", bb.bbCntEvts).AppendLine(); - sb.AppendFormat("Heap size with 128KiB of RAM: {0} bytes", bb.bb128KSHeap).AppendLine(); - sb.AppendFormat("Heap size with 256KiB of RAM: {0} bytes", bb.bb256KSHeap).AppendLine(); - sb.AppendFormat("Heap size with 512KiB of RAM or more: {0} bytes", bb.bbSysHeapSize).AppendLine(); - } + sb.AppendLine(bootBlockInfo); } else if(mdb.drFndrInfo0 != 0 || mdb.drFndrInfo3 != 0 || @@ -301,7 +262,7 @@ namespace DiscImageChef.Filesystems XmlFsType.BackupDateSpecified = true; } - XmlFsType.Bootable = bb.bbID == HFSBB_MAGIC || mdb.drFndrInfo0 != 0 || mdb.drFndrInfo3 != 0 || + XmlFsType.Bootable = bootBlockInfo != null || mdb.drFndrInfo0 != 0 || mdb.drFndrInfo3 != 0 || mdb.drFndrInfo5 != 0; XmlFsType.Clusters = mdb.drNmAlBlks; diff --git a/DiscImageChef.Filesystems/AppleHFS/Structs.cs b/DiscImageChef.Filesystems/AppleHFS/Structs.cs index ecd9f6f21..d12433c9b 100644 --- a/DiscImageChef.Filesystems/AppleHFS/Structs.cs +++ b/DiscImageChef.Filesystems/AppleHFS/Structs.cs @@ -38,57 +38,6 @@ namespace DiscImageChef.Filesystems // https://developer.apple.com/legacy/library/documentation/mac/pdf/Files/File_Manager.pdf public partial class AppleHFS { - /// Should be sectors 0 and 1 in volume, followed by boot code - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct HfsBootBlock // Should be sectors 0 and 1 in volume - { - /// 0x000, Signature, 0x4C4B if bootable - public readonly ushort bbID; - /// 0x002, Branch - public readonly uint bbEntry; - /// 0x007, Boot block version - public readonly ushort bbVersion; - /// 0x006, Boot block flags - public readonly short bbPageFlags; - /// 0x00A, System file name (16 bytes) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public readonly byte[] bbSysName; - /// 0x01A, Finder file name (16 bytes) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public readonly byte[] bbShellName; - /// 0x02A, Debugger file name (16 bytes) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public readonly byte[] bbDbg1Name; - /// 0x03A, Disassembler file name (16 bytes) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public readonly byte[] bbDbg2Name; - /// 0x04A, Startup screen file name (16 bytes) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public readonly byte[] bbScreenName; - /// 0x05A, First program to execute on boot (16 bytes) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public readonly byte[] bbHelloName; - /// 0x06A, Clipboard file name (16 bytes) - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public readonly byte[] bbScrapName; - /// 0x07A, 1/4 of maximum opened at a time files - public readonly ushort bbCntFCBs; - /// 0x07C, Event queue size - public readonly ushort bbCntEvts; - /// 0x07E, Heap size on a Mac with 128KiB of RAM - public readonly uint bb128KSHeap; - /// 0x082, Heap size on a Mac with 256KiB of RAM - public readonly uint bb256KSHeap; - /// 0x086, Heap size on a Mac with 512KiB of RAM or more - public readonly uint bbSysHeapSize; - /// Padding - public readonly ushort filler; - /// Additional system heap space - public readonly uint bbSysHeapExtra; - /// Fraction of RAM for system heap - public readonly uint bbSysHeapFract; - } - /// Master Directory Block, should be sector 2 in volume [StructLayout(LayoutKind.Sequential, Pack = 1)] struct HfsMasterDirectoryBlock // Should be sector 2 in volume diff --git a/DiscImageChef.Filesystems/AppleMFS/Consts.cs b/DiscImageChef.Filesystems/AppleMFS/Consts.cs index 346d8c558..b9587bb49 100644 --- a/DiscImageChef.Filesystems/AppleMFS/Consts.cs +++ b/DiscImageChef.Filesystems/AppleMFS/Consts.cs @@ -36,8 +36,6 @@ namespace DiscImageChef.Filesystems.AppleMFS public partial class AppleMFS { const ushort MFS_MAGIC = 0xD2D7; - // "LK" - const ushort MFSBB_MAGIC = 0x4C4B; const short DIRID_TRASH = -3; const short DIRID_DESKTOP = -2; diff --git a/DiscImageChef.Filesystems/AppleMFS/Info.cs b/DiscImageChef.Filesystems/AppleMFS/Info.cs index fbc877c9e..9ba50418a 100644 --- a/DiscImageChef.Filesystems/AppleMFS/Info.cs +++ b/DiscImageChef.Filesystems/AppleMFS/Info.cs @@ -64,7 +64,6 @@ namespace DiscImageChef.Filesystems.AppleMFS var sb = new StringBuilder(); var mdb = new MFS_MasterDirectoryBlock(); - var bb = new MFS_BootBlock(); byte[] pString = new byte[16]; @@ -93,40 +92,6 @@ namespace DiscImageChef.Filesystems.AppleMFS Array.Copy(mdbSector, 0x024, variableSize, 0, mdb.drVNSiz + 1); mdb.drVN = StringHandlers.PascalToString(variableSize, Encoding); - bb.bbID = BigEndianBitConverter.ToUInt16(bbSector, 0x000); - - if(bb.bbID == MFSBB_MAGIC) - { - bb.bbEntry = BigEndianBitConverter.ToUInt32(bbSector, 0x002); - bb.boot_flags = bbSector[0x006]; - bb.bbVersion = bbSector[0x007]; - - bb.bbPageFlags = BigEndianBitConverter.ToInt16(bbSector, 0x008); - - Array.Copy(mdbSector, 0x00A, pString, 0, 16); - bb.bbSysName = StringHandlers.PascalToString(pString, Encoding); - Array.Copy(mdbSector, 0x01A, pString, 0, 16); - bb.bbShellName = StringHandlers.PascalToString(pString, Encoding); - Array.Copy(mdbSector, 0x02A, pString, 0, 16); - bb.bbDbg1Name = StringHandlers.PascalToString(pString, Encoding); - Array.Copy(mdbSector, 0x03A, pString, 0, 16); - bb.bbDbg2Name = StringHandlers.PascalToString(pString, Encoding); - Array.Copy(mdbSector, 0x04A, pString, 0, 16); - bb.bbScreenName = StringHandlers.PascalToString(pString, Encoding); - Array.Copy(mdbSector, 0x05A, pString, 0, 16); - bb.bbHelloName = StringHandlers.PascalToString(pString, Encoding); - Array.Copy(mdbSector, 0x06A, pString, 0, 16); - bb.bbScrapName = StringHandlers.PascalToString(pString, Encoding); - - bb.bbCntFCBs = BigEndianBitConverter.ToUInt16(bbSector, 0x07A); - bb.bbCntEvts = BigEndianBitConverter.ToUInt16(bbSector, 0x07C); - bb.bb128KSHeap = BigEndianBitConverter.ToUInt32(bbSector, 0x07E); - bb.bb256KSHeap = BigEndianBitConverter.ToUInt32(bbSector, 0x082); - bb.bbSysHeapSize = BigEndianBitConverter.ToUInt32(bbSector, 0x086); - } - else - bb.bbID = 0x0000; - sb.AppendLine("Apple Macintosh File System"); sb.AppendLine(); sb.AppendLine("Master Directory Block:"); @@ -150,37 +115,13 @@ namespace DiscImageChef.Filesystems.AppleMFS sb.AppendFormat("{0} unused allocation blocks.", mdb.drFreeBks).AppendLine(); sb.AppendFormat("Volume name: {0}", mdb.drVN).AppendLine(); - if(bb.bbID == MFSBB_MAGIC) + string bootBlockInfo = AppleCommon.GetBootBlockInformation(bbSector, Encoding); + + if(bootBlockInfo != null) { sb.AppendLine("Volume is bootable."); sb.AppendLine(); - sb.AppendLine("Boot Block:"); - - if((bb.boot_flags & 0x40) == 0x40) - sb.AppendLine("Boot block should be executed."); - - if((bb.boot_flags & 0x80) == 0x80) - sb.AppendLine("Boot block is in new unknown format."); - else - { - if(bb.bbPageFlags > 0) - sb.AppendLine("Allocate secondary sound buffer at boot."); - else if(bb.bbPageFlags < 0) - sb.AppendLine("Allocate secondary sound and video buffers at boot."); - - sb.AppendFormat("System filename: {0}", bb.bbSysName).AppendLine(); - sb.AppendFormat("Finder filename: {0}", bb.bbShellName).AppendLine(); - sb.AppendFormat("Debugger filename: {0}", bb.bbDbg1Name).AppendLine(); - sb.AppendFormat("Disassembler filename: {0}", bb.bbDbg2Name).AppendLine(); - sb.AppendFormat("Startup screen filename: {0}", bb.bbScreenName).AppendLine(); - sb.AppendFormat("First program to execute at boot: {0}", bb.bbHelloName).AppendLine(); - sb.AppendFormat("Clipboard filename: {0}", bb.bbScrapName).AppendLine(); - sb.AppendFormat("Maximum opened files: {0}", bb.bbCntFCBs * 4).AppendLine(); - sb.AppendFormat("Event queue size: {0}", bb.bbCntEvts).AppendLine(); - sb.AppendFormat("Heap size with 128KiB of RAM: {0} bytes", bb.bb128KSHeap).AppendLine(); - sb.AppendFormat("Heap size with 256KiB of RAM: {0} bytes", bb.bb256KSHeap).AppendLine(); - sb.AppendFormat("Heap size with 512KiB of RAM or more: {0} bytes", bb.bbSysHeapSize).AppendLine(); - } + sb.AppendLine(bootBlockInfo); } else sb.AppendLine("Volume is not bootable."); @@ -195,7 +136,7 @@ namespace DiscImageChef.Filesystems.AppleMFS XmlFsType.BackupDateSpecified = true; } - XmlFsType.Bootable = bb.bbID == MFSBB_MAGIC; + XmlFsType.Bootable = bootBlockInfo != null; XmlFsType.Clusters = mdb.drNmAlBlks; XmlFsType.ClusterSize = mdb.drAlBlkSiz; diff --git a/DiscImageChef.Filesystems/AppleMFS/Structs.cs b/DiscImageChef.Filesystems/AppleMFS/Structs.cs index 35f640025..2fc3567ad 100644 --- a/DiscImageChef.Filesystems/AppleMFS/Structs.cs +++ b/DiscImageChef.Filesystems/AppleMFS/Structs.cs @@ -76,45 +76,6 @@ namespace DiscImageChef.Filesystems.AppleMFS public string drVN; } - /// Should be at offset 0x0000 in volume, followed by boot code - struct MFS_BootBlock - { - /// 0x000, Signature, 0x4C4B if bootable - public ushort bbID; - /// 0x002, Branch - public uint bbEntry; - /// 0x006, Boot block flags - public byte boot_flags; - /// 0x007, Boot block version - public byte bbVersion; - /// 0x008, Allocate secondary buffers - public short bbPageFlags; - /// 0x00A, System file name (16 bytes) - public string bbSysName; - /// 0x01A, Finder file name (16 bytes) - public string bbShellName; - /// 0x02A, Debugger file name (16 bytes) - public string bbDbg1Name; - /// 0x03A, Disassembler file name (16 bytes) - public string bbDbg2Name; - /// 0x04A, Startup screen file name (16 bytes) - public string bbScreenName; - /// 0x05A, First program to execute on boot (16 bytes) - public string bbHelloName; - /// 0x06A, Clipboard file name (16 bytes) - public string bbScrapName; - /// 0x07A, 1/4 of maximum opened at a time files - public ushort bbCntFCBs; - /// 0x07C, Event queue size - public ushort bbCntEvts; - /// 0x07E, Heap size on a Mac with 128KiB of RAM - public uint bb128KSHeap; - /// 0x082, Heap size on a Mac with 256KiB of RAM - public uint bb256KSHeap; - /// 0x086, Heap size on a Mac with 512KiB of RAM or more - public uint bbSysHeapSize; - } - [Flags] enum MFS_FileFlags : byte { diff --git a/DiscImageChef.Filesystems/AppleMFS/Super.cs b/DiscImageChef.Filesystems/AppleMFS/Super.cs index 9ac2428d8..08c103f65 100644 --- a/DiscImageChef.Filesystems/AppleMFS/Super.cs +++ b/DiscImageChef.Filesystems/AppleMFS/Super.cs @@ -44,21 +44,28 @@ namespace DiscImageChef.Filesystems.AppleMFS // Information from Inside Macintosh Volume II public partial class AppleMFS { - public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, - Dictionary options, string @namespace) + public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, + Dictionary options, string @namespace) { device = imagePlugin; partitionStart = partition.Start; Encoding = encoding ?? Encoding.GetEncoding("macintosh"); - if(options == null) options = GetDefaultOptions(); - if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug); + + if(options == null) + options = GetDefaultOptions(); + + if(options.TryGetValue("debug", out string debugString)) + bool.TryParse(debugString, out debug); + volMDB = new MFS_MasterDirectoryBlock(); mdbBlocks = device.ReadSector(2 + partitionStart); bootBlocks = device.ReadSector(0 + partitionStart); volMDB.drSigWord = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x000); - if(volMDB.drSigWord != MFS_MAGIC) return Errno.InvalidArgument; + + if(volMDB.drSigWord != MFS_MAGIC) + return Errno.InvalidArgument; volMDB.drCrDate = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x002); volMDB.drLsBkUp = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x006); @@ -78,37 +85,58 @@ namespace DiscImageChef.Filesystems.AppleMFS volMDB.drVN = StringHandlers.PascalToString(variableSize, Encoding); directoryBlocks = device.ReadSectors(volMDB.drDirSt + partitionStart, volMDB.drBlLen); - int bytesInBlockMap = volMDB.drNmAlBlks * 12 / 8 + volMDB.drNmAlBlks * 12 % 8; + int bytesInBlockMap = ((volMDB.drNmAlBlks * 12) / 8) + ((volMDB.drNmAlBlks * 12) % 8); const int BYTES_BEFORE_BLOCK_MAP = 64; int bytesInWholeMdb = bytesInBlockMap + BYTES_BEFORE_BLOCK_MAP; - int sectorsInWholeMdb = bytesInWholeMdb / (int)device.Info.SectorSize + - bytesInWholeMdb % (int)device.Info.SectorSize; + + int sectorsInWholeMdb = (bytesInWholeMdb / (int)device.Info.SectorSize) + + (bytesInWholeMdb % (int)device.Info.SectorSize); + byte[] wholeMdb = device.ReadSectors(partitionStart + 2, (uint)sectorsInWholeMdb); blockMapBytes = new byte[bytesInBlockMap]; Array.Copy(wholeMdb, BYTES_BEFORE_BLOCK_MAP, blockMapBytes, 0, blockMapBytes.Length); int offset = 0; blockMap = new uint[volMDB.drNmAlBlks + 2 + 1]; + for(int i = 2; i < volMDB.drNmAlBlks + 2; i += 8) { uint tmp1 = 0; uint tmp2 = 0; uint tmp3 = 0; - if(offset + 4 <= blockMapBytes.Length) tmp1 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset); + if(offset + 4 <= blockMapBytes.Length) + tmp1 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset); + if(offset + 4 + 4 <= blockMapBytes.Length) tmp2 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 4); + if(offset + 8 + 4 <= blockMapBytes.Length) tmp3 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 8); - if(i < blockMap.Length) blockMap[i] = (tmp1 & 0xFFF00000) >> 20; - if(i + 2 < blockMap.Length) blockMap[i + 1] = (tmp1 & 0xFFF00) >> 8; - if(i + 3 < blockMap.Length) blockMap[i + 2] = ((tmp1 & 0xFF) << 4) + ((tmp2 & 0xF0000000) >> 28); - if(i + 4 < blockMap.Length) blockMap[i + 3] = (tmp2 & 0xFFF0000) >> 16; - if(i + 5 < blockMap.Length) blockMap[i + 4] = (tmp2 & 0xFFF0) >> 4; - if(i + 6 < blockMap.Length) blockMap[i + 5] = ((tmp2 & 0xF) << 8) + ((tmp3 & 0xFF000000) >> 24); - if(i + 7 < blockMap.Length) blockMap[i + 6] = (tmp3 & 0xFFF000) >> 12; - if(i + 8 < blockMap.Length) blockMap[i + 7] = tmp3 & 0xFFF; + if(i < blockMap.Length) + blockMap[i] = (tmp1 & 0xFFF00000) >> 20; + + if(i + 2 < blockMap.Length) + blockMap[i + 1] = (tmp1 & 0xFFF00) >> 8; + + if(i + 3 < blockMap.Length) + blockMap[i + 2] = ((tmp1 & 0xFF) << 4) + ((tmp2 & 0xF0000000) >> 28); + + if(i + 4 < blockMap.Length) + blockMap[i + 3] = (tmp2 & 0xFFF0000) >> 16; + + if(i + 5 < blockMap.Length) + blockMap[i + 4] = (tmp2 & 0xFFF0) >> 4; + + if(i + 6 < blockMap.Length) + blockMap[i + 5] = ((tmp2 & 0xF) << 8) + ((tmp3 & 0xFF000000) >> 24); + + if(i + 7 < blockMap.Length) + blockMap[i + 6] = (tmp3 & 0xFFF000) >> 12; + + if(i + 8 < blockMap.Length) + blockMap[i + 7] = tmp3 & 0xFFF; offset += 12; } @@ -117,32 +145,38 @@ namespace DiscImageChef.Filesystems.AppleMFS { mdbTags = device.ReadSectorTag(2 + partitionStart, SectorTagType.AppleSectorTag); bootTags = device.ReadSectorTag(0 + partitionStart, SectorTagType.AppleSectorTag); + directoryTags = device.ReadSectorsTag(volMDB.drDirSt + partitionStart, volMDB.drBlLen, SectorTagType.AppleSectorTag); + bitmapTags = device.ReadSectorsTag(partitionStart + 2, (uint)sectorsInWholeMdb, SectorTagType.AppleSectorTag); } sectorsPerBlock = (int)(volMDB.drAlBlkSiz / device.Info.SectorSize); - if(!FillDirectory()) return Errno.InvalidArgument; + if(!FillDirectory()) + return Errno.InvalidArgument; mounted = true; ushort bbSig = BigEndianBitConverter.ToUInt16(bootBlocks, 0x000); - if(bbSig != MFSBB_MAGIC) bootBlocks = null; + if(bbSig != AppleCommon.BB_MAGIC) + bootBlocks = null; XmlFsType = new FileSystemType(); + if(volMDB.drLsBkUp > 0) { XmlFsType.BackupDate = DateHandlers.MacToDateTime(volMDB.drLsBkUp); XmlFsType.BackupDateSpecified = true; } - XmlFsType.Bootable = bbSig == MFSBB_MAGIC; + XmlFsType.Bootable = bbSig == AppleCommon.BB_MAGIC; XmlFsType.Clusters = volMDB.drNmAlBlks; XmlFsType.ClusterSize = volMDB.drAlBlkSiz; + if(volMDB.drCrDate > 0) { XmlFsType.CreationDate = DateHandlers.MacToDateTime(volMDB.drCrDate); @@ -174,13 +208,11 @@ namespace DiscImageChef.Filesystems.AppleMFS { stat = new FileSystemInfo { - Blocks = volMDB.drNmAlBlks, - FilenameLength = 255, - Files = volMDB.drNmFls, - FreeBlocks = volMDB.drFreeBks, - PluginId = Id, - Type = "Apple MFS" + Blocks = volMDB.drNmAlBlks, FilenameLength = 255, Files = volMDB.drNmFls, + FreeBlocks = volMDB.drFreeBks, + PluginId = Id, Type = "Apple MFS" }; + stat.FreeFiles = uint.MaxValue - stat.Files; return Errno.NoError; diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj index e486e0b01..8e3bc3970 100644 --- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj +++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj @@ -54,6 +54,9 @@ + + +