Example #1
0
 public void FromBytesTest()
 {
     using (var fs = System.IO.File.OpenRead("E://NTFS2G.img")) {
         var bts = StreamUtilities.ReadSector(fs);
         var bpb = BiosParameterBlock.FromBytes(bts, 0);
     }
 }
Example #2
0
        private static FileSystem?GetFatFromBiosParameterBlock(Stream stream, BiosParameterBlock bpb)
        {
            uint rootDirSectors = (((uint)bpb.RootDirectoryEntries * 32) + ((uint)bpb.BytesPerLogicalSector - 1)) / (uint)bpb.BytesPerLogicalSector;

            uint fatSectors   = bpb.LogicalSectorsPerFAT;
            uint totalSectors = bpb.TotalLogicalSectors;

            uint dataSectors  = totalSectors - (bpb.ReservedLogicalSectors + (bpb.NumberOfFATs * fatSectors) + rootDirSectors);
            uint clusterCount = dataSectors / bpb.LogicalSectorsPerCluster;

            stream.Position = 0;
            if (clusterCount < 4085)
            {
                // return FAT12
                return(new Fat12FileSystem(stream, bpb));
            }
            else if (clusterCount < 65525)
            {
                // return FAT16
                return(new Fat16FileSystem(stream, bpb));
            }
            else
            {
                // return FAT32
                return(new Fat32FileSystem(stream, bpb));
            }
        }
Example #3
0
 public Fat12FileSystem(Stream stream, BiosParameterBlock bpb) : base(stream, bpb)
 {
     ClusterMaps = new ClusterMap[bpb.NumberOfFATs];
     for (int i = 0; i < bpb.NumberOfFATs; i++)
     {
         ClusterMaps[i] = new ClusterMap(this, i);
     }
 }
Example #4
0
        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

            if(hpofsBpbSector.Length < 512) return false;

            BiosParameterBlock bpb = Marshal.ByteArrayToStructureLittleEndian<BiosParameterBlock>(hpofsBpbSector);

            return bpb.fs_type.SequenceEqual(hpofsType);
        }
Example #5
0
        public Fat32FileSystem(Stream stream, BiosParameterBlock bpb) : base(stream, bpb)
        {
            ClusterMaps = new ClusterMap[bpb.NumberOfFATs];
            for (int i = 0; i < bpb.NumberOfFATs; i++)
            {
                ClusterMaps[i] = new ClusterMap(this, i);
            }

            if (bpb is Fat32BiosParameterBlock fat32bpb)
            {
                using var reader = new BinaryReader(stream);
                stream.Position  = fat32bpb.BytesPerLogicalSector * fat32bpb.FsInfo;
                _fsInfo          = FsInfo.Parse(reader);
            }
        }
Example #6
0
        /// <summary>
        /// Create a new raw image with the provided parameters
        /// </summary>
        /// <param name="bpb">The BIOS Parameter Block to use within the image</param>
        /// <param name="tracks">The number of tracks within the image</param>
        /// <param name="writeBPB">Specifies whether the BIOS Parameter Block should be written to the image</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="bpb"/> is null</exception>
        public static RawContainer CreateImage(BiosParameterBlock bpb, byte tracks, bool writeBPB)
        {
            if (bpb == null)
            {
                throw new ArgumentNullException(nameof(bpb), "BPB cannot be null!");
            }

            uint imageSize  = (uint)(bpb.BytesPerLogicalSector * bpb.PhysicalSectorsPerTrack * bpb.NumberOfHeads * tracks);
            var  imageBytes = new byte[imageSize];

            //TODO: At this point we need to consider writeBPB value...
            var stream = new MemoryStream(imageBytes, true);

            Fat12FileSystem.Create(stream, bpb, writeBPB);

            return(new RawContainer(stream));
        }
Example #7
0
        /// <inheritdoc />
        public FileSystem?TryLoadFileSystem(Stream stream)
        {
            using var reader = new BinaryReader(stream, Encoding.ASCII, true);

            BiosParameterBlock?_bpb;
            byte bpbOffset = 0x0B;

            try
            {
                _bpb = BiosParameterBlock.Parse(reader, bpbOffset); //Try to parse the BPB at the standard offset
            }
            catch (InvalidDataException)
            {
                //BPB likely invalid, check if this is an Acorn 800k disk without one
                if (CheckForAcorn800k(reader))
                {
                    return(new Fat12FileSystem(stream, BiosParameterBlock.DefaultAcornParameters));
                }
                else
                {
                    //BPB likely invalid, try parsing it at 0x50 in case it's an Apricot disk
                    try
                    {
                        bpbOffset = 0x50;
                        _bpb      = BiosParameterBlock.Parse(reader, bpbOffset);
                    }
                    catch (InvalidDataException)
                    {
                        //BPB still invalid, it may not even be there, try to figure out if it's a DOS 1.x disk by looking at file length
                        //(we can do this for raw sector images) and the media descriptor byte
                        if (!BiosParameterBlock.DefaultParametersForSize.TryGetValue(stream.Length, out _bpb))
                        {
                            return(null);
                        }
                    }
                }
            }

            return(GetFatFromBiosParameterBlock(stream, _bpb));
        }
Example #8
0
        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

            if (hpofsBpbSector.Length < 512)
            {
                return(false);
            }

            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));
        }
Example #9
0
        //Formats a volume with FAT12 file system - currently assumes it's a floppy disk...
        public static Fat12FileSystem Create(Stream stream, BiosParameterBlock bpb, bool writeBPB)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream), "stream cannot be null!");
            }
            if (bpb == null)
            {
                throw new ArgumentNullException(nameof(bpb), "bpb cannot be null!");
            }
            if (!bpb.Validate())
            {
                throw new InvalidDataException("bpb is invalid!");
            }

            var fat = new Fat12FileSystem(stream, bpb);

            uint totalSize      = (uint)stream.Length;
            uint rootDirSize    = (uint)(bpb.RootDirectoryEntries << 5);
            uint fatSize        = (uint)(bpb.LogicalSectorsPerFAT * bpb.BytesPerLogicalSector);
            uint fat1Offset     = (uint)(bpb.ReservedLogicalSectors * bpb.BytesPerLogicalSector);
            uint fat2Offset     = fat1Offset + fatSize;
            uint dataAreaOffset = fat2Offset + fatSize + rootDirSize;

            using (var writer = new BinaryWriter(stream, Encoding.ASCII, true))
            {
                stream.Seek(0, SeekOrigin.Begin);
                for (uint i = 0; i < totalSize; i++)
                {
                    writer.Write((byte)0);
                }

                //Fille the data area with 0xF6
                stream.Seek(dataAreaOffset, SeekOrigin.Begin);
                for (uint i = 0; i < totalSize - dataAreaOffset; i++)
                {
                    writer.Write((byte)0xF6);
                }

                stream.Seek(0, SeekOrigin.Begin);
                writer.Write(bpb.BootJump, 0, 3);
                writer.Write(bpb.OemId.PadRight(8, ' ').ToCharArray());

                if (writeBPB)
                {
                    writer.Write(bpb.BytesPerLogicalSector);
                    writer.Write(bpb.LogicalSectorsPerCluster);
                    writer.Write(bpb.ReservedLogicalSectors);
                    writer.Write(bpb.NumberOfFATs);
                    writer.Write(bpb.RootDirectoryEntries);
                    writer.Write(bpb.TotalLogicalSectors <= ushort.MaxValue ? (ushort)bpb.TotalLogicalSectors : (ushort)0);
                    writer.Write(bpb.MediaDescriptor);
                    writer.Write(bpb.Version != BiosParameterBlockVersion.Fat32 ? (ushort)bpb.LogicalSectorsPerFAT : (ushort)0);
                    writer.Write(bpb.PhysicalSectorsPerTrack);
                    writer.Write(bpb.NumberOfHeads);
                    writer.Write(bpb.HiddenSectors);
                    writer.Write(bpb.TotalLogicalSectors > ushort.MaxValue ? bpb.TotalLogicalSectors : 0);

                    //DOS 3.4+ specific values
                    if (bpb.Version == BiosParameterBlockVersion.Dos34 || bpb.Version == BiosParameterBlockVersion.Dos40)
                    {
                        var ebpb = (ExtendedBiosParameterBlock)bpb;
                        writer.Write(ebpb.PhysicalDriveNumber);
                        writer.Write(ebpb.Flags);
                        writer.Write((byte)ebpb.ExtendedBootSignature);
                        writer.Write(ebpb.VolumeSerialNumber.Value);

                        //DOS 4.0 adds volume label and FS type as well
                        if (bpb.Version == BiosParameterBlockVersion.Dos40)
                        {
                            if (string.IsNullOrWhiteSpace(ebpb.VolumeLabel))
                            {
                                writer.Write("NO NAME    ".ToCharArray());
                            }
                            else
                            {
                                writer.Write(ebpb.VolumeLabel.PadRight(11, ' ').ToCharArray());
                            }
                            writer.Write(ebpb.FileSystemType.PadRight(8, ' ').ToCharArray());
                        }
                    }
                }

                //Boot signature
                stream.Seek(0x1FE, SeekOrigin.Begin);
                writer.Write((byte)0x55);
                writer.Write((byte)0xAA);

                /* Media descriptor needs to be written to each FAT as well, upper 4 bits must all be set.
                 * It takes up the first cluster entry (0), and the second entry (1) is also reserved */
                stream.Seek(fat1Offset, SeekOrigin.Begin);
                writer.Write(bpb.MediaDescriptor);
                writer.Write((byte)0xFF);
                writer.Write((byte)0xFF);
                stream.Seek(fat2Offset, SeekOrigin.Begin);
                writer.Write(bpb.MediaDescriptor);
                writer.Write((byte)0xFF);
                writer.Write((byte)0xFF);

                //Volume label needs to be written to the root directory as well
                stream.Seek(fat2Offset + fatSize, SeekOrigin.Begin);

                //First 11 bytes (8.3 space-padded filename without the period) are the label itself
                {
                    if (bpb is ExtendedBiosParameterBlock bpb40 && !string.IsNullOrEmpty(bpb40.VolumeLabel))
                    {
                        writer.Write(bpb40.VolumeLabel.PadRight(11, ' ').ToCharArray());
                        writer.Write((byte)0x08); //Volume label attribute
                    }
                }
            }

            return(fat);
        }
Example #10
0
 protected FatFileSystem(Stream stream, BiosParameterBlock bpb) : base(stream)
 {
     _bpb          = bpb;
     RootDirectory = new FatDirectory(this);
 }
Example #11
0
File: Info.cs Project: paulyc/Aaru
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("ibm850");
            information = "";

            var 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

            BiosParameterBlock     bpb = Marshal.ByteArrayToStructureLittleEndian <BiosParameterBlock>(hpofsBpbSector);
            MediaInformationBlock  mib = Marshal.ByteArrayToStructureBigEndian <MediaInformationBlock>(medInfoSector);
            VolumeInformationBlock vib = Marshal.ByteArrayToStructureBigEndian <VolumeInformationBlock>(volInfoSector);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.oem_name = \"{0}\"",
                                       StringHandlers.CToString(bpb.oem_name));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.bps = {0}", bpb.bps);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.spc = {0}", bpb.spc);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.rsectors = {0}", bpb.rsectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.fats_no = {0}", bpb.fats_no);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.root_ent = {0}", bpb.root_ent);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.sectors = {0}", bpb.sectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.media = 0x{0:X2}", bpb.media);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.spfat = {0}", bpb.spfat);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.sptrk = {0}", bpb.sptrk);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.heads = {0}", bpb.heads);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.hsectors = {0}", bpb.hsectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.big_sectors = {0}", bpb.big_sectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.drive_no = 0x{0:X2}", bpb.drive_no);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.nt_flags = {0}", bpb.nt_flags);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.signature = 0x{0:X2}", bpb.signature);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.serial_no = 0x{0:X8}", bpb.serial_no);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.volume_label = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(bpb.volume_label));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.fs_type = \"{0}\"", StringHandlers.CToString(bpb.fs_type));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.boot_code is empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(bpb.boot_code));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.unknown = {0}", bpb.unknown);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.unknown2 = {0}", bpb.unknown2);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "bpb.signature2 = {0}", bpb.signature2);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.blockId = \"{0}\"", StringHandlers.CToString(mib.blockId));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.volumeLabel = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(mib.volumeLabel));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.comment = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(mib.comment));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.serial = 0x{0:X8}", mib.serial);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.creationTimestamp = {0}",
                                       DateHandlers.DosToDateTime(mib.creationDate, mib.creationTime));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.codepageType = {0}", mib.codepageType);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.codepage = {0}", mib.codepage);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.rps = {0}", mib.rps);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.bps = {0}", mib.bps);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.bpc = {0}", mib.bpc);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown2 = {0}", mib.unknown2);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.sectors = {0}", mib.sectors);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown3 = {0}", mib.unknown3);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown4 = {0}", mib.unknown4);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.major = {0}", mib.major);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.minor = {0}", mib.minor);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown5 = {0}", mib.unknown5);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.unknown6 = {0}", mib.unknown6);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "mib.filler is empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(mib.filler));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.blockId = \"{0}\"", StringHandlers.CToString(vib.blockId));
            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown = {0}", vib.unknown);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown2 = {0}", vib.unknown2);

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown3 is empty? = {0}",
                                       ArrayHelpers.ArrayIsNullOrEmpty(vib.unknown3));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown4 = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(vib.unknown4));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.owner = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(vib.owner));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown5 = \"{0}\"",
                                       StringHandlers.SpacePaddedToString(vib.unknown5));

            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown6 = {0}", vib.unknown6);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.percentFull = {0}", vib.percentFull);
            AaruConsole.DebugWriteLine("HPOFS Plugin", "vib.unknown7 = {0}", vib.unknown7);

            AaruConsole.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            = (uint)(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();
        }
Example #12
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("ibm850");
            information = "";

            var sb = new StringBuilder();

            byte[] hpfsBpbSector =
                imagePlugin.ReadSector(0 + partition.Start); // Seek to BIOS parameter block, on logical sector 0

            byte[] hpfsSbSector =
                imagePlugin.ReadSector(16 + partition.Start); // Seek to superblock, on logical sector 16

            byte[] hpfsSpSector =
                imagePlugin.ReadSector(17 + partition.Start); // Seek to spareblock, on logical sector 17

            BiosParameterBlock bpb = Marshal.ByteArrayToStructureLittleEndian <BiosParameterBlock>(hpfsBpbSector);

            SuperBlock hpfsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(hpfsSbSector);

            SpareBlock sp = Marshal.ByteArrayToStructureLittleEndian <SpareBlock>(hpfsSpSector);

            if (StringHandlers.CToString(bpb.fs_type) != "HPFS    " ||
                hpfsSb.magic1 != 0xF995E849 ||
                hpfsSb.magic2 != 0xFA53E9C5 ||
                sp.magic1 != 0xF9911849 ||
                sp.magic2 != 0xFA5229C5)
            {
                sb.AppendLine("This may not be HPFS, following information may be not correct.");
                sb.AppendFormat("File system type: \"{0}\" (Should be \"HPFS    \")", bpb.fs_type).AppendLine();
                sb.AppendFormat("Superblock magic1: 0x{0:X8} (Should be 0xF995E849)", hpfsSb.magic1).AppendLine();
                sb.AppendFormat("Superblock magic2: 0x{0:X8} (Should be 0xFA53E9C5)", hpfsSb.magic2).AppendLine();
                sb.AppendFormat("Spareblock magic1: 0x{0:X8} (Should be 0xF9911849)", sp.magic1).AppendLine();
                sb.AppendFormat("Spareblock magic2: 0x{0:X8} (Should be 0xFA5229C5)", sp.magic2).AppendLine();
            }

            sb.AppendFormat("OEM name: {0}", StringHandlers.CToString(bpb.oem_name)).AppendLine();
            sb.AppendFormat("{0} bytes per sector", bpb.bps).AppendLine();

            //          sb.AppendFormat("{0} sectors per cluster", hpfs_bpb.spc).AppendLine();
            //          sb.AppendFormat("{0} reserved sectors", hpfs_bpb.rsectors).AppendLine();
            //          sb.AppendFormat("{0} FATs", hpfs_bpb.fats_no).AppendLine();
            //          sb.AppendFormat("{0} entries on root directory", hpfs_bpb.root_ent).AppendLine();
            //          sb.AppendFormat("{0} mini sectors on volume", hpfs_bpb.sectors).AppendLine();
            sb.AppendFormat("Media descriptor: 0x{0:X2}", bpb.media).AppendLine();

            //          sb.AppendFormat("{0} sectors per FAT", hpfs_bpb.spfat).AppendLine();
            //          sb.AppendFormat("{0} sectors per track", hpfs_bpb.sptrk).AppendLine();
            //          sb.AppendFormat("{0} heads", hpfs_bpb.heads).AppendLine();
            sb.AppendFormat("{0} sectors hidden before BPB", bpb.hsectors).AppendLine();

            sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfsSb.sectors, hpfsSb.sectors * bpb.bps).AppendLine();

            //          sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfs_bpb.big_sectors, hpfs_bpb.big_sectors * hpfs_bpb.bps).AppendLine();
            sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", bpb.drive_no).AppendLine();
            sb.AppendFormat("NT Flags: 0x{0:X2}", bpb.nt_flags).AppendLine();
            sb.AppendFormat("Signature: 0x{0:X2}", bpb.signature).AppendLine();
            sb.AppendFormat("Serial number: 0x{0:X8}", bpb.serial_no).AppendLine();
            sb.AppendFormat("Volume label: {0}", StringHandlers.CToString(bpb.volume_label, Encoding)).AppendLine();

            //          sb.AppendFormat("Filesystem type: \"{0}\"", hpfs_bpb.fs_type).AppendLine();

            DateTime lastChk   = DateHandlers.UnixToDateTime(hpfsSb.last_chkdsk);
            DateTime lastOptim = DateHandlers.UnixToDateTime(hpfsSb.last_optim);

            sb.AppendFormat("HPFS version: {0}", hpfsSb.version).AppendLine();
            sb.AppendFormat("Functional version: {0}", hpfsSb.func_version).AppendLine();
            sb.AppendFormat("Sector of root directory FNode: {0}", hpfsSb.root_fnode).AppendLine();
            sb.AppendFormat("{0} sectors are marked bad", hpfsSb.badblocks).AppendLine();
            sb.AppendFormat("Sector of free space bitmaps: {0}", hpfsSb.bitmap_lsn).AppendLine();
            sb.AppendFormat("Sector of bad blocks list: {0}", hpfsSb.badblock_lsn).AppendLine();

            if (hpfsSb.last_chkdsk > 0)
            {
                sb.AppendFormat("Date of last integrity check: {0}", lastChk).AppendLine();
            }
            else
            {
                sb.AppendLine("Filesystem integrity has never been checked");
            }

            if (hpfsSb.last_optim > 0)
            {
                sb.AppendFormat("Date of last optimization {0}", lastOptim).AppendLine();
            }
            else
            {
                sb.AppendLine("Filesystem has never been optimized");
            }

            sb.AppendFormat("Directory band has {0} sectors", hpfsSb.dband_sectors).AppendLine();
            sb.AppendFormat("Directory band starts at sector {0}", hpfsSb.dband_start).AppendLine();
            sb.AppendFormat("Directory band ends at sector {0}", hpfsSb.dband_last).AppendLine();
            sb.AppendFormat("Sector of directory band bitmap: {0}", hpfsSb.dband_bitmap).AppendLine();
            sb.AppendFormat("Sector of ACL directory: {0}", hpfsSb.acl_start).AppendLine();

            sb.AppendFormat("Sector of Hotfix directory: {0}", sp.hotfix_start).AppendLine();
            sb.AppendFormat("{0} used Hotfix entries", sp.hotfix_used).AppendLine();
            sb.AppendFormat("{0} total Hotfix entries", sp.hotfix_entries).AppendLine();
            sb.AppendFormat("{0} free spare DNodes", sp.spare_dnodes_free).AppendLine();
            sb.AppendFormat("{0} total spare DNodes", sp.spare_dnodes).AppendLine();
            sb.AppendFormat("Sector of codepage directory: {0}", sp.codepage_lsn).AppendLine();
            sb.AppendFormat("{0} codepages used in the volume", sp.codepages).AppendLine();
            sb.AppendFormat("SuperBlock CRC32: {0:X8}", sp.sb_crc32).AppendLine();
            sb.AppendFormat("SpareBlock CRC32: {0:X8}", sp.sp_crc32).AppendLine();

            sb.AppendLine("Flags:");
            sb.AppendLine((sp.flags1 & 0x01) == 0x01 ? "Filesystem is dirty." : "Filesystem is clean.");

            if ((sp.flags1 & 0x02) == 0x02)
            {
                sb.AppendLine("Spare directory blocks are in use");
            }

            if ((sp.flags1 & 0x04) == 0x04)
            {
                sb.AppendLine("Hotfixes are in use");
            }

            if ((sp.flags1 & 0x08) == 0x08)
            {
                sb.AppendLine("Disk contains bad sectors");
            }

            if ((sp.flags1 & 0x10) == 0x10)
            {
                sb.AppendLine("Disk has a bad bitmap");
            }

            if ((sp.flags1 & 0x20) == 0x20)
            {
                sb.AppendLine("Filesystem was formatted fast");
            }

            if ((sp.flags1 & 0x40) == 0x40)
            {
                sb.AppendLine("Unknown flag 0x40 on flags1 is active");
            }

            if ((sp.flags1 & 0x80) == 0x80)
            {
                sb.AppendLine("Filesystem has been mounted by an old IFS");
            }

            if ((sp.flags2 & 0x01) == 0x01)
            {
                sb.AppendLine("Install DASD limits");
            }

            if ((sp.flags2 & 0x02) == 0x02)
            {
                sb.AppendLine("Resync DASD limits");
            }

            if ((sp.flags2 & 0x04) == 0x04)
            {
                sb.AppendLine("DASD limits are operational");
            }

            if ((sp.flags2 & 0x08) == 0x08)
            {
                sb.AppendLine("Multimedia is active");
            }

            if ((sp.flags2 & 0x10) == 0x10)
            {
                sb.AppendLine("DCE ACLs are active");
            }

            if ((sp.flags2 & 0x20) == 0x20)
            {
                sb.AppendLine("DASD limits are dirty");
            }

            if ((sp.flags2 & 0x40) == 0x40)
            {
                sb.AppendLine("Unknown flag 0x40 on flags2 is active");
            }

            if ((sp.flags2 & 0x80) == 0x80)
            {
                sb.AppendLine("Unknown flag 0x80 on flags2 is active");
            }

            XmlFsType = new FileSystemType();

            // Theoretically everything from BPB to SB is boot code, should I hash everything or only the sector loaded by BIOS itself?
            if (bpb.jump[0] == 0xEB &&
                bpb.jump[1] > 0x3C &&
                bpb.jump[1] < 0x80 &&
                bpb.signature2 == 0xAA55)
            {
                XmlFsType.Bootable = true;
                string bootChk = Sha1Context.Data(bpb.boot_code, out byte[] _);
                sb.AppendLine("Volume is bootable");
                sb.AppendFormat("Boot code's SHA1: {0}", bootChk).AppendLine();
            }

            XmlFsType.Dirty           |= (sp.flags1 & 0x01) == 0x01;
            XmlFsType.Clusters         = hpfsSb.sectors;
            XmlFsType.ClusterSize      = bpb.bps;
            XmlFsType.Type             = "HPFS";
            XmlFsType.VolumeName       = StringHandlers.CToString(bpb.volume_label, Encoding);
            XmlFsType.VolumeSerial     = $"{bpb.serial_no:X8}";
            XmlFsType.SystemIdentifier = StringHandlers.CToString(bpb.oem_name);

            information = sb.ToString();
        }
Example #13
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            var sb = new StringBuilder();

            byte[] bpbSector = imagePlugin.ReadSector(0 + partition.Start);

            var bpb = new BiosParameterBlock
            {
                bps       = BitConverter.ToUInt16(bpbSector, 0x0B),
                root_ent  = BitConverter.ToUInt16(bpbSector, 0x10),
                sectors   = BitConverter.ToUInt16(bpbSector, 0x12),
                media     = bpbSector[0x14],
                spfat     = BitConverter.ToUInt16(bpbSector, 0x15),
                sptrk     = BitConverter.ToUInt16(bpbSector, 0x17),
                heads     = BitConverter.ToUInt16(bpbSector, 0x19),
                signature = bpbSector[0x25]
            };

            byte[] bpbStrings = new byte[8];
            Array.Copy(bpbSector, 0x03, bpbStrings, 0, 8);
            bpb.OEMName = StringHandlers.CToString(bpbStrings);
            bpbStrings  = new byte[8];
            Array.Copy(bpbSector, 0x2A, bpbStrings, 0, 11);
            bpb.vol_name = StringHandlers.CToString(bpbStrings, Encoding);
            bpbStrings   = new byte[8];
            Array.Copy(bpbSector, 0x35, bpbStrings, 0, 8);
            bpb.fs_type = StringHandlers.CToString(bpbStrings, Encoding);

            bpb.x86_jump = new byte[3];
            Array.Copy(bpbSector, 0x00, bpb.x86_jump, 0, 3);
            bpb.unk1 = bpbSector[0x0D];
            bpb.unk2 = BitConverter.ToUInt16(bpbSector, 0x0E);
            bpb.unk3 = new byte[10];
            Array.Copy(bpbSector, 0x1B, bpb.unk3, 0, 10);
            bpb.unk4 = BitConverter.ToUInt32(bpbSector, 0x26);

            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.x86_jump: 0x{0:X2}{1:X2}{2:X2}", bpb.x86_jump[0],
                                       bpb.x86_jump[1], bpb.x86_jump[2]);

            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.OEMName: \"{0}\"", bpb.OEMName);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.bps: {0}", bpb.bps);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.unk1: 0x{0:X2}", bpb.unk1);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.unk2: 0x{0:X4}", bpb.unk2);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.root_ent: {0}", bpb.root_ent);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.sectors: {0}", bpb.sectors);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.media: 0x{0:X2}", bpb.media);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.spfat: {0}", bpb.spfat);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.sptrk: {0}", bpb.sptrk);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.heads: {0}", bpb.heads);

            AaruConsole.DebugWriteLine("SolarFS plugin",
                                       "BPB.unk3: 0x{0:X2}{1:X2}{2:X2}{3:X2}{4:X2}{5:X2}{6:X2}{7:X2}{8:X2}{9:X2}",
                                       bpb.unk3[0], bpb.unk3[1], bpb.unk3[2], bpb.unk3[3], bpb.unk3[4], bpb.unk3[5],
                                       bpb.unk3[6], bpb.unk3[7], bpb.unk3[8], bpb.unk3[9]);

            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.signature: 0x{0:X2}", bpb.signature);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.unk4: 0x{0:X8}", bpb.unk4);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.vol_name: \"{0}\"", bpb.vol_name);
            AaruConsole.DebugWriteLine("SolarFS plugin", "BPB.fs_type: \"{0}\"", bpb.fs_type);

            sb.AppendLine("Solar_OS filesystem");
            sb.AppendFormat("Media descriptor: 0x{0:X2}", bpb.media).AppendLine();
            sb.AppendFormat("{0} bytes per sector", bpb.bps).AppendLine();

            if (imagePlugin.Info.SectorSize == 2336 ||
                imagePlugin.Info.SectorSize == 2352 ||
                imagePlugin.Info.SectorSize == 2448)
            {
                if (bpb.bps != imagePlugin.Info.SectorSize)
                {
                    sb.
                    AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector",
                                 bpb.bps, 2048).AppendLine();
                }
            }
            else if (bpb.bps != imagePlugin.Info.SectorSize)
            {
                sb.
                AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector",
                             bpb.bps, imagePlugin.Info.SectorSize).AppendLine();
            }

            sb.AppendFormat("{0} sectors on volume ({1} bytes)", bpb.sectors, bpb.sectors * bpb.bps).AppendLine();

            if (bpb.sectors > imagePlugin.Info.Sectors)
            {
                sb.AppendFormat("WARNING: Filesystem describes a {0} sectors volume, bigger than device ({1} sectors)",
                                bpb.sectors, imagePlugin.Info.Sectors);
            }

            sb.AppendFormat("{0} heads", bpb.heads).AppendLine();
            sb.AppendFormat("{0} sectors per track", bpb.sptrk).AppendLine();
            sb.AppendFormat("Volume name: {0}", bpb.vol_name).AppendLine();

            XmlFsType = new FileSystemType
            {
                Type        = "SolarFS",
                Clusters    = bpb.sectors,
                ClusterSize = bpb.bps,
                VolumeName  = bpb.vol_name
            };

            information = sb.ToString();
        }
Example #14
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = Encoding.Unicode;
            information = "";

            var sb = new StringBuilder();

            byte[] ntfsBpb = imagePlugin.ReadSector(0 + partition.Start);

            BiosParameterBlock ntfsBb = Marshal.ByteArrayToStructureLittleEndian <BiosParameterBlock>(ntfsBpb);

            sb.AppendFormat("{0} bytes per sector", ntfsBb.bps).AppendLine();
            sb.AppendFormat("{0} sectors per cluster ({1} bytes)", ntfsBb.spc, ntfsBb.spc * ntfsBb.bps).AppendLine();

            //          sb.AppendFormat("{0} reserved sectors", ntfs_bb.rsectors).AppendLine();
            //          sb.AppendFormat("{0} FATs", ntfs_bb.fats_no).AppendLine();
            //          sb.AppendFormat("{0} entries in the root folder", ntfs_bb.root_ent).AppendLine();
            //          sb.AppendFormat("{0} sectors on volume (small)", ntfs_bb.sml_sectors).AppendLine();
            sb.AppendFormat("Media descriptor: 0x{0:X2}", ntfsBb.media).AppendLine();

            //          sb.AppendFormat("{0} sectors per FAT", ntfs_bb.spfat).AppendLine();
            sb.AppendFormat("{0} sectors per track", ntfsBb.sptrk).AppendLine();
            sb.AppendFormat("{0} heads", ntfsBb.heads).AppendLine();
            sb.AppendFormat("{0} hidden sectors before filesystem", ntfsBb.hsectors).AppendLine();

            //          sb.AppendFormat("{0} sectors on volume (big)", ntfs_bb.big_sectors).AppendLine();
            sb.AppendFormat("BIOS drive number: 0x{0:X2}", ntfsBb.drive_no).AppendLine();

            //          sb.AppendFormat("NT flags: 0x{0:X2}", ntfs_bb.nt_flags).AppendLine();
            //          sb.AppendFormat("Signature 1: 0x{0:X2}", ntfs_bb.signature1).AppendLine();
            sb.AppendFormat("{0} sectors on volume ({1} bytes)", ntfsBb.sectors, ntfsBb.sectors * ntfsBb.bps).
            AppendLine();

            sb.AppendFormat("Cluster where $MFT starts: {0}", ntfsBb.mft_lsn).AppendLine();
            sb.AppendFormat("Cluster where $MFTMirr starts: {0}", ntfsBb.mftmirror_lsn).AppendLine();

            if (ntfsBb.mft_rc_clusters > 0)
            {
                sb.AppendFormat("{0} clusters per MFT record ({1} bytes)", ntfsBb.mft_rc_clusters,
                                ntfsBb.mft_rc_clusters * ntfsBb.bps * ntfsBb.spc).AppendLine();
            }
            else
            {
                sb.AppendFormat("{0} bytes per MFT record", 1 << -ntfsBb.mft_rc_clusters).AppendLine();
            }

            if (ntfsBb.index_blk_cts > 0)
            {
                sb.AppendFormat("{0} clusters per Index block ({1} bytes)", ntfsBb.index_blk_cts,
                                ntfsBb.index_blk_cts * ntfsBb.bps * ntfsBb.spc).AppendLine();
            }
            else
            {
                sb.AppendFormat("{0} bytes per Index block", 1 << -ntfsBb.index_blk_cts).AppendLine();
            }

            sb.AppendFormat("Volume serial number: {0:X16}", ntfsBb.serial_no).AppendLine();

            //          sb.AppendFormat("Signature 2: 0x{0:X4}", ntfs_bb.signature2).AppendLine();

            XmlFsType = new FileSystemType();

            if (ntfsBb.jump[0] == 0xEB &&
                ntfsBb.jump[1] > 0x4E &&
                ntfsBb.jump[1] < 0x80 &&
                ntfsBb.signature2 == 0xAA55)
            {
                XmlFsType.Bootable = true;
                string bootChk = Sha1Context.Data(ntfsBb.boot_code, out _);
                sb.AppendLine("Volume is bootable");
                sb.AppendFormat("Boot code's SHA1: {0}", bootChk).AppendLine();
            }

            XmlFsType.ClusterSize  = (uint)(ntfsBb.spc * ntfsBb.bps);
            XmlFsType.Clusters     = (ulong)(ntfsBb.sectors / ntfsBb.spc);
            XmlFsType.VolumeSerial = $"{ntfsBb.serial_no:X16}";
            XmlFsType.Type         = "NTFS";

            information = sb.ToString();
        }