diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj index e1254fea5..1a42d47ce 100644 --- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj +++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj @@ -132,6 +132,7 @@ + @@ -189,7 +190,7 @@ - + diff --git a/DiscImageChef.Filesystems/RT11.cs b/DiscImageChef.Filesystems/RT11.cs new file mode 100644 index 000000000..0a87c4e3a --- /dev/null +++ b/DiscImageChef.Filesystems/RT11.cs @@ -0,0 +1,235 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : RT11.cs +// Author(s) : Natalia Portillo +// +// Component : RT-11 file system plugin. +// +// --[ Description ] ---------------------------------------------------------- +// +// Identifies the RT-11 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-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.trailing-edge.com/~shoppa/rt11fs/ + // TODO: Implement Radix-50 + public class RT11 : Filesystem + { + public RT11() + { + Name = "RT-11 file system"; + PluginUUID = new Guid("DB3E2F98-8F98-463C-8126-E937843DA024"); + CurrentEncoding = Encoding.GetEncoding("iso-8859-1"); + } + + public RT11(ImagePlugins.ImagePlugin imagePlugin, Partition partition, Encoding encoding) + { + Name = "RT-11 file system"; + PluginUUID = new Guid("DB3E2F98-8F98-463C-8126-E937843DA024"); + if(encoding == null) + CurrentEncoding = Encoding.GetEncoding("iso-8859-1"); + 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; + + byte[] magic_b = new byte[12]; + string magic; + byte[] hb_sector = imagePlugin.ReadSector(1 + partition.Start); + + Array.Copy(hb_sector, 0x1F0, magic_b, 0, 12); + magic = Encoding.ASCII.GetString(magic_b); + + return magic == "DECRT11A "; + } + + public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, Partition partition, out string information) + { + information = ""; + + StringBuilder sb = new StringBuilder(); + RT11HomeBlock homeblock = new RT11HomeBlock(); + + byte[] hb_sector = imagePlugin.ReadSector(1 + partition.Start); + + GCHandle handle = GCHandle.Alloc(hb_sector, GCHandleType.Pinned); + homeblock = (RT11HomeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(RT11HomeBlock)); + handle.Free(); + + /* TODO: Is this correct? + * Assembler: + * MOV address, R0 + * CLR R1 + * MOV #255., R2 + * 10$: ADD (R0)+, R1 + * SOB R2, 10$ + * MOV 1,@R0 + */ + ushort check = 0; + for(int i = 0; i < 512; i += 2) + check += BitConverter.ToUInt16(hb_sector, i); + + sb.AppendFormat("Volume format is {0}", StringHandlers.SpacePaddedToString(homeblock.format, CurrentEncoding)).AppendLine(); + sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512).AppendLine(); + sb.AppendFormat("First directory segment starts at block {0}", homeblock.rootBlock).AppendLine(); + sb.AppendFormat("Volume owner is \"{0}\"", StringHandlers.SpacePaddedToString(homeblock.ownername, CurrentEncoding)).AppendLine(); + sb.AppendFormat("Volume label: \"{0}\"", StringHandlers.SpacePaddedToString(homeblock.volname, CurrentEncoding)).AppendLine(); + sb.AppendFormat("Checksum: 0x{0:X4} (calculated 0x{1:X4})", homeblock.checksum, check).AppendLine(); + + byte[] bootBlock = imagePlugin.ReadSector(0); + + xmlFSType = new Schemas.FileSystemType + { + Type = "RT-11", + ClusterSize = homeblock.cluster * 512, + Clusters = homeblock.cluster, + VolumeName = StringHandlers.SpacePaddedToString(homeblock.volname, CurrentEncoding), + Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlock) + }; + + information = sb.ToString(); + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct RT11HomeBlock + { + /// Bad block replacement table + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 130)] + public byte[] badBlockTable; + /// Unused + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] unused; + /// INITIALIZE/RESTORE data area + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 38)] + public byte[] initArea; + /// BUP information area + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] + public byte[] bupInformation; + /// Empty + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)] + public byte[] empty; + /// Reserved + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] reserved1; + /// Reserved + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] reserved2; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] + public byte[] empty2; + /// Cluster size + public ushort cluster; + /// Block of the first directory segment + public ushort rootBlock; + /// "V3A" in Radix-50 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] systemVersion; + /// Name of the volume, 12 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] + public byte[] volname; + /// Name of the volume owner, 12 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] + public byte[] ownername; + /// RT11 defines it as "DECRT11A ", 12 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] + public byte[] format; + /// Unused + public ushort unused2; + /// Checksum of preceding 255 words (16 bit units) + public ushort checksum; + } + + 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 4ed7d03e8..b7e59fa24 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ Supported file systems for identification and information only * Coherent UNIX file system * Commodore 1540/1541/1571/1581 filesystems * Cram file system +* DEC RT-11 file system * DEC Files-11 (only checked with On Disk Structure 2, ODS-2) * ECMA-67: 130mm Flexible Disk Cartridge Labelling and File Structure for Information Interchange * Flash-Friendly File System (F2FS)