From 473f9b39ccb7ab4ede379511677e68872b0cbd7a Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 21 Sep 2017 21:20:53 +0100 Subject: [PATCH] Added support for the MicroDOS file system. --- .../DiscImageChef.Filesystems.csproj | 3 +- DiscImageChef.Filesystems/MicroDOS.cs | 238 ++++++++++++++++++ README.md | 1 + 3 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 DiscImageChef.Filesystems/MicroDOS.cs diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj index 096338e06..e78dcfa91 100644 --- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj +++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj @@ -136,6 +136,7 @@ + @@ -193,7 +194,7 @@ - + diff --git a/DiscImageChef.Filesystems/MicroDOS.cs b/DiscImageChef.Filesystems/MicroDOS.cs new file mode 100644 index 000000000..37452ff43 --- /dev/null +++ b/DiscImageChef.Filesystems/MicroDOS.cs @@ -0,0 +1,238 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : MicroDOS.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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-2017 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using DiscImageChef.CommonTypes; + +namespace DiscImageChef.Filesystems +{ + // Information from http://www.owg.ru/mkt/BK/MKDOS.TXT + // Thanks to tarlabnor for translating it + public class MicroDOS : Filesystem + { + const ushort magic = 0xA72E; + const ushort magic2 = 0x530C; + + public MicroDOS() + { + Name = "MicroDOS file system"; + PluginUUID = new Guid("9F9A364A-1A27-48A3-B730-7A7122000324"); + CurrentEncoding = Encoding.GetEncoding("koi8-r"); + } + + public MicroDOS(ImagePlugins.ImagePlugin imagePlugin, Partition partition, Encoding encoding) + { + Name = "MicroDOS file system"; + PluginUUID = new Guid("9F9A364A-1A27-48A3-B730-7A7122000324"); + if(encoding == null) + CurrentEncoding = Encoding.GetEncoding("koi8-r"); + else + CurrentEncoding = encoding; + } + + public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, Partition partition) + { + if((1 + partition.Start) >= partition.End) + return false; + + if(imagePlugin.GetSectorSize() < 512) + return false; + + MicroDOSBlock0 block0 = new MicroDOSBlock0(); + + byte[] bk0 = imagePlugin.ReadSector(0 + partition.Start); + + GCHandle handle = GCHandle.Alloc(bk0, GCHandleType.Pinned); + block0 = (MicroDOSBlock0)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MicroDOSBlock0)); + handle.Free(); + + return block0.label == magic && block0.mklabel == magic2; + } + + public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, Partition partition, out string information) + { + information = ""; + + StringBuilder sb = new StringBuilder(); + MicroDOSBlock0 block0 = new MicroDOSBlock0(); + + byte[] bk0 = imagePlugin.ReadSector(0 + partition.Start); + + GCHandle handle = GCHandle.Alloc(bk0, GCHandleType.Pinned); + block0 = (MicroDOSBlock0)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MicroDOSBlock0)); + handle.Free(); + + sb.AppendLine("MicroDOS filesystem"); + sb.AppendFormat("Volume has {0} blocks ({1} bytes)", block0.blocks, block0.blocks * 512).AppendLine(); + sb.AppendFormat("Volume has {0} blocks used ({1} bytes)", block0.usedBlocks, block0.usedBlocks * 512).AppendLine(); + sb.AppendFormat("Volume contains {0} files", block0.files).AppendLine(); + sb.AppendFormat("First used block is {0}", block0.firstUsedBlock).AppendLine(); + + xmlFSType = new Schemas.FileSystemType + { + Type = "MicroDOS", + ClusterSize = 512, + Clusters = block0.blocks, + Files = block0.files, + FilesSpecified = true, + FreeClusters = block0.blocks - block0.usedBlocks, + FreeClustersSpecified = true + }; + + information = sb.ToString(); + } + + // Followed by directory entries + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct MicroDOSBlock0 + { + /// BK starts booting here + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] + public byte[] bootCode; + /// Number of files in directory + public ushort files; + /// Total number of blocks in files of the directory + public ushort usedBlocks; + /// Unknown + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 228)] + public byte[] unknown; + /// Ownership label (label that shows it belongs to Micro DOS format) + public ushort label; + /// MK-DOS directory format label + public ushort mklabel; + /// Unknown + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] + public byte[] unknown2; + /// Disk size in blocks (absolute value for the system unlike NORD, NORTON etc.) that + /// doesn't use two fixed values 40 or 80 tracks, but i.e. if you drive works with 76 tracks + /// this field will contain an appropriate number of blocks + public ushort blocks; + /// Number of the first file's block. Value is changable + public ushort firstUsedBlock; + /// Unknown + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] unknown3; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct DirectoryEntry + { + /// File status + public byte status; + /// Directory number (0 - root) + public byte directory; + /// File name 14. symbols in ASCII KOI8 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] + public byte[] filename; + /// Block number + public ushort blockNo; + /// Length in blocks + public ushort blocks; + /// Address + public ushort address; + /// Length + public ushort length; + } + + enum FileStatus : byte + { + CommonFile = 0, + Protected = 1, + LogicalDisk = 2, + BadFile = 0x80, + Deleted = 0xFF + } + + public override Errno Mount() + { + return Errno.NotImplemented; + } + + public override Errno Mount(bool debug) + { + return Errno.NotImplemented; + } + + public override Errno Unmount() + { + return Errno.NotImplemented; + } + + public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock) + { + return Errno.NotImplemented; + } + + public override Errno GetAttributes(string path, ref FileAttributes attributes) + { + return Errno.NotImplemented; + } + + public override Errno ListXAttr(string path, ref List xattrs) + { + return Errno.NotImplemented; + } + + public override Errno GetXattr(string path, string xattr, ref byte[] buf) + { + return Errno.NotImplemented; + } + + public override Errno Read(string path, long offset, long size, ref byte[] buf) + { + return Errno.NotImplemented; + } + + public override Errno ReadDir(string path, ref List contents) + { + return Errno.NotImplemented; + } + + public override Errno StatFs(ref FileSystemInfo stat) + { + return Errno.NotImplemented; + } + + public override Errno Stat(string path, ref FileEntryInfo stat) + { + return Errno.NotImplemented; + } + + public override Errno ReadLink(string path, ref string dest) + { + return Errno.NotImplemented; + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 63911e104..297d9bcae 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ Supported file systems for identification and information only * Linux extended file system 3 * Linux extended file system 4 * Locus file system +* MicroDOS file system * Microsoft 12-bit File Allocation Table (FAT12), including Atari ST extensions * Microsoft 16-bit File Allocation Table (FAT16) * Microsoft 32-bit File Allocation Table (FAT32), including FAT+ extension