public void FromBytesTest() { using (var fs = System.IO.File.OpenRead("E://NTFS2G.img")) { var bts = StreamUtilities.ReadSector(fs); var bpb = BiosParameterBlock.FromBytes(bts, 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)); } }
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); } }
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); }
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); } }
/// <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)); }
/// <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)); }
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)); }
//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); }
protected FatFileSystem(Stream stream, BiosParameterBlock bpb) : base(stream) { _bpb = bpb; RootDirectory = new FatDirectory(this); }
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(); }
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(); }
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(); }
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(); }