public bool Identify(IMediaImage imagePlugin, Partition partition) { uint sbSize = (uint)(Marshal.SizeOf <VolumeHeader>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <VolumeHeader>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } if (partition.Start + sbSize >= partition.End) { return(false); } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf <VolumeHeader>()) { return(false); } VolumeHeader vhdr = Marshal.ByteArrayToStructureLittleEndian <VolumeHeader>(sector); return(vhdr.identifier == FSRS && ArrayHelpers.ArrayIsNullOrEmpty(vhdr.mustBeZero) && vhdr.signature.SequenceEqual(_signature)); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = Encoding.GetEncoding("koi8-r"); byte[] sector = imagePlugin.ReadSector(0); BootBlock bb = Marshal.ByteArrayToStructureLittleEndian <BootBlock>(sector); var sbInformation = new StringBuilder(); sbInformation.AppendLine("Alexander Osipov DOS file system"); XmlFsType = new FileSystemType { Type = "Alexander Osipov DOS file system", Clusters = imagePlugin.Info.Sectors, ClusterSize = imagePlugin.Info.SectorSize, Files = bb.files, FilesSpecified = true, FreeClusters = imagePlugin.Info.Sectors - bb.usedSectors, FreeClustersSpecified = true, VolumeName = StringHandlers.SpacePaddedToString(bb.volumeLabel, Encoding), Bootable = true }; sbInformation.AppendFormat("{0} files on volume", bb.files).AppendLine(); sbInformation.AppendFormat("{0} used sectors on volume", bb.usedSectors).AppendLine(); sbInformation.AppendFormat("Disk name: {0}", StringHandlers.CToString(bb.volumeLabel, Encoding)). AppendLine(); information = sbInformation.ToString(); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { // Does AO-DOS support hard disks? if (partition.Start > 0) { return(false); } // How is it really? if (imagePlugin.Info.SectorSize != 512) { return(false); } // Does AO-DOS support any other kind of disk? if (imagePlugin.Info.Sectors != 800 && imagePlugin.Info.Sectors != 1600) { return(false); } byte[] sector = imagePlugin.ReadSector(0); BootBlock bb = Marshal.ByteArrayToStructureLittleEndian <BootBlock>(sector); return(bb.identifier.SequenceEqual(_identifier)); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } uint sbAddr = REISER4_SUPER_OFFSET / imagePlugin.Info.SectorSize; if (sbAddr == 0) { sbAddr = 1; } uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return; } Superblock reiserSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); if (!_magic.SequenceEqual(reiserSb.magic)) { return; } var sb = new StringBuilder(); sb.AppendLine("Reiser 4 filesystem"); sb.AppendFormat("{0} bytes per block", reiserSb.blocksize).AppendLine(); sb.AppendFormat("Volume disk format: {0}", reiserSb.diskformat).AppendLine(); sb.AppendFormat("Volume UUID: {0}", reiserSb.uuid).AppendLine(); sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(reiserSb.label, Encoding)).AppendLine(); information = sb.ToString(); XmlFsType = new FileSystemType { Type = "Reiser 4 filesystem", ClusterSize = reiserSb.blocksize, Clusters = ((partition.End - partition.Start) * imagePlugin.Info.SectorSize) / reiserSb.blocksize, VolumeName = StringHandlers.CToString(reiserSb.label, Encoding), VolumeSerial = reiserSb.uuid.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(); int sbSizeInBytes = Marshal.SizeOf <SuperBlock>(); uint sbSizeInSectors = (uint)(sbSizeInBytes / imagePlugin.Info.SectorSize); if (sbSizeInBytes % imagePlugin.Info.SectorSize > 0) { sbSizeInSectors++; } byte[] sbSector = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors); SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector); sb.AppendFormat("{0} bytes per zone", supblk.s_zone_size).AppendLine(); sb.AppendFormat("{0} zones in volume ({1} bytes)", supblk.s_nzones, supblk.s_nzones * supblk.s_zone_size). AppendLine(); sb.AppendFormat("{0} inodes", supblk.s_ninodes).AppendLine(); sb.AppendFormat("{0} data zones ({1} bytes)", supblk.s_ndatazones, supblk.s_ndatazones * supblk.s_zone_size).AppendLine(); sb.AppendFormat("{0} imap zones ({1} bytes)", supblk.s_imap_zones, supblk.s_imap_zones * supblk.s_zone_size).AppendLine(); sb.AppendFormat("{0} zmap zones ({1} bytes)", supblk.s_zmap_zones, supblk.s_zmap_zones * supblk.s_zone_size).AppendLine(); sb.AppendFormat("First data zone: {0}", supblk.s_firstdatazone).AppendLine(); sb.AppendFormat("Maximum filesize is {0} bytes ({1} MiB)", supblk.s_max_size, supblk.s_max_size / 1048576). AppendLine(); sb.AppendFormat("{0} zones reserved for kernel images ({1} bytes)", supblk.s_kernzones, supblk.s_kernzones * supblk.s_zone_size).AppendLine(); sb.AppendFormat("First kernel zone: {0}", supblk.s_firstkernzone).AppendLine(); XmlFsType = new FileSystemType { Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(supblk.s_boot_segment), Clusters = supblk.s_nzones, ClusterSize = supblk.s_zone_size, Type = "Xia filesystem" }; information = sb.ToString(); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.UTF8; ulong vmfsSuperOff = VXFS_BASE / imagePlugin.Info.SectorSize; byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); SuperBlock vxSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector); var sbInformation = new StringBuilder(); sbInformation.AppendLine("Veritas file system"); sbInformation.AppendFormat("Volume version {0}", vxSb.vs_version).AppendLine(); sbInformation.AppendFormat("Volume name {0}", StringHandlers.CToString(vxSb.vs_fname, Encoding)). AppendLine(); sbInformation.AppendFormat("Volume has {0} blocks of {1} bytes each", vxSb.vs_bsize, vxSb.vs_size). AppendLine(); sbInformation.AppendFormat("Volume has {0} inodes per block", vxSb.vs_inopb).AppendLine(); sbInformation.AppendFormat("Volume has {0} free inodes", vxSb.vs_ifree).AppendLine(); sbInformation.AppendFormat("Volume has {0} free blocks", vxSb.vs_free).AppendLine(); sbInformation.AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(vxSb.vs_ctime, vxSb.vs_cutime)).AppendLine(); sbInformation.AppendFormat("Volume last modified on {0}", DateHandlers.UnixUnsignedToDateTime(vxSb.vs_wtime, vxSb.vs_wutime)).AppendLine(); if (vxSb.vs_clean != 0) { sbInformation.AppendLine("Volume is dirty"); } information = sbInformation.ToString(); XmlFsType = new FileSystemType { Type = "Veritas file system", CreationDate = DateHandlers.UnixUnsignedToDateTime(vxSb.vs_ctime, vxSb.vs_cutime), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(vxSb.vs_wtime, vxSb.vs_wutime), ModificationDateSpecified = true, Clusters = (ulong)vxSb.vs_size, ClusterSize = (uint)vxSb.vs_bsize, Dirty = vxSb.vs_clean != 0, FreeClusters = (ulong)vxSb.vs_free, FreeClustersSpecified = true }; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = new Radix50(); information = ""; var sb = new StringBuilder(); byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start); HomeBlock homeblock = Marshal.ByteArrayToStructureLittleEndian <HomeBlock>(hbSector); /* 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(hbSector, i); } sb.AppendFormat("Volume format is {0}", StringHandlers.SpacePaddedToString(homeblock.format, Encoding.ASCII)).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}\"", Encoding.GetString(homeblock.ownername).TrimEnd()).AppendLine(); sb.AppendFormat("Volume label: \"{0}\"", Encoding.GetString(homeblock.volname).TrimEnd()).AppendLine(); sb.AppendFormat("Checksum: 0x{0:X4} (calculated 0x{1:X4})", homeblock.checksum, check).AppendLine(); byte[] bootBlock = imagePlugin.ReadSector(0); XmlFsType = new FileSystemType { Type = "RT-11", ClusterSize = (uint)(homeblock.cluster * 512), Clusters = homeblock.cluster, VolumeName = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding), Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlock) }; information = sb.ToString(); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { if (partition.Start + 1 >= imagePlugin.Info.Sectors) { return(false); } byte[] sector = imagePlugin.ReadSector(partition.Start + 1); if (sector.Length < 512) { return(false); } Superblock qnxSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); // Check root directory name if (!_rootDirFname.SequenceEqual(qnxSb.rootDir.di_fname)) { return(false); } // Check sizes are multiple of blocks if (qnxSb.rootDir.di_size % 512 != 0 || qnxSb.inode.di_size % 512 != 0 || qnxSb.boot.di_size % 512 != 0 || qnxSb.altBoot.di_size % 512 != 0) { return(false); } // Check extents are not past device if (qnxSb.rootDir.di_first_xtnt.block + partition.Start >= partition.End || qnxSb.inode.di_first_xtnt.block + partition.Start >= partition.End || qnxSb.boot.di_first_xtnt.block + partition.Start >= partition.End || qnxSb.altBoot.di_first_xtnt.block + partition.Start >= partition.End) { return(false); } // Check inodes are in use if ((qnxSb.rootDir.di_status & 0x01) != 0x01 || (qnxSb.inode.di_status & 0x01) != 0x01 || (qnxSb.boot.di_status & 0x01) != 0x01) { return(false); } // All hail filesystems without identification marks return(true); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { if (partition.Start > 0) { return(false); } if (imagePlugin.Info.SectorSize != 256) { return(false); } if (imagePlugin.Info.Sectors != 683 && imagePlugin.Info.Sectors != 768 && imagePlugin.Info.Sectors != 1366 && imagePlugin.Info.Sectors != 3200) { return(false); } byte[] sector; if (imagePlugin.Info.Sectors == 3200) { sector = imagePlugin.ReadSector(1560); Header cbmHdr = Marshal.ByteArrayToStructureLittleEndian <Header>(sector); if (cbmHdr.diskDosVersion == 0x44 && cbmHdr.dosVersion == 0x33 && cbmHdr.diskVersion == 0x44) { return(true); } } else { sector = imagePlugin.ReadSector(357); BAM cbmBam = Marshal.ByteArrayToStructureLittleEndian <BAM>(sector); if (cbmBam.dosVersion == 0x41 && (cbmBam.doubleSided == 0x00 || cbmBam.doubleSided == 0x80) && cbmBam.unused1 == 0x00 && cbmBam.directoryTrack == 0x12) { return(true); } } return(false); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.UTF8; ulong vmfsSuperOff = VMFS_BASE / imagePlugin.Info.SectorSize; byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); VolumeInfo volInfo = Marshal.ByteArrayToStructureLittleEndian <VolumeInfo>(sector); var sbInformation = new StringBuilder(); sbInformation.AppendLine("VMware file system"); uint ctimeSecs = (uint)(volInfo.ctime / 1000000); uint ctimeNanoSecs = (uint)(volInfo.ctime % 1000000); uint mtimeSecs = (uint)(volInfo.mtime / 1000000); uint mtimeNanoSecs = (uint)(volInfo.mtime % 1000000); sbInformation.AppendFormat("Volume version {0}", volInfo.version).AppendLine(); sbInformation.AppendFormat("Volume name {0}", StringHandlers.CToString(volInfo.name, Encoding)). AppendLine(); sbInformation.AppendFormat("Volume size {0} bytes", volInfo.size * 256).AppendLine(); sbInformation.AppendFormat("Volume UUID {0}", volInfo.uuid).AppendLine(); sbInformation. AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(ctimeSecs, ctimeNanoSecs)). AppendLine(); sbInformation.AppendFormat("Volume last modified on {0}", DateHandlers.UnixUnsignedToDateTime(mtimeSecs, mtimeNanoSecs)).AppendLine(); information = sbInformation.ToString(); XmlFsType = new FileSystemType { Type = "VMware file system", CreationDate = DateHandlers.UnixUnsignedToDateTime(ctimeSecs, ctimeNanoSecs), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(mtimeSecs, mtimeNanoSecs), ModificationDateSpecified = true, Clusters = (volInfo.size * 256) / imagePlugin.Info.SectorSize, ClusterSize = imagePlugin.Info.SectorSize, VolumeSerial = volInfo.uuid.ToString() }; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); byte[] sector = imagePlugin.ReadSector(partition.Start); uint magic = BitConverter.ToUInt32(sector, 0x00); var crSb = new SuperBlock(); bool littleEndian = true; switch (magic) { case CRAM_MAGIC: crSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector); break; case CRAM_CIGAM: crSb = Marshal.ByteArrayToStructureBigEndian <SuperBlock>(sector); littleEndian = false; break; } var sbInformation = new StringBuilder(); sbInformation.AppendLine("Cram file system"); sbInformation.AppendLine(littleEndian ? "Little-endian" : "Big-endian"); sbInformation.AppendFormat("Volume edition {0}", crSb.edition).AppendLine(); sbInformation.AppendFormat("Volume name: {0}", StringHandlers.CToString(crSb.name, Encoding)).AppendLine(); sbInformation.AppendFormat("Volume has {0} bytes", crSb.size).AppendLine(); sbInformation.AppendFormat("Volume has {0} blocks", crSb.blocks).AppendLine(); sbInformation.AppendFormat("Volume has {0} files", crSb.files).AppendLine(); information = sbInformation.ToString(); XmlFsType = new FileSystemType { VolumeName = StringHandlers.CToString(crSb.name, Encoding), Type = "Cram file system", Clusters = crSb.blocks, Files = crSb.files, FilesSpecified = true, FreeClusters = 0, FreeClustersSpecified = true }; }
public bool Identify(IMediaImage imagePlugin, Partition partition) { if (imagePlugin.Info.SectorSize < 512) { return(false); } for (ulong location = 0; location <= 8; location++) { uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } if (partition.Start + location + sbSize >= imagePlugin.Info.Sectors) { break; } byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return(false); } Superblock locusSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); AaruConsole.DebugWriteLine("Locus plugin", "magic at {1} = 0x{0:X8}", locusSb.s_magic, location); if (locusSb.s_magic == LOCUS_MAGIC || locusSb.s_magic == LOCUS_CIGAM || locusSb.s_magic == LOCUS_MAGIC_OLD || locusSb.s_magic == LOCUS_CIGAM_OLD) { return(true); } } return(false); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize; if (partition.Start + bootSectors >= partition.End) { return(false); } byte[] sector = imagePlugin.ReadSector(partition.Start + bootSectors); if (sector.Length < 512) { return(false); } SuperBlock jfsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector); return(jfsSb.s_magic == JFS_MAGIC); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { int sbSizeInBytes = Marshal.SizeOf <SuperBlock>(); uint sbSizeInSectors = (uint)(sbSizeInBytes / imagePlugin.Info.SectorSize); if (sbSizeInBytes % imagePlugin.Info.SectorSize > 0) { sbSizeInSectors++; } if (sbSizeInSectors + partition.Start >= partition.End) { return(false); } byte[] sbSector = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors); SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector); return(supblk.s_magic == XIAFS_SUPER_MAGIC); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { if (imagePlugin.Info.SectorSize < 512) { return(false); } // It should be start of a tape or floppy or file if (partition.Start != 0) { return(false); } uint sbSize = (uint)(Marshal.SizeOf <s_spcl>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <s_spcl>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf <s_spcl>()) { return(false); } spcl16 oldHdr = Marshal.ByteArrayToStructureLittleEndian <spcl16>(sector); spcl_aix aixHdr = Marshal.ByteArrayToStructureLittleEndian <spcl_aix>(sector); s_spcl newHdr = Marshal.ByteArrayToStructureLittleEndian <s_spcl>(sector); AaruConsole.DebugWriteLine("dump(8) plugin", "old magic = 0x{0:X8}", oldHdr.c_magic); AaruConsole.DebugWriteLine("dump(8) plugin", "aix magic = 0x{0:X8}", aixHdr.c_magic); AaruConsole.DebugWriteLine("dump(8) plugin", "new magic = 0x{0:X8}", newHdr.c_magic); return(oldHdr.c_magic == OFS_MAGIC || aixHdr.c_magic == XIX_MAGIC || aixHdr.c_magic == XIX_CIGAM || newHdr.c_magic == OFS_MAGIC || newHdr.c_magic == NFS_MAGIC || newHdr.c_magic == OFS_CIGAM || newHdr.c_magic == NFS_CIGAM || newHdr.c_magic == UFS2_MAGIC || newHdr.c_magic == UFS2_CIGAM); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { if (imagePlugin.Info.SectorSize < F2FS_MIN_SECTOR || imagePlugin.Info.SectorSize > F2FS_MAX_SECTOR) { return(false); } uint sbAddr = F2FS_SUPER_OFFSET / imagePlugin.Info.SectorSize; if (sbAddr == 0) { sbAddr = 1; } uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } if (partition.Start + sbAddr >= partition.End) { return(false); } byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return(false); } Superblock sb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); return(sb.magic == F2FS_MAGIC); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { if (imagePlugin.Info.SectorSize < 512) { return(false); } uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize; if (sbAddr == 0) { sbAddr = 1; } uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } if (partition.Start + sbAddr + sbSize >= partition.End) { return(false); } byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return(false); } Superblock reiserSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); return(_magic35.SequenceEqual(reiserSb.magic) || _magic36.SequenceEqual(reiserSb.magic) || _magicJr.SequenceEqual(reiserSb.magic)); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { uint sectors = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize; uint bootSectors = QNX6_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize; if (partition.Start + bootSectors + sectors >= partition.End) { return(false); } byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors); byte[] sector = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors); if (sector.Length < QNX6_SUPER_BLOCK_SIZE) { return(false); } AudiSuperBlock audiSb = Marshal.ByteArrayToStructureLittleEndian <AudiSuperBlock>(audiSector); SuperBlock qnxSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector); return(qnxSb.magic == QNX6_MAGIC || audiSb.magic == QNX6_MAGIC); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); information = ""; var sb = new StringBuilder(); byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start); HomeBlock homeblock = Marshal.ByteArrayToStructureLittleEndian <HomeBlock>(hbSector); // Optical disc if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc && StringHandlers.CToString(homeblock.format) != "DECFILE11A " && StringHandlers.CToString(homeblock.format) != "DECFILE11B ") { if (hbSector.Length < 0x400) { return; } byte[] tmp = imagePlugin.ReadSector(partition.Start); hbSector = new byte[0x200]; Array.Copy(tmp, 0x200, hbSector, 0, 0x200); homeblock = Marshal.ByteArrayToStructureLittleEndian <HomeBlock>(hbSector); if (StringHandlers.CToString(homeblock.format) != "DECFILE11A " && StringHandlers.CToString(homeblock.format) != "DECFILE11B ") { return; } } if ((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 || StringHandlers.CToString(homeblock.format) != "DECFILE11B ") { sb.AppendLine("The following information may be incorrect for this volume."); } if (homeblock.resfiles < 5 || homeblock.devtype != 0) { sb.AppendLine("This volume may be corrupted."); } sb.AppendFormat("Volume format is {0}", StringHandlers.SpacePaddedToString(homeblock.format, Encoding)). AppendLine(); sb.AppendFormat("Volume is Level {0} revision {1}", (homeblock.struclev & 0xFF00) >> 8, homeblock.struclev & 0xFF).AppendLine(); sb.AppendFormat("Lowest structure in the volume is Level {0}, revision {1}", (homeblock.lowstruclev & 0xFF00) >> 8, homeblock.lowstruclev & 0xFF).AppendLine(); sb.AppendFormat("Highest structure in the volume is Level {0}, revision {1}", (homeblock.highstruclev & 0xFF00) >> 8, homeblock.highstruclev & 0xFF).AppendLine(); sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512). AppendLine(); sb.AppendFormat("This home block is on sector {0} (VBN {1})", homeblock.homelbn, homeblock.homevbn). AppendLine(); sb.AppendFormat("Secondary home block is on sector {0} (VBN {1})", homeblock.alhomelbn, homeblock.alhomevbn).AppendLine(); sb.AppendFormat("Volume bitmap starts in sector {0} (VBN {1})", homeblock.ibmaplbn, homeblock.ibmapvbn). AppendLine(); sb.AppendFormat("Volume bitmap runs for {0} sectors ({1} bytes)", homeblock.ibmapsize, homeblock.ibmapsize * 512).AppendLine(); sb.AppendFormat("Backup INDEXF.SYS;1 is in sector {0} (VBN {1})", homeblock.altidxlbn, homeblock.altidxvbn). AppendLine(); sb.AppendFormat("{0} maximum files on the volume", homeblock.maxfiles).AppendLine(); sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine(); if (homeblock.rvn > 0 && homeblock.setcount > 0 && StringHandlers.CToString(homeblock.strucname) != " ") { sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount, StringHandlers.SpacePaddedToString(homeblock.strucname, Encoding)).AppendLine(); } sb.AppendFormat("Volume owner is \"{0}\" (ID 0x{1:X8})", StringHandlers.SpacePaddedToString(homeblock.ownername, Encoding), homeblock.volowner). AppendLine(); sb.AppendFormat("Volume label: \"{0}\"", StringHandlers.SpacePaddedToString(homeblock.volname, Encoding)). AppendLine(); sb.AppendFormat("Drive serial number: 0x{0:X8}", homeblock.serialnum).AppendLine(); sb.AppendFormat("Volume was created on {0}", DateHandlers.VmsToDateTime(homeblock.credate)).AppendLine(); if (homeblock.revdate > 0) { sb.AppendFormat("Volume was last modified on {0}", DateHandlers.VmsToDateTime(homeblock.revdate)). AppendLine(); } if (homeblock.copydate > 0) { sb.AppendFormat("Volume copied on {0}", DateHandlers.VmsToDateTime(homeblock.copydate)).AppendLine(); } sb.AppendFormat("Checksums: 0x{0:X4} and 0x{1:X4}", homeblock.checksum1, homeblock.checksum2).AppendLine(); sb.AppendLine("Flags:"); sb.AppendFormat("Window: {0}", homeblock.window).AppendLine(); sb.AppendFormat("Cached directores: {0}", homeblock.lru_lim).AppendLine(); sb.AppendFormat("Default allocation: {0} blocks", homeblock.extend).AppendLine(); if ((homeblock.volchar & 0x01) == 0x01) { sb.AppendLine("Readings should be verified"); } if ((homeblock.volchar & 0x02) == 0x02) { sb.AppendLine("Writings should be verified"); } if ((homeblock.volchar & 0x04) == 0x04) { sb.AppendLine("Files should be erased or overwritten when deleted"); } if ((homeblock.volchar & 0x08) == 0x08) { sb.AppendLine("Highwater mark is to be disabled"); } if ((homeblock.volchar & 0x10) == 0x10) { sb.AppendLine("Classification checks are enabled"); } sb.AppendLine("Volume permissions (r = read, w = write, c = create, d = delete)"); sb.AppendLine("System, owner, group, world"); // System sb.Append((homeblock.protect & 0x1000) == 0x1000 ? "-" : "r"); sb.Append((homeblock.protect & 0x2000) == 0x2000 ? "-" : "w"); sb.Append((homeblock.protect & 0x4000) == 0x4000 ? "-" : "c"); sb.Append((homeblock.protect & 0x8000) == 0x8000 ? "-" : "d"); // Owner sb.Append((homeblock.protect & 0x100) == 0x100 ? "-" : "r"); sb.Append((homeblock.protect & 0x200) == 0x200 ? "-" : "w"); sb.Append((homeblock.protect & 0x400) == 0x400 ? "-" : "c"); sb.Append((homeblock.protect & 0x800) == 0x800 ? "-" : "d"); // Group sb.Append((homeblock.protect & 0x10) == 0x10 ? "-" : "r"); sb.Append((homeblock.protect & 0x20) == 0x20 ? "-" : "w"); sb.Append((homeblock.protect & 0x40) == 0x40 ? "-" : "c"); sb.Append((homeblock.protect & 0x80) == 0x80 ? "-" : "d"); // World (other) sb.Append((homeblock.protect & 0x1) == 0x1 ? "-" : "r"); sb.Append((homeblock.protect & 0x2) == 0x2 ? "-" : "w"); sb.Append((homeblock.protect & 0x4) == 0x4 ? "-" : "c"); sb.Append((homeblock.protect & 0x8) == 0x8 ? "-" : "d"); sb.AppendLine(); sb.AppendLine("Unknown structures:"); sb.AppendFormat("Security mask: 0x{0:X8}", homeblock.sec_mask).AppendLine(); sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine(); sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine(); XmlFsType = new FileSystemType { Type = "FILES-11", ClusterSize = (uint)(homeblock.cluster * 512), Clusters = partition.Size / (ulong)(homeblock.cluster * 512), VolumeName = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding), VolumeSerial = $"{homeblock.serialnum:X8}" }; if (homeblock.credate > 0) { XmlFsType.CreationDate = DateHandlers.VmsToDateTime(homeblock.credate); XmlFsType.CreationDateSpecified = true; } if (homeblock.revdate > 0) { XmlFsType.ModificationDate = DateHandlers.VmsToDateTime(homeblock.revdate); XmlFsType.ModificationDateSpecified = true; } information = sb.ToString(); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } if (partition.Start != 0) { return; } uint sbSize = (uint)(Marshal.SizeOf <s_spcl>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <s_spcl>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf <s_spcl>()) { return; } spcl16 oldHdr = Marshal.ByteArrayToStructureLittleEndian <spcl16>(sector); spcl_aix aixHdr = Marshal.ByteArrayToStructureLittleEndian <spcl_aix>(sector); s_spcl newHdr = Marshal.ByteArrayToStructureLittleEndian <s_spcl>(sector); bool useOld = false; bool useAix = false; if (newHdr.c_magic == OFS_MAGIC || newHdr.c_magic == NFS_MAGIC || newHdr.c_magic == OFS_CIGAM || newHdr.c_magic == NFS_CIGAM || newHdr.c_magic == UFS2_MAGIC || newHdr.c_magic == UFS2_CIGAM) { if (newHdr.c_magic == OFS_CIGAM || newHdr.c_magic == NFS_CIGAM || newHdr.c_magic == UFS2_CIGAM) { newHdr = Marshal.ByteArrayToStructureBigEndian <s_spcl>(sector); } } else if (aixHdr.c_magic == XIX_MAGIC || aixHdr.c_magic == XIX_CIGAM) { useAix = true; if (aixHdr.c_magic == XIX_CIGAM) { aixHdr = Marshal.ByteArrayToStructureBigEndian <spcl_aix>(sector); } } else if (oldHdr.c_magic == OFS_MAGIC) { useOld = true; // Swap PDP-11 endian oldHdr.c_date = (int)Swapping.PDPFromLittleEndian((uint)oldHdr.c_date); oldHdr.c_ddate = (int)Swapping.PDPFromLittleEndian((uint)oldHdr.c_ddate); } else { information = "Could not read dump(8) header block"; return; } var sb = new StringBuilder(); XmlFsType = new FileSystemType { ClusterSize = 1024, Clusters = partition.Size / 1024 }; if (useOld) { XmlFsType.Type = "Old 16-bit dump(8)"; sb.AppendLine(XmlFsType.Type); if (oldHdr.c_date > 0) { XmlFsType.CreationDate = DateHandlers.UnixToDateTime(oldHdr.c_date); XmlFsType.CreationDateSpecified = true; sb.AppendFormat("Dump created on {0}", XmlFsType.CreationDate).AppendLine(); } if (oldHdr.c_ddate > 0) { XmlFsType.BackupDate = DateHandlers.UnixToDateTime(oldHdr.c_ddate); XmlFsType.BackupDateSpecified = true; sb.AppendFormat("Previous dump created on {0}", XmlFsType.BackupDate).AppendLine(); } sb.AppendFormat("Dump volume number: {0}", oldHdr.c_volume).AppendLine(); } else if (useAix) { XmlFsType.Type = "AIX dump(8)"; sb.AppendLine(XmlFsType.Type); if (aixHdr.c_date > 0) { XmlFsType.CreationDate = DateHandlers.UnixToDateTime(aixHdr.c_date); XmlFsType.CreationDateSpecified = true; sb.AppendFormat("Dump created on {0}", XmlFsType.CreationDate).AppendLine(); } if (aixHdr.c_ddate > 0) { XmlFsType.BackupDate = DateHandlers.UnixToDateTime(aixHdr.c_ddate); XmlFsType.BackupDateSpecified = true; sb.AppendFormat("Previous dump created on {0}", XmlFsType.BackupDate).AppendLine(); } sb.AppendFormat("Dump volume number: {0}", aixHdr.c_volume).AppendLine(); } else { XmlFsType.Type = "dump(8)"; sb.AppendLine(XmlFsType.Type); if (newHdr.c_ndate > 0) { XmlFsType.CreationDate = DateHandlers.UnixToDateTime(newHdr.c_ndate); XmlFsType.CreationDateSpecified = true; sb.AppendFormat("Dump created on {0}", XmlFsType.CreationDate).AppendLine(); } else if (newHdr.c_date > 0) { XmlFsType.CreationDate = DateHandlers.UnixToDateTime(newHdr.c_date); XmlFsType.CreationDateSpecified = true; sb.AppendFormat("Dump created on {0}", XmlFsType.CreationDate).AppendLine(); } if (newHdr.c_nddate > 0) { XmlFsType.BackupDate = DateHandlers.UnixToDateTime(newHdr.c_nddate); XmlFsType.BackupDateSpecified = true; sb.AppendFormat("Previous dump created on {0}", XmlFsType.BackupDate).AppendLine(); } else if (newHdr.c_ddate > 0) { XmlFsType.BackupDate = DateHandlers.UnixToDateTime(newHdr.c_ddate); XmlFsType.BackupDateSpecified = true; sb.AppendFormat("Previous dump created on {0}", XmlFsType.BackupDate).AppendLine(); } sb.AppendFormat("Dump volume number: {0}", newHdr.c_volume).AppendLine(); sb.AppendFormat("Dump level: {0}", newHdr.c_level).AppendLine(); string dumpname = StringHandlers.CToString(newHdr.c_label); if (!string.IsNullOrEmpty(dumpname)) { XmlFsType.VolumeName = dumpname; sb.AppendFormat("Dump label: {0}", dumpname).AppendLine(); } string str = StringHandlers.CToString(newHdr.c_filesys); if (!string.IsNullOrEmpty(str)) { sb.AppendFormat("Dumped filesystem name: {0}", str).AppendLine(); } str = StringHandlers.CToString(newHdr.c_dev); if (!string.IsNullOrEmpty(str)) { sb.AppendFormat("Dumped device: {0}", str).AppendLine(); } str = StringHandlers.CToString(newHdr.c_host); if (!string.IsNullOrEmpty(str)) { sb.AppendFormat("Dump hostname: {0}", str).AppendLine(); } } information = sb.ToString(); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; byte[] sector = imagePlugin.ReadSector(partition.Start + 1); if (sector.Length < 512) { return; } Superblock qnxSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); // Too much useless information /* * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_fname = {0}", CurrentEncoding.GetString(qnxSb.rootDir.di_fname)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_size = {0}", qnxSb.rootDir.di_size); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_first_xtnt.block = {0}", qnxSb.rootDir.di_first_xtnt.block); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_first_xtnt.length = {0}", qnxSb.rootDir.di_first_xtnt.length); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_xblk = {0}", qnxSb.rootDir.di_xblk); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_ftime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_mtime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_atime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_ctime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_num_xtnts = {0}", qnxSb.rootDir.di_num_xtnts); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_mode = {0}", Convert.ToString(qnxSb.rootDir.di_mode, 8)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_uid = {0}", qnxSb.rootDir.di_uid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_gid = {0}", qnxSb.rootDir.di_gid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_nlink = {0}", qnxSb.rootDir.di_nlink); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_zero = {0}", qnxSb.rootDir.di_zero); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_type = {0}", qnxSb.rootDir.di_type); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_status = {0}", qnxSb.rootDir.di_status); * * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_fname = {0}", CurrentEncoding.GetString(qnxSb.inode.di_fname)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_size = {0}", qnxSb.inode.di_size); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_first_xtnt.block = {0}", qnxSb.inode.di_first_xtnt.block); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_first_xtnt.length = {0}", qnxSb.inode.di_first_xtnt.length); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_xblk = {0}", qnxSb.inode.di_xblk); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_ftime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_mtime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_atime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_ctime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_num_xtnts = {0}", qnxSb.inode.di_num_xtnts); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_mode = {0}", Convert.ToString(qnxSb.inode.di_mode, 8)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_uid = {0}", qnxSb.inode.di_uid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_gid = {0}", qnxSb.inode.di_gid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_nlink = {0}", qnxSb.inode.di_nlink); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_zero = {0}", qnxSb.inode.di_zero); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_type = {0}", qnxSb.inode.di_type); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_status = {0}", qnxSb.inode.di_status); * * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_fname = {0}", CurrentEncoding.GetString(qnxSb.boot.di_fname)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_size = {0}", qnxSb.boot.di_size); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_first_xtnt.block = {0}", qnxSb.boot.di_first_xtnt.block); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_first_xtnt.length = {0}", qnxSb.boot.di_first_xtnt.length); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_xblk = {0}", qnxSb.boot.di_xblk); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_ftime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_mtime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_atime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_ctime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_num_xtnts = {0}", qnxSb.boot.di_num_xtnts); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_mode = {0}", Convert.ToString(qnxSb.boot.di_mode, 8)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_uid = {0}", qnxSb.boot.di_uid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_gid = {0}", qnxSb.boot.di_gid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_nlink = {0}", qnxSb.boot.di_nlink); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_zero = {0}", qnxSb.boot.di_zero); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_type = {0}", qnxSb.boot.di_type); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_status = {0}", qnxSb.boot.di_status); * * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_fname = {0}", CurrentEncoding.GetString(qnxSb.altBoot.di_fname)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_size = {0}", qnxSb.altBoot.di_size); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_first_xtnt.block = {0}", qnxSb.altBoot.di_first_xtnt.block); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_first_xtnt.length = {0}", qnxSb.altBoot.di_first_xtnt.length); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_xblk = {0}", qnxSb.altBoot.di_xblk); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_ftime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_mtime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_atime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_ctime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_num_xtnts = {0}", qnxSb.altBoot.di_num_xtnts); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_mode = {0}", Convert.ToString(qnxSb.altBoot.di_mode, 8)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_uid = {0}", qnxSb.altBoot.di_uid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_gid = {0}", qnxSb.altBoot.di_gid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_nlink = {0}", qnxSb.altBoot.di_nlink); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_zero = {0}", qnxSb.altBoot.di_zero); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_type = {0}", qnxSb.altBoot.di_type); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_status = {0}", qnxSb.altBoot.di_status); */ information = $"QNX4 filesystem\nCreated on {DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_ftime)}\n"; XmlFsType = new FileSystemType { Type = "QNX4 filesystem", Clusters = partition.Length, ClusterSize = 512, CreationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_ftime), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_mtime), ModificationDateSpecified = true }; XmlFsType.Bootable |= qnxSb.boot.di_size != 0 || qnxSb.altBoot.di_size != 0; }
public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset) { partitions = new List <Partition>(); if (imagePlugin.Info.SectorSize < 512) { return(false); } if (sectorOffset + 2 >= imagePlugin.Info.Sectors) { return(false); } bool useDkl = false, useDkl8 = false, useDkl16 = false; byte[] sunSector = imagePlugin.ReadSector(sectorOffset); dk_label dkl = Marshal.ByteArrayToStructureLittleEndian <dk_label>(sunSector); dk_label8 dkl8 = Marshal.ByteArrayToStructureLittleEndian <dk_label8>(sunSector); dk_label16 dkl16 = Marshal.ByteArrayToStructureLittleEndian <dk_label16>(sunSector); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_magic = 0x{0:X4}", dkl.dkl_magic); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_sanity = 0x{0:X8}", dkl8.dkl_vtoc.v_sanity); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sanity = 0x{0:X8}", dkl16.dkl_vtoc.v_sanity); if (dkl.dkl_magic == DKL_MAGIC || dkl.dkl_magic == DKL_CIGAM) { if (dkl16.dkl_vtoc.v_sanity == VTOC_SANE || dkl16.dkl_vtoc.v_sanity == VTOC_ENAS) { useDkl16 = true; } else if (dkl8.dkl_vtoc.v_sanity == VTOC_SANE || dkl8.dkl_vtoc.v_sanity == VTOC_ENAS) { useDkl8 = true; } else { useDkl = true; } } if (!useDkl && !useDkl8 && !useDkl16) { sunSector = imagePlugin.ReadSector(sectorOffset + 1); dkl = Marshal.ByteArrayToStructureLittleEndian <dk_label>(sunSector); dkl8 = Marshal.ByteArrayToStructureLittleEndian <dk_label8>(sunSector); dkl16 = Marshal.ByteArrayToStructureLittleEndian <dk_label16>(sunSector); if (dkl.dkl_magic == DKL_MAGIC || dkl.dkl_magic == DKL_CIGAM) { if (dkl16.dkl_vtoc.v_sanity == VTOC_SANE || dkl16.dkl_vtoc.v_sanity == VTOC_ENAS) { useDkl16 = true; } else if (dkl8.dkl_vtoc.v_sanity == VTOC_SANE || dkl8.dkl_vtoc.v_sanity == VTOC_ENAS) { useDkl8 = true; } else { useDkl = true; } } } if (!useDkl && !useDkl8 && !useDkl16) { return(false); } if (useDkl16 && dkl16.dkl_magic == DKL_CIGAM) { dkl16 = SwapDiskLabel(dkl16); } else if (useDkl8 && dkl8.dkl_magic == DKL_CIGAM) { dkl8 = SwapDiskLabel(dkl8); } else if (useDkl && dkl.dkl_magic == DKL_CIGAM) { dkl = SwapDiskLabel(dkl); } if (useDkl) { ulong sectorsPerCylinder = (ulong)(dkl.dkl_nsect * dkl.dkl_nhead); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_asciilabel = \"{0}\"", StringHandlers.CToString(dkl.dkl_asciilabel)); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_rpm = {0}", dkl.dkl_rpm); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_pcyl = {0}", dkl.dkl_pcyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_apc = {0}", dkl.dkl_apc); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_gap1 = {0}", dkl.dkl_gap1); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_gap2 = {0}", dkl.dkl_gap2); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_intrlv = {0}", dkl.dkl_intrlv); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_ncyl = {0}", dkl.dkl_ncyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_acyl = {0}", dkl.dkl_acyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_nhead = {0}", dkl.dkl_nhead); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_nsect = {0}", dkl.dkl_nsect); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_bhead = {0}", dkl.dkl_bhead); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_ppart = {0}", dkl.dkl_ppart); for (int i = 0; i < NDKMAP; i++) { AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_map[{0}].dkl_cylno = {1}", i, dkl.dkl_map[i].dkl_cylno); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_map[{0}].dkl_nblk = {1}", i, dkl.dkl_map[i].dkl_nblk); } AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_magic = 0x{0:X4}", dkl.dkl_magic); AaruConsole.DebugWriteLine("Sun plugin", "dkl.dkl_cksum = 0x{0:X4}", dkl.dkl_cksum); AaruConsole.DebugWriteLine("Sun plugin", "sectorsPerCylinder = {0}", sectorsPerCylinder); for (int i = 0; i < NDKMAP; i++) { if (dkl.dkl_map[i].dkl_cylno > 0 && dkl.dkl_map[i].dkl_nblk > 0) { var part = new Partition { Size = (ulong)dkl.dkl_map[i].dkl_nblk * DK_LABEL_SIZE, Length = (ulong)((dkl.dkl_map[i].dkl_nblk * DK_LABEL_SIZE) / imagePlugin.Info.SectorSize), Sequence = (ulong)i, Offset = (((ulong)dkl.dkl_map[i].dkl_cylno * sectorsPerCylinder) + sectorOffset) * DK_LABEL_SIZE, Start = ((((ulong)dkl.dkl_map[i].dkl_cylno * sectorsPerCylinder) + sectorOffset) * DK_LABEL_SIZE) / imagePlugin.Info.SectorSize, Type = "SunOS partition", Scheme = Name }; if (part.Start < imagePlugin.Info.Sectors && part.End <= imagePlugin.Info.Sectors) { partitions.Add(part); } } } } else if (useDkl8) { ulong sectorsPerCylinder = (ulong)(dkl8.dkl_nsect * dkl8.dkl_nhead); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_asciilabel = \"{0}\"", StringHandlers.CToString(dkl8.dkl_asciilabel)); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_version = {0}", dkl8.dkl_vtoc.v_version); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_volume = \"{0}\"", StringHandlers.CToString(dkl8.dkl_vtoc.v_volume)); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_nparts = {0}", dkl8.dkl_vtoc.v_nparts); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_sanity = 0x{0:X8}", dkl8.dkl_vtoc.v_sanity); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_write_reinstruct = {0}", dkl8.dkl_write_reinstruct); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_read_reinstruct = {0}", dkl8.dkl_read_reinstruct); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_rpm = {0}", dkl8.dkl_rpm); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_pcyl = {0}", dkl8.dkl_pcyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_apc = {0}", dkl8.dkl_apc); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs1 = {0}", dkl8.dkl_obs1); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs2 = {0}", dkl8.dkl_obs2); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_intrlv = {0}", dkl8.dkl_intrlv); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_ncyl = {0}", dkl8.dkl_ncyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_acyl = {0}", dkl8.dkl_acyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_nhead = {0}", dkl8.dkl_nhead); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_nsect = {0}", dkl8.dkl_nsect); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs3 = {0}", dkl8.dkl_obs3); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_obs4 = {0}", dkl8.dkl_obs4); for (int i = 0; i < NDKMAP; i++) { AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_map[{0}].dkl_cylno = {1}", i, dkl8.dkl_map[i].dkl_cylno); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_map[{0}].dkl_nblk = {1}", i, dkl8.dkl_map[i].dkl_nblk); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_part[{0}].p_tag = {1} ({2})", i, dkl8.dkl_vtoc.v_part[i].p_tag, (ushort)dkl8.dkl_vtoc.v_part[i].p_tag); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_part[{0}].p_flag = {1} ({2})", i, dkl8.dkl_vtoc.v_part[i].p_flag, (ushort)dkl8.dkl_vtoc.v_part[i].p_flag); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_vtoc.v_timestamp[{0}] = {1}", i, DateHandlers.UnixToDateTime(dkl8.dkl_vtoc.v_timestamp[i])); } AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_magic = 0x{0:X4}", dkl8.dkl_magic); AaruConsole.DebugWriteLine("Sun plugin", "dkl8.dkl_cksum = 0x{0:X4}", dkl8.dkl_cksum); AaruConsole.DebugWriteLine("Sun plugin", "sectorsPerCylinder = {0}", sectorsPerCylinder); if (dkl8.dkl_vtoc.v_nparts > NDKMAP) { return(false); } for (int i = 0; i < dkl8.dkl_vtoc.v_nparts; i++) { if (dkl8.dkl_map[i].dkl_nblk > 0 && dkl8.dkl_vtoc.v_part[i].p_tag != SunTag.SunEmpty && dkl8.dkl_vtoc.v_part[i].p_tag != SunTag.SunWholeDisk) { var part = new Partition { Description = SunFlagsToString(dkl8.dkl_vtoc.v_part[i].p_flag), Size = (ulong)dkl8.dkl_map[i].dkl_nblk * DK_LABEL_SIZE, Length = (ulong)((dkl8.dkl_map[i].dkl_nblk * DK_LABEL_SIZE) / imagePlugin.Info.SectorSize), Sequence = (ulong)i, Offset = (((ulong)dkl8.dkl_map[i].dkl_cylno * sectorsPerCylinder) + sectorOffset) * DK_LABEL_SIZE, Start = ((((ulong)dkl8.dkl_map[i].dkl_cylno * sectorsPerCylinder) + sectorOffset) * DK_LABEL_SIZE) / imagePlugin.Info.SectorSize, Type = SunIdToString(dkl8.dkl_vtoc.v_part[i].p_tag), Scheme = Name }; if (dkl8.dkl_vtoc.v_timestamp[i] != 0) { part.Description += $"\nPartition timestamped on {DateHandlers.UnixToDateTime(dkl8.dkl_vtoc.v_timestamp[i])}"; } if (part.Start < imagePlugin.Info.Sectors && part.End <= imagePlugin.Info.Sectors) { partitions.Add(part); } } } } else { AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sanity = 0x{0:X8}", dkl16.dkl_vtoc.v_sanity); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_version = {0}", dkl16.dkl_vtoc.v_version); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_volume = \"{0}\"", StringHandlers.CToString(dkl16.dkl_vtoc.v_volume)); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_sectorsz = {0}", dkl16.dkl_vtoc.v_sectorsz); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_nparts = {0}", dkl16.dkl_vtoc.v_nparts); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_asciilabel = \"{0}\"", StringHandlers.CToString(dkl16.dkl_vtoc.v_asciilabel)); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_pcyl = {0}", dkl16.dkl_pcyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_ncyl = {0}", dkl16.dkl_ncyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_acyl = {0}", dkl16.dkl_acyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_bcyl = {0}", dkl16.dkl_bcyl); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_nhead = {0}", dkl16.dkl_nhead); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_nsect = {0}", dkl16.dkl_nsect); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_intrlv = {0}", dkl16.dkl_intrlv); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_skew = {0}", dkl16.dkl_skew); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_apc = {0}", dkl16.dkl_apc); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_rpm = {0}", dkl16.dkl_rpm); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_write_reinstruct = {0}", dkl16.dkl_write_reinstruct); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_read_reinstruct = {0}", dkl16.dkl_read_reinstruct); for (int i = 0; i < NDKMAP16; i++) { AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_start = {1}", i, dkl16.dkl_vtoc.v_part[i].p_start); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_size = {1}", i, dkl16.dkl_vtoc.v_part[i].p_size); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_tag = {1} ({2})", i, dkl16.dkl_vtoc.v_part[i].p_tag, (ushort)dkl16.dkl_vtoc.v_part[i].p_tag); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_part[{0}].p_flag = {1} ({2})", i, dkl16.dkl_vtoc.v_part[i].p_flag, (ushort)dkl16.dkl_vtoc.v_part[i].p_flag); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_vtoc.v_timestamp[{0}] = {1}", i, DateHandlers.UnixToDateTime(dkl16.dkl_vtoc.v_timestamp[i])); } AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_magic = 0x{0:X4}", dkl16.dkl_magic); AaruConsole.DebugWriteLine("Sun plugin", "dkl16.dkl_cksum = 0x{0:X4}", dkl16.dkl_cksum); if (dkl16.dkl_vtoc.v_nparts > NDKMAP16) { return(false); } for (int i = 0; i < dkl16.dkl_vtoc.v_nparts; i++) { if (dkl16.dkl_vtoc.v_part[i].p_size > 0 && dkl16.dkl_vtoc.v_part[i].p_tag != SunTag.SunEmpty && dkl16.dkl_vtoc.v_part[i].p_tag != SunTag.SunWholeDisk) { var part = new Partition { Description = SunFlagsToString(dkl16.dkl_vtoc.v_part[i].p_flag), Size = (ulong)dkl16.dkl_vtoc.v_part[i].p_size * dkl16.dkl_vtoc.v_sectorsz, Length = (ulong)((dkl16.dkl_vtoc.v_part[i].p_size * dkl16.dkl_vtoc.v_sectorsz) / imagePlugin.Info.SectorSize), Sequence = (ulong)i, Offset = ((ulong)dkl16.dkl_vtoc.v_part[i].p_start + sectorOffset) * dkl16.dkl_vtoc.v_sectorsz, Start = (((ulong)dkl16.dkl_vtoc.v_part[i].p_start + sectorOffset) * dkl16.dkl_vtoc.v_sectorsz) / imagePlugin.Info.SectorSize, Type = SunIdToString(dkl16.dkl_vtoc.v_part[i].p_tag), Scheme = Name }; if (dkl16.dkl_vtoc.v_timestamp[i] != 0) { part.Description += $"\nPartition timestamped on {DateHandlers.UnixToDateTime(dkl16.dkl_vtoc.v_timestamp[i])}"; } if (part.Start < imagePlugin.Info.Sectors && part.End <= imagePlugin.Info.Sectors) { partitions.Add(part); } } } } return(partitions.Count > 0); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize; if (sbAddr == 0) { sbAddr = 1; } uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); if (sector.Length < Marshal.SizeOf <Superblock>()) { return; } Superblock reiserSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); if (!_magic35.SequenceEqual(reiserSb.magic) && !_magic36.SequenceEqual(reiserSb.magic) && !_magicJr.SequenceEqual(reiserSb.magic)) { return; } var sb = new StringBuilder(); if (_magic35.SequenceEqual(reiserSb.magic)) { sb.AppendLine("Reiser 3.5 filesystem"); } else if (_magic36.SequenceEqual(reiserSb.magic)) { sb.AppendLine("Reiser 3.6 filesystem"); } else if (_magicJr.SequenceEqual(reiserSb.magic)) { sb.AppendLine("Reiser Jr. filesystem"); } sb.AppendFormat("Volume has {0} blocks with {1} blocks free", reiserSb.block_count, reiserSb.free_blocks). AppendLine(); sb.AppendFormat("{0} bytes per block", reiserSb.blocksize).AppendLine(); sb.AppendFormat("Root directory resides on block {0}", reiserSb.root_block).AppendLine(); if (reiserSb.umount_state == 2) { sb.AppendLine("Volume has not been cleanly umounted"); } sb.AppendFormat("Volume last checked on {0}", DateHandlers.UnixUnsignedToDateTime(reiserSb.last_check)). AppendLine(); if (reiserSb.version >= 2) { sb.AppendFormat("Volume UUID: {0}", reiserSb.uuid).AppendLine(); sb.AppendFormat("Volume name: {0}", Encoding.GetString(reiserSb.label)).AppendLine(); } information = sb.ToString(); XmlFsType = new FileSystemType(); if (_magic35.SequenceEqual(reiserSb.magic)) { XmlFsType.Type = "Reiser 3.5 filesystem"; } else if (_magic36.SequenceEqual(reiserSb.magic)) { XmlFsType.Type = "Reiser 3.6 filesystem"; } else if (_magicJr.SequenceEqual(reiserSb.magic)) { XmlFsType.Type = "Reiser Jr. filesystem"; } XmlFsType.ClusterSize = reiserSb.blocksize; XmlFsType.Clusters = reiserSb.block_count; XmlFsType.FreeClusters = reiserSb.free_blocks; XmlFsType.FreeClustersSpecified = true; XmlFsType.Dirty = reiserSb.umount_state == 2; if (reiserSb.version < 2) { return; } XmlFsType.VolumeName = Encoding.GetString(reiserSb.label); XmlFsType.VolumeSerial = reiserSb.uuid.ToString(); }
static bool GetMinix(IMediaImage imagePlugin, ulong start, ulong divider, ulong sectorOffset, uint sectorSize, out List <Partition> partitions) { partitions = new List <Partition>(); byte[] sector = imagePlugin.ReadSector(start); ExtendedBootRecord mnx = Marshal.ByteArrayToStructureLittleEndian <ExtendedBootRecord>(sector); AaruConsole.DebugWriteLine("MBR plugin", "mnx.magic == MBR_Magic = {0}", mnx.magic == MBR_MAGIC); if (mnx.magic != MBR_MAGIC) { return(false); } bool anyMnx = false; foreach (PartitionEntry mnxEntry in mnx.entries) { bool mnxValid = true; byte startSector = (byte)(mnxEntry.start_sector & 0x3F); ushort startCylinder = (ushort)(((mnxEntry.start_sector & 0xC0) << 2) | mnxEntry.start_cylinder); byte endSector = (byte)(mnxEntry.end_sector & 0x3F); ushort endCylinder = (ushort)(((mnxEntry.end_sector & 0xC0) << 2) | mnxEntry.end_cylinder); ulong mnxStart = mnxEntry.lba_start; ulong mnxSectors = mnxEntry.lba_sectors; AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.status {0}", mnxEntry.status); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.type {0}", mnxEntry.type); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.lba_start {0}", mnxEntry.lba_start); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.lba_sectors {0}", mnxEntry.lba_sectors); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.start_cylinder {0}", startCylinder); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.start_head {0}", mnxEntry.start_head); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.start_sector {0}", startSector); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.end_cylinder {0}", endCylinder); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.end_head {0}", mnxEntry.end_head); AaruConsole.DebugWriteLine("MBR plugin", "mnx_entry.end_sector {0}", endSector); mnxValid &= mnxEntry.status == 0x00 || mnxEntry.status == 0x80; mnxValid &= mnxEntry.type == 0x81 || mnxEntry.type == 0x80; mnxValid &= mnxEntry.lba_start != 0 || mnxEntry.lba_sectors != 0 || mnxEntry.start_cylinder != 0 || mnxEntry.start_head != 0 || mnxEntry.start_sector != 0 || mnxEntry.end_cylinder != 0 || mnxEntry.end_head != 0 || mnxEntry.end_sector != 0; if (mnxEntry.lba_start == 0 && mnxEntry.lba_sectors == 0 && mnxValid) { mnxStart = CHS.ToLBA(startCylinder, mnxEntry.start_head, startSector, imagePlugin.Info.Heads, imagePlugin.Info.SectorsPerTrack); mnxSectors = CHS.ToLBA(endCylinder, mnxEntry.end_head, mnxEntry.end_sector, imagePlugin.Info.Heads, imagePlugin.Info.SectorsPerTrack) - mnxStart; } // For optical media mnxStart /= divider; mnxSectors /= divider; AaruConsole.DebugWriteLine("MBR plugin", "mnx_start {0}", mnxStart); AaruConsole.DebugWriteLine("MBR plugin", "mnx_sectors {0}", mnxSectors); if (!mnxValid) { continue; } var part = new Partition(); if (mnxStart > 0 && mnxSectors > 0) { part.Start = mnxStart + sectorOffset; part.Length = mnxSectors; part.Offset = part.Start * sectorSize; part.Size = part.Length * sectorSize; } else { mnxValid = false; } if (!mnxValid) { continue; } anyMnx = true; part.Type = "MINIX"; part.Name = "MINIX"; part.Description = mnxEntry.status == 0x80 ? "Partition is bootable." : ""; part.Scheme = "MINIX"; partitions.Add(part); } return(anyMnx); }
public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset) { partitions = new List <Partition>(); // I think Apricot can't chain partitions so. if (sectorOffset != 0) { return(false); } byte[] sector = imagePlugin.ReadSector(0); if (sector.Length < 512) { return(false); } Label label = Marshal.ByteArrayToStructureLittleEndian <Label>(sector); // Not much to check but... ulong deviceSectors = imagePlugin.Info.Sectors; ulong deviceSizeAccordingToLabel = label.cylinders * label.heads * label.spt; if (label.operatingSystem > 4 || label.bootType > 5 || label.partitionCount > 8 || deviceSizeAccordingToLabel > deviceSectors || label.firstDataBlock > deviceSectors) { return(false); } AaruConsole.DebugWriteLine("Apricot partitions", "label.version = \"{0}\"", StringHandlers.CToString(label.version)); AaruConsole.DebugWriteLine("Apricot partitions", "label.operatingSystem = {0} ({1})", label.operatingSystem, label.operatingSystem < _operatingSystemCodes.Length ? _operatingSystemCodes[label.operatingSystem] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.writeProtected = {0}", label.writeProtected); AaruConsole.DebugWriteLine("Apricot partitions", "label.copyProtected = {0}", label.copyProtected); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootType = {0} ({1})", label.bootType, label.bootType < _bootTypeCodes.Length ? _bootTypeCodes[label.bootType] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitionCount = {0}", label.partitionCount); AaruConsole.DebugWriteLine("Apricot partitions", "label.winchester = {0}", label.winchester); AaruConsole.DebugWriteLine("Apricot partitions", "label.sectorSize = {0}", label.sectorSize); AaruConsole.DebugWriteLine("Apricot partitions", "label.spt = {0}", label.spt); AaruConsole.DebugWriteLine("Apricot partitions", "label.cylinders = {0}", label.cylinders); AaruConsole.DebugWriteLine("Apricot partitions", "label.heads = {0}", label.heads); AaruConsole.DebugWriteLine("Apricot partitions", "label.interleave = {0}", label.interleave); AaruConsole.DebugWriteLine("Apricot partitions", "label.skew = {0}", label.skew); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootLocation = {0}", label.bootLocation); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootSize = {0}", label.bootSize); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootAddress = 0x{0:X8}", label.bootAddress); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootOffset:label.bootSegment = {0:X4}:{1:X4}", label.bootOffset, label.bootSegment); AaruConsole.DebugWriteLine("Apricot partitions", "label.firstDataBlock = {0}", label.firstDataBlock); AaruConsole.DebugWriteLine("Apricot partitions", "label.generation = {0}", label.generation); AaruConsole.DebugWriteLine("Apricot partitions", "label.copyCount = {0}", label.copyCount); AaruConsole.DebugWriteLine("Apricot partitions", "label.maxCopies = {0}", label.maxCopies); AaruConsole.DebugWriteLine("Apricot partitions", "label.serialNumber = \"{0}\"", StringHandlers.CToString(label.serialNumber)); AaruConsole.DebugWriteLine("Apricot partitions", "label.partNumber = \"{0}\"", StringHandlers.CToString(label.partNumber)); AaruConsole.DebugWriteLine("Apricot partitions", "label.copyright = \"{0}\"", StringHandlers.CToString(label.copyright)); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.bps = {0}", label.mainBPB.bps); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.spc = {0}", label.mainBPB.spc); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.rsectors = {0}", label.mainBPB.rsectors); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.fats_no = {0}", label.mainBPB.fats_no); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.root_ent = {0}", label.mainBPB.root_ent); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.sectors = {0}", label.mainBPB.sectors); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.media = {0}", label.mainBPB.media); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.spfat = {0}", label.mainBPB.spfat); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.diskType = {0} ({1})", label.mainBPB.diskType, label.mainBPB.diskType < _diskTypeCodes.Length ? _diskTypeCodes[label.mainBPB.diskType] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.startSector = {0}", label.mainBPB.startSector); AaruConsole.DebugWriteLine("Apricot partitions", "label.fontName = \"{0}\"", StringHandlers.CToString(label.fontName)); AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardName = \"{0}\"", StringHandlers.CToString(label.keyboardName)); AaruConsole.DebugWriteLine("Apricot partitions", "label.biosMajorVersion = {0}", label.biosMajorVersion); AaruConsole.DebugWriteLine("Apricot partitions", "label.biosMinorVersion = {0}", label.biosMinorVersion); AaruConsole.DebugWriteLine("Apricot partitions", "label.diagnosticsFlag = {0}", label.diagnosticsFlag); AaruConsole.DebugWriteLine("Apricot partitions", "label.prnDevice = {0} ({1})", label.prnDevice, label.prnDevice < _printDevices.Length ? _printDevices[label.prnDevice] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.bellVolume = {0}", label.bellVolume); AaruConsole.DebugWriteLine("Apricot partitions", "label.enableCache = {0}", label.enableCache); AaruConsole.DebugWriteLine("Apricot partitions", "label.enableGraphics = {0}", label.enableGraphics); AaruConsole.DebugWriteLine("Apricot partitions", "label.dosLength = {0}", label.dosLength); AaruConsole.DebugWriteLine("Apricot partitions", "label.fontLength = {0}", label.fontLength); AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardLength = {0}", label.keyboardLength); AaruConsole.DebugWriteLine("Apricot partitions", "label.dosStart = {0}", label.dosStart); AaruConsole.DebugWriteLine("Apricot partitions", "label.fontStart = {0}", label.fontStart); AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardStart = {0}", label.keyboardStart); AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardVolume = {0}", label.keyboardVolume); AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeat = {0}", label.autorepeat); AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeatLeadIn = {0}", label.autorepeatLeadIn); AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeatInterval = {0}", label.autorepeatInterval); AaruConsole.DebugWriteLine("Apricot partitions", "label.microscreenMode = {0}", label.microscreenMode); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareKeyboard is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareKeyboard)); AaruConsole.DebugWriteLine("Apricot partitions", "label.lineMode = {0} ({1} lines)", label.lineMode, label.lineMode < _lineModes.Length ? _lineModes[label.lineMode] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.lineWidth = {0} ({1} columns)", label.lineWidth, label.lineWidth < _lineWidths.Length ? _lineWidths[label.lineWidth] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.imageOff = {0}", label.imageOff); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareScreen is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareScreen)); AaruConsole.DebugWriteLine("Apricot partitions", "label.txBaudRate = {0} ({1} bps)", label.txBaudRate, label.txBaudRate < _baudRates.Length ? _baudRates[label.txBaudRate] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.rxBaudRate = {0} ({1} bps)", label.rxBaudRate, label.rxBaudRate < _baudRates.Length ? _baudRates[label.rxBaudRate] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.txBits = {0}", label.txBits); AaruConsole.DebugWriteLine("Apricot partitions", "label.rxBits = {0}", label.rxBits); AaruConsole.DebugWriteLine("Apricot partitions", "label.stopBits = {0} ({1} bits)", label.stopBits, label.stopBits < _stopBits.Length ? _stopBits[label.stopBits] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.parityCheck = {0}", label.parityCheck); AaruConsole.DebugWriteLine("Apricot partitions", "label.parityType = {0} ({1})", label.parityType, label.parityType < _parityTypes.Length ? _parityTypes[label.parityType] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.txXonXoff = {0}", label.txXonXoff); AaruConsole.DebugWriteLine("Apricot partitions", "label.rxXonXoff = {0}", label.rxXonXoff); AaruConsole.DebugWriteLine("Apricot partitions", "label.xonCharacter = {0}", label.xonCharacter); AaruConsole.DebugWriteLine("Apricot partitions", "label.xoffCharacter = {0}", label.xoffCharacter); AaruConsole.DebugWriteLine("Apricot partitions", "label.rxXonXoffBuffer = {0}", label.rxXonXoffBuffer); AaruConsole.DebugWriteLine("Apricot partitions", "label.dtrDsr = {0}", label.dtrDsr); AaruConsole.DebugWriteLine("Apricot partitions", "label.ctsRts = {0}", label.ctsRts); AaruConsole.DebugWriteLine("Apricot partitions", "label.nullsAfterCr = {0}", label.nullsAfterCr); AaruConsole.DebugWriteLine("Apricot partitions", "label.nullsAfterFF = {0}", label.nullsAfterFF); AaruConsole.DebugWriteLine("Apricot partitions", "label.lfAfterCRSerial = {0}", label.lfAfterCRSerial); AaruConsole.DebugWriteLine("Apricot partitions", "label.biosErrorReportSerial = {0}", label.biosErrorReportSerial); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareSerial is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareSerial)); AaruConsole.DebugWriteLine("Apricot partitions", "label.lfAfterCrParallel = {0}", label.lfAfterCrParallel); AaruConsole.DebugWriteLine("Apricot partitions", "label.selectLine = {0}", label.selectLine); AaruConsole.DebugWriteLine("Apricot partitions", "label.paperEmpty = {0}", label.paperEmpty); AaruConsole.DebugWriteLine("Apricot partitions", "label.faultLine = {0}", label.faultLine); AaruConsole.DebugWriteLine("Apricot partitions", "label.biosErrorReportParallel = {0}", label.biosErrorReportParallel); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareParallel is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareParallel)); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareWinchester is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareWinchester)); AaruConsole.DebugWriteLine("Apricot partitions", "label.parkingEnabled = {0}", label.parkingEnabled); AaruConsole.DebugWriteLine("Apricot partitions", "label.formatProtection = {0}", label.formatProtection); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareRamDisk is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareRamDisk)); for (int i = 0; i < 32; i++) { AaruConsole.DebugWriteLine("Apricot partitions", "label.badBlocks[{1}] = {0}", label.badBlocks[i], i); } for (int i = 0; i < 8; i++) { AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].bps = {0}", label.partitions[i].bps, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].spc = {0}", label.partitions[i].spc, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].rsectors = {0}", label.partitions[i].rsectors, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].fats_no = {0}", label.partitions[i].fats_no, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].root_ent = {0}", label.partitions[i].root_ent, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].sectors = {0}", label.partitions[i].sectors, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].media = {0}", label.partitions[i].media, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].spfat = {0}", label.partitions[i].spfat, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].diskType = {0} ({2})", label.partitions[i].diskType, i, label.partitions[i].diskType < _diskTypeCodes.Length ? _diskTypeCodes[label.partitions[i].diskType] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].startSector = {0}", label.partitions[i].startSector, i); } AaruConsole.DebugWriteLine("Apricot partitions", "label.spare is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spare)); AaruConsole.DebugWriteLine("Apricot partitions", "label.cpmDoubleSided = {0}", label.cpmDoubleSided); // Only hard disks can contain partitions if (!label.winchester) { return(false); } for (byte i = 0; i < label.partitionCount; i++) { var part = new Partition { Start = label.partitions[i].startSector, Size = (ulong)(label.partitions[i].sectors * label.sectorSize), Length = label.partitions[i].sectors, Type = "ACT Apricot partition", Sequence = i, Scheme = Name, Offset = (ulong)(label.partitions[i].startSector * label.sectorSize) }; if (part.Start < deviceSectors && part.End < deviceSectors) { partitions.Add(part); } } return(partitions.Count > 0); }
public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset) { ulong counter = 0; partitions = new List <Partition>(); if (imagePlugin.Info.SectorSize < 512) { return(false); } uint sectorSize = imagePlugin.Info.SectorSize; // Divider of sector size in MBR between real sector size ulong divider = 1; if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc) { sectorSize = 512; divider = 4; } byte[] sector = imagePlugin.ReadSector(sectorOffset); MasterBootRecord mbr = Marshal.ByteArrayToStructureLittleEndian <MasterBootRecord>(sector); TimedMasterBootRecord mbrTime = Marshal.ByteArrayToStructureLittleEndian <TimedMasterBootRecord>(sector); SerializedMasterBootRecord mbrSerial = Marshal.ByteArrayToStructureLittleEndian <SerializedMasterBootRecord>(sector); ModernMasterBootRecord mbrModern = Marshal.ByteArrayToStructureLittleEndian <ModernMasterBootRecord>(sector); NecMasterBootRecord mbrNec = Marshal.ByteArrayToStructureLittleEndian <NecMasterBootRecord>(sector); DiskManagerMasterBootRecord mbrOntrack = Marshal.ByteArrayToStructureLittleEndian <DiskManagerMasterBootRecord>(sector); AaruConsole.DebugWriteLine("MBR plugin", "xmlmedia = {0}", imagePlugin.Info.XmlMediaType); AaruConsole.DebugWriteLine("MBR plugin", "mbr.magic = {0:X4}", mbr.magic); if (mbr.magic != MBR_MAGIC) { return(false); // Not MBR } byte[] hdrBytes = imagePlugin.ReadSector(1 + sectorOffset); ulong signature = BitConverter.ToUInt64(hdrBytes, 0); AaruConsole.DebugWriteLine("MBR Plugin", "gpt.signature = 0x{0:X16}", signature); if (signature == GPT_MAGIC) { return(false); } if (signature != GPT_MAGIC && imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc) { hdrBytes = imagePlugin.ReadSector(sectorOffset); signature = BitConverter.ToUInt64(hdrBytes, 512); AaruConsole.DebugWriteLine("MBR Plugin", "gpt.signature @ 0x200 = 0x{0:X16}", signature); if (signature == GPT_MAGIC) { return(false); } } PartitionEntry[] entries; if (mbrOntrack.dm_magic == DM_MAGIC) { entries = mbrOntrack.entries; } else if (mbrNec.nec_magic == NEC_MAGIC) { entries = mbrNec.entries; } else { entries = mbr.entries; } foreach (PartitionEntry entry in entries) { byte startSector = (byte)(entry.start_sector & 0x3F); ushort startCylinder = (ushort)(((entry.start_sector & 0xC0) << 2) | entry.start_cylinder); byte endSector = (byte)(entry.end_sector & 0x3F); ushort endCylinder = (ushort)(((entry.end_sector & 0xC0) << 2) | entry.end_cylinder); ulong lbaStart = entry.lba_start; ulong lbaSectors = entry.lba_sectors; // Let's start the fun... bool valid = true; bool extended = false; bool minix = false; if (entry.status != 0x00 && entry.status != 0x80) { return(false); // Maybe a FAT filesystem } valid &= entry.type != 0x00; if (entry.type == 0x05 || entry.type == 0x0F || entry.type == 0x15 || entry.type == 0x1F || entry.type == 0x85 || entry.type == 0x91 || entry.type == 0x9B || entry.type == 0xC5 || entry.type == 0xCF || entry.type == 0xD5) { valid = false; extended = true; // Extended partition } minix |= entry.type == 0x81 || entry.type == 0x80; // MINIX partition valid &= entry.lba_start != 0 || entry.lba_sectors != 0 || entry.start_cylinder != 0 || entry.start_head != 0 || entry.start_sector != 0 || entry.end_cylinder != 0 || entry.end_head != 0 || entry.end_sector != 0; if (entry.lba_start == 0 && entry.lba_sectors == 0 && valid) { lbaStart = CHS.ToLBA(startCylinder, entry.start_head, startSector, imagePlugin.Info.Heads, imagePlugin.Info.SectorsPerTrack); lbaSectors = CHS.ToLBA(endCylinder, entry.end_head, entry.end_sector, imagePlugin.Info.Heads, imagePlugin.Info.SectorsPerTrack) - lbaStart; } // For optical media lbaStart /= divider; lbaSectors /= divider; if (minix && lbaStart == sectorOffset) { minix = false; } if (lbaStart > imagePlugin.Info.Sectors) { valid = false; extended = false; } // Some buggy implementations do some rounding errors getting a few sectors beyond device size if (lbaStart + lbaSectors > imagePlugin.Info.Sectors) { lbaSectors = imagePlugin.Info.Sectors - lbaStart; } AaruConsole.DebugWriteLine("MBR plugin", "entry.status {0}", entry.status); AaruConsole.DebugWriteLine("MBR plugin", "entry.type {0}", entry.type); AaruConsole.DebugWriteLine("MBR plugin", "entry.lba_start {0}", entry.lba_start); AaruConsole.DebugWriteLine("MBR plugin", "entry.lba_sectors {0}", entry.lba_sectors); AaruConsole.DebugWriteLine("MBR plugin", "entry.start_cylinder {0}", startCylinder); AaruConsole.DebugWriteLine("MBR plugin", "entry.start_head {0}", entry.start_head); AaruConsole.DebugWriteLine("MBR plugin", "entry.start_sector {0}", startSector); AaruConsole.DebugWriteLine("MBR plugin", "entry.end_cylinder {0}", endCylinder); AaruConsole.DebugWriteLine("MBR plugin", "entry.end_head {0}", entry.end_head); AaruConsole.DebugWriteLine("MBR plugin", "entry.end_sector {0}", endSector); AaruConsole.DebugWriteLine("MBR plugin", "entry.minix = {0}", minix); AaruConsole.DebugWriteLine("MBR plugin", "lba_start {0}", lbaStart); AaruConsole.DebugWriteLine("MBR plugin", "lba_sectors {0}", lbaSectors); if (valid && minix) // Let's mix the fun { if (GetMinix(imagePlugin, lbaStart, divider, sectorOffset, sectorSize, out List <Partition> mnxParts)) { partitions.AddRange(mnxParts); } else { minix = false; } } if (valid && !minix) { var part = new Partition(); if ((lbaStart > 0 || imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc) && lbaSectors > 0) { part.Start = lbaStart + sectorOffset; part.Length = lbaSectors; part.Offset = part.Start * sectorSize; part.Size = part.Length * sectorSize; } else { valid = false; } if (valid) { part.Type = $"0x{entry.type:X2}"; part.Name = DecodeMbrType(entry.type); part.Sequence = counter; part.Description = entry.status == 0x80 ? "Partition is bootable." : ""; part.Scheme = Name; counter++; partitions.Add(part); } } AaruConsole.DebugWriteLine("MBR plugin", "entry.extended = {0}", extended); if (!extended) { continue; } bool processingExtended = true; ulong chainStart = lbaStart; while (processingExtended) { sector = imagePlugin.ReadSector(lbaStart); ExtendedBootRecord ebr = Marshal.ByteArrayToStructureLittleEndian <ExtendedBootRecord>(sector); AaruConsole.DebugWriteLine("MBR plugin", "ebr.magic == MBR_Magic = {0}", ebr.magic == MBR_MAGIC); if (ebr.magic != MBR_MAGIC) { break; } ulong nextStart = 0; foreach (PartitionEntry ebrEntry in ebr.entries) { bool extValid = true; startSector = (byte)(ebrEntry.start_sector & 0x3F); startCylinder = (ushort)(((ebrEntry.start_sector & 0xC0) << 2) | ebrEntry.start_cylinder); endSector = (byte)(ebrEntry.end_sector & 0x3F); endCylinder = (ushort)(((ebrEntry.end_sector & 0xC0) << 2) | ebrEntry.end_cylinder); ulong extStart = ebrEntry.lba_start; ulong extSectors = ebrEntry.lba_sectors; bool extMinix = false; AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.status {0}", ebrEntry.status); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.type {0}", ebrEntry.type); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.lba_start {0}", ebrEntry.lba_start); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.lba_sectors {0}", ebrEntry.lba_sectors); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.start_cylinder {0}", startCylinder); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.start_head {0}", ebrEntry.start_head); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.start_sector {0}", startSector); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.end_cylinder {0}", endCylinder); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.end_head {0}", ebrEntry.end_head); AaruConsole.DebugWriteLine("MBR plugin", "ebr_entry.end_sector {0}", endSector); // Let's start the fun... extValid &= ebrEntry.status == 0x00 || ebrEntry.status == 0x80; extValid &= ebrEntry.type != 0x00; extValid &= ebrEntry.lba_start != 0 || ebrEntry.lba_sectors != 0 || ebrEntry.start_cylinder != 0 || ebrEntry.start_head != 0 || ebrEntry.start_sector != 0 || ebrEntry.end_cylinder != 0 || ebrEntry.end_head != 0 || ebrEntry.end_sector != 0; if (ebrEntry.lba_start == 0 && ebrEntry.lba_sectors == 0 && extValid) { extStart = CHS.ToLBA(startCylinder, ebrEntry.start_head, startSector, imagePlugin.Info.Heads, imagePlugin.Info.SectorsPerTrack); extSectors = CHS.ToLBA(endCylinder, ebrEntry.end_head, ebrEntry.end_sector, imagePlugin.Info.Heads, imagePlugin.Info.SectorsPerTrack) - extStart; } extMinix |= ebrEntry.type == 0x81 || ebrEntry.type == 0x80; // For optical media extStart /= divider; extSectors /= divider; AaruConsole.DebugWriteLine("MBR plugin", "ext_start {0}", extStart); AaruConsole.DebugWriteLine("MBR plugin", "ext_sectors {0}", extSectors); if (ebrEntry.type == 0x05 || ebrEntry.type == 0x0F || ebrEntry.type == 0x15 || ebrEntry.type == 0x1F || ebrEntry.type == 0x85 || ebrEntry.type == 0x91 || ebrEntry.type == 0x9B || ebrEntry.type == 0xC5 || ebrEntry.type == 0xCF || ebrEntry.type == 0xD5) { extValid = false; nextStart = chainStart + extStart; } extStart += lbaStart; extValid &= extStart <= imagePlugin.Info.Sectors; // Some buggy implementations do some rounding errors getting a few sectors beyond device size if (extStart + extSectors > imagePlugin.Info.Sectors) { extSectors = imagePlugin.Info.Sectors - extStart; } if (extValid && extMinix) // Let's mix the fun { if (GetMinix(imagePlugin, lbaStart, divider, sectorOffset, sectorSize, out List <Partition> mnxParts)) { partitions.AddRange(mnxParts); } else { extMinix = false; } } if (!extValid || extMinix) { continue; } var part = new Partition(); if (extStart > 0 && extSectors > 0) { part.Start = extStart + sectorOffset; part.Length = extSectors; part.Offset = part.Start * sectorSize; part.Size = part.Length * sectorSize; } else { extValid = false; } if (!extValid) { continue; } part.Type = $"0x{ebrEntry.type:X2}"; part.Name = DecodeMbrType(ebrEntry.type); part.Sequence = counter; part.Description = ebrEntry.status == 0x80 ? "Partition is bootable." : ""; part.Scheme = Name; counter++; partitions.Add(part); } AaruConsole.DebugWriteLine("MBR plugin", "next_start {0}", nextStart); processingExtended &= nextStart != 0; processingExtended &= nextStart <= imagePlugin.Info.Sectors; lbaStart = nextStart; } } // An empty MBR may exist, NeXT creates one and then hardcodes its disklabel return(partitions.Count != 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(); SuperBlock superBlock; uint run = HAMMER_VOLHDR_SIZE / imagePlugin.Info.SectorSize; if (HAMMER_VOLHDR_SIZE % imagePlugin.Info.SectorSize > 0) { run++; } byte[] sbSector = imagePlugin.ReadSectors(partition.Start, run); ulong magic = BitConverter.ToUInt64(sbSector, 0); superBlock = magic == HAMMER_FSBUF_VOLUME?Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector) : Marshal.ByteArrayToStructureBigEndian <SuperBlock>(sbSector); sb.AppendLine("HAMMER filesystem"); sb.AppendFormat("Volume version: {0}", superBlock.vol_version).AppendLine(); sb.AppendFormat("Volume {0} of {1} on this filesystem", superBlock.vol_no + 1, superBlock.vol_count). AppendLine(); sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(superBlock.vol_label, Encoding)).AppendLine(); sb.AppendFormat("Volume serial: {0}", superBlock.vol_fsid).AppendLine(); sb.AppendFormat("Filesystem type: {0}", superBlock.vol_fstype).AppendLine(); sb.AppendFormat("Boot area starts at {0}", superBlock.vol_bot_beg).AppendLine(); sb.AppendFormat("Memory log starts at {0}", superBlock.vol_mem_beg).AppendLine(); sb.AppendFormat("First volume buffer starts at {0}", superBlock.vol_buf_beg).AppendLine(); sb.AppendFormat("Volume ends at {0}", superBlock.vol_buf_end).AppendLine(); XmlFsType = new FileSystemType { Clusters = partition.Size / HAMMER_BIGBLOCK_SIZE, ClusterSize = HAMMER_BIGBLOCK_SIZE, Dirty = false, Type = "HAMMER", VolumeName = StringHandlers.CToString(superBlock.vol_label, Encoding), VolumeSerial = superBlock.vol_fsid.ToString() }; if (superBlock.vol_no == superBlock.vol_rootvol) { sb.AppendFormat("Filesystem contains {0} \"big-blocks\" ({1} bytes)", superBlock.vol0_stat_bigblocks, superBlock.vol0_stat_bigblocks * HAMMER_BIGBLOCK_SIZE).AppendLine(); sb.AppendFormat("Filesystem has {0} \"big-blocks\" free ({1} bytes)", superBlock.vol0_stat_freebigblocks, superBlock.vol0_stat_freebigblocks * HAMMER_BIGBLOCK_SIZE).AppendLine(); sb.AppendFormat("Filesystem has {0} inode used", superBlock.vol0_stat_inodes).AppendLine(); XmlFsType.Clusters = (ulong)superBlock.vol0_stat_bigblocks; XmlFsType.FreeClusters = (ulong)superBlock.vol0_stat_freebigblocks; XmlFsType.FreeClustersSpecified = true; XmlFsType.Files = (ulong)superBlock.vol0_stat_inodes; XmlFsType.FilesSpecified = true; } // 0 ? //sb.AppendFormat("Volume header CRC: 0x{0:X8}", afs_sb.vol_crc).AppendLine(); 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(); uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize; byte[] sector = imagePlugin.ReadSector(partition.Start + bootSectors); if (sector.Length < 512) { return; } SuperBlock jfsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector); sb.AppendLine("JFS filesystem"); sb.AppendFormat("Version {0}", jfsSb.s_version).AppendLine(); sb.AppendFormat("{0} blocks of {1} bytes", jfsSb.s_size, jfsSb.s_bsize).AppendLine(); sb.AppendFormat("{0} blocks per allocation group", jfsSb.s_agsize).AppendLine(); if (jfsSb.s_flags.HasFlag(Flags.Unicode)) { sb.AppendLine("Volume uses Unicode for directory entries"); } if (jfsSb.s_flags.HasFlag(Flags.RemountRO)) { sb.AppendLine("Volume remounts read-only on error"); } if (jfsSb.s_flags.HasFlag(Flags.Continue)) { sb.AppendLine("Volume continues on error"); } if (jfsSb.s_flags.HasFlag(Flags.Panic)) { sb.AppendLine("Volume panics on error"); } if (jfsSb.s_flags.HasFlag(Flags.UserQuota)) { sb.AppendLine("Volume has user quotas enabled"); } if (jfsSb.s_flags.HasFlag(Flags.GroupQuota)) { sb.AppendLine("Volume has group quotas enabled"); } if (jfsSb.s_flags.HasFlag(Flags.NoJournal)) { sb.AppendLine("Volume is not using any journal"); } if (jfsSb.s_flags.HasFlag(Flags.Discard)) { sb.AppendLine("Volume sends TRIM/UNMAP commands to underlying device"); } if (jfsSb.s_flags.HasFlag(Flags.GroupCommit)) { sb.AppendLine("Volume commits in groups of 1"); } if (jfsSb.s_flags.HasFlag(Flags.LazyCommit)) { sb.AppendLine("Volume commits lazy"); } if (jfsSb.s_flags.HasFlag(Flags.Temporary)) { sb.AppendLine("Volume does not commit to log"); } if (jfsSb.s_flags.HasFlag(Flags.InlineLog)) { sb.AppendLine("Volume has log withing itself"); } if (jfsSb.s_flags.HasFlag(Flags.InlineMoving)) { sb.AppendLine("Volume has log withing itself and is moving it out"); } if (jfsSb.s_flags.HasFlag(Flags.BadSAIT)) { sb.AppendLine("Volume has bad current secondary ait"); } if (jfsSb.s_flags.HasFlag(Flags.Sparse)) { sb.AppendLine("Volume supports sparse files"); } if (jfsSb.s_flags.HasFlag(Flags.DASDEnabled)) { sb.AppendLine("Volume has DASD limits enabled"); } if (jfsSb.s_flags.HasFlag(Flags.DASDPrime)) { sb.AppendLine("Volume primes DASD on boot"); } if (jfsSb.s_flags.HasFlag(Flags.SwapBytes)) { sb.AppendLine("Volume is in a big-endian system"); } if (jfsSb.s_flags.HasFlag(Flags.DirIndex)) { sb.AppendLine("Volume has presistent indexes"); } if (jfsSb.s_flags.HasFlag(Flags.Linux)) { sb.AppendLine("Volume supports Linux"); } if (jfsSb.s_flags.HasFlag(Flags.DFS)) { sb.AppendLine("Volume supports DCE DFS LFS"); } if (jfsSb.s_flags.HasFlag(Flags.OS2)) { sb.AppendLine("Volume supports OS/2, and is case insensitive"); } if (jfsSb.s_flags.HasFlag(Flags.AIX)) { sb.AppendLine("Volume supports AIX"); } if (jfsSb.s_state != 0) { sb.AppendLine("Volume is dirty"); } sb.AppendFormat("Volume was last updated on {0}", DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec)). AppendLine(); if (jfsSb.s_version == 1) { sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(jfsSb.s_fpack, Encoding)).AppendLine(); } else { sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(jfsSb.s_label, Encoding)).AppendLine(); } sb.AppendFormat("Volume UUID: {0}", jfsSb.s_uuid).AppendLine(); XmlFsType = new FileSystemType { Type = "JFS filesystem", Clusters = jfsSb.s_size, ClusterSize = jfsSb.s_bsize, Bootable = true, VolumeName = StringHandlers.CToString(jfsSb.s_version == 1 ? jfsSb.s_fpack : jfsSb.s_label, Encoding), VolumeSerial = $"{jfsSb.s_uuid}", ModificationDate = DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec), ModificationDateSpecified = true }; if (jfsSb.s_state != 0) { XmlFsType.Dirty = true; } information = sb.ToString(); }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); _vmEHdr = new VMwareExtentHeader(); _vmCHdr = new VMwareCowHeader(); bool embedded = false; if (stream.Length > Marshal.SizeOf <VMwareExtentHeader>()) { stream.Seek(0, SeekOrigin.Begin); byte[] vmEHdrB = new byte[Marshal.SizeOf <VMwareExtentHeader>()]; stream.Read(vmEHdrB, 0, Marshal.SizeOf <VMwareExtentHeader>()); _vmEHdr = Marshal.ByteArrayToStructureLittleEndian <VMwareExtentHeader>(vmEHdrB); } if (stream.Length > Marshal.SizeOf <VMwareCowHeader>()) { stream.Seek(0, SeekOrigin.Begin); byte[] vmCHdrB = new byte[Marshal.SizeOf <VMwareCowHeader>()]; stream.Read(vmCHdrB, 0, Marshal.SizeOf <VMwareCowHeader>()); _vmCHdr = Marshal.ByteArrayToStructureLittleEndian <VMwareCowHeader>(vmCHdrB); } var ddfStream = new MemoryStream(); bool vmEHdrSet = false; bool cowD = false; if (_vmEHdr.magic == VMWARE_EXTENT_MAGIC) { vmEHdrSet = true; _gdFilter = imageFilter; if (_vmEHdr.descriptorOffset == 0 || _vmEHdr.descriptorSize == 0) { throw new Exception("Please open VMDK descriptor."); } byte[] ddfEmbed = new byte[_vmEHdr.descriptorSize * SECTOR_SIZE]; stream.Seek((long)(_vmEHdr.descriptorOffset * SECTOR_SIZE), SeekOrigin.Begin); stream.Read(ddfEmbed, 0, ddfEmbed.Length); ddfStream.Write(ddfEmbed, 0, ddfEmbed.Length); embedded = true; } else if (_vmCHdr.magic == VMWARE_COW_MAGIC) { _gdFilter = imageFilter; cowD = true; } else { byte[] ddfMagic = new byte[0x15]; stream.Seek(0, SeekOrigin.Begin); stream.Read(ddfMagic, 0, 0x15); if (!_ddfMagicBytes.SequenceEqual(ddfMagic)) { throw new Exception("Not a descriptor."); } stream.Seek(0, SeekOrigin.Begin); byte[] ddfExternal = new byte[imageFilter.GetDataForkLength()]; stream.Read(ddfExternal, 0, ddfExternal.Length); ddfStream.Write(ddfExternal, 0, ddfExternal.Length); } _extents = new Dictionary <ulong, VMwareExtent>(); ulong currentSector = 0; bool matchedCyls = false, matchedHds = false, matchedSpt = false; if (cowD) { int cowCount = 1; string basePath = Path.GetFileNameWithoutExtension(imageFilter.GetBasePath()); while (true) { string curPath; if (cowCount == 1) { curPath = basePath + ".vmdk"; } else { curPath = $"{basePath}-{cowCount:D2}.vmdk"; } if (!File.Exists(curPath)) { break; } IFilter extentFilter = new FiltersList().GetFilter(curPath); Stream extentStream = extentFilter.GetDataForkStream(); if (stream.Length > Marshal.SizeOf <VMwareCowHeader>()) { var extHdrCow = new VMwareCowHeader(); extentStream.Seek(0, SeekOrigin.Begin); byte[] vmCHdrB = new byte[Marshal.SizeOf <VMwareCowHeader>()]; extentStream.Read(vmCHdrB, 0, Marshal.SizeOf <VMwareCowHeader>()); extHdrCow = Marshal.ByteArrayToStructureLittleEndian <VMwareCowHeader>(vmCHdrB); if (extHdrCow.magic != VMWARE_COW_MAGIC) { break; } var newExtent = new VMwareExtent { Access = "RW", Filter = extentFilter, Filename = extentFilter.GetFilename(), Offset = 0, Sectors = extHdrCow.sectors, Type = "SPARSE" }; AaruConsole.DebugWriteLine("VMware plugin", "{0} {1} {2} \"{3}\" {4}", newExtent.Access, newExtent.Sectors, newExtent.Type, newExtent.Filename, newExtent.Offset); _extents.Add(currentSector, newExtent); currentSector += newExtent.Sectors; } else { break; } cowCount++; } _imageType = VM_TYPE_SPLIT_SPARSE; } else { ddfStream.Seek(0, SeekOrigin.Begin); var regexVersion = new Regex(REGEX_VERSION); var regexCid = new Regex(REGEX_CID); var regexParentCid = new Regex(REGEX_CID_PARENT); var regexType = new Regex(REGEX_TYPE); var regexExtent = new Regex(REGEX_EXTENT); var regexParent = new Regex(PARENT_REGEX); var regexCylinders = new Regex(REGEX_DDB_CYLINDERS); var regexHeads = new Regex(REGEX_DDB_HEADS); var regexSectors = new Regex(REGEX_DDB_SECTORS); var ddfStreamRdr = new StreamReader(ddfStream); while (ddfStreamRdr.Peek() >= 0) { string line = ddfStreamRdr.ReadLine(); Match matchVersion = regexVersion.Match(line); Match matchCid = regexCid.Match(line); Match matchParentCid = regexParentCid.Match(line); Match matchType = regexType.Match(line); Match matchExtent = regexExtent.Match(line); Match matchParent = regexParent.Match(line); Match matchCylinders = regexCylinders.Match(line); Match matchHeads = regexHeads.Match(line); Match matchSectors = regexSectors.Match(line); if (matchVersion.Success) { uint.TryParse(matchVersion.Groups["version"].Value, out _version); AaruConsole.DebugWriteLine("VMware plugin", "version = {0}", _version); } else if (matchCid.Success) { _cid = Convert.ToUInt32(matchCid.Groups["cid"].Value, 16); AaruConsole.DebugWriteLine("VMware plugin", "cid = {0:x8}", _cid); } else if (matchParentCid.Success) { _parentCid = Convert.ToUInt32(matchParentCid.Groups["cid"].Value, 16); AaruConsole.DebugWriteLine("VMware plugin", "parentCID = {0:x8}", _parentCid); } else if (matchType.Success) { _imageType = matchType.Groups["type"].Value; AaruConsole.DebugWriteLine("VMware plugin", "createType = \"{0}\"", _imageType); } else if (matchExtent.Success) { var newExtent = new VMwareExtent { Access = matchExtent.Groups["access"].Value }; if (!embedded) { newExtent.Filter = new FiltersList(). GetFilter(Path.Combine(Path.GetDirectoryName(imageFilter.GetBasePath()), matchExtent.Groups["filename"].Value)); } else { newExtent.Filter = imageFilter; } uint.TryParse(matchExtent.Groups["offset"].Value, out newExtent.Offset); uint.TryParse(matchExtent.Groups["sectors"].Value, out newExtent.Sectors); newExtent.Type = matchExtent.Groups["type"].Value; AaruConsole.DebugWriteLine("VMware plugin", "{0} {1} {2} \"{3}\" {4}", newExtent.Access, newExtent.Sectors, newExtent.Type, newExtent.Filename, newExtent.Offset); _extents.Add(currentSector, newExtent); currentSector += newExtent.Sectors; } else if (matchParent.Success) { _parentName = matchParent.Groups["filename"].Value; AaruConsole.DebugWriteLine("VMware plugin", "parentFileNameHint = \"{0}\"", _parentName); _hasParent = true; } else if (matchCylinders.Success) { uint.TryParse(matchCylinders.Groups["cylinders"].Value, out _imageInfo.Cylinders); matchedCyls = true; } else if (matchHeads.Success) { uint.TryParse(matchHeads.Groups["heads"].Value, out _imageInfo.Heads); matchedHds = true; } else if (matchSectors.Success) { uint.TryParse(matchSectors.Groups["sectors"].Value, out _imageInfo.SectorsPerTrack); matchedSpt = true; } } } if (_extents.Count == 0) { throw new Exception("Did not find any extent"); } switch (_imageType) { case VM_TYPE_MONO_SPARSE: //"monolithicSparse"; case VM_TYPE_MONO_FLAT: //"monolithicFlat"; case VM_TYPE_SPLIT_SPARSE: //"twoGbMaxExtentSparse"; case VM_TYPE_SPLIT_FLAT: //"twoGbMaxExtentFlat"; case VMFS_TYPE_FLAT: //"vmfsPreallocated"; case VMFS_TYPE_ZERO: //"vmfsEagerZeroedThick"; case VMFS_TYPE_THIN: //"vmfsThin"; case VMFS_TYPE_SPARSE: //"vmfsSparse"; case VMFS_TYPE: //"vmfs"; case VM_TYPE_STREAM: //"streamOptimized"; break; case VM_TYPE_FULL_DEVICE: //"fullDevice"; case VM_TYPE_PART_DEVICE: //"partitionedDevice"; case VMFS_TYPE_RDM: //"vmfsRDM"; case VMFS_TYPE_RDM_OLD: //"vmfsRawDeviceMap"; case VMFS_TYPE_RDMP: //"vmfsRDMP"; case VMFS_TYPE_RDMP_OLD: //"vmfsPassthroughRawDeviceMap"; case VMFS_TYPE_RAW: //"vmfsRaw"; throw new ImageNotSupportedException("Raw device image files are not supported, try accessing the device directly."); default: throw new ImageNotSupportedException($"Dunno how to handle \"{_imageType}\" extents."); } bool oneNoFlat = cowD; foreach (VMwareExtent extent in _extents.Values) { if (extent.Filter == null) { throw new Exception($"Extent file {extent.Filename} not found."); } if (extent.Access == "NOACCESS") { throw new Exception("Cannot access NOACCESS extents ;)."); } if (extent.Type == "FLAT" || extent.Type == "ZERO" || extent.Type == "VMFS" || cowD) { continue; } Stream extentStream = extent.Filter.GetDataForkStream(); extentStream.Seek(0, SeekOrigin.Begin); if (extentStream.Length < SECTOR_SIZE) { throw new Exception($"Extent {extent.Filename} is too small."); } byte[] extentHdrB = new byte[Marshal.SizeOf <VMwareExtentHeader>()]; extentStream.Read(extentHdrB, 0, Marshal.SizeOf <VMwareExtentHeader>()); VMwareExtentHeader extentHdr = Marshal.ByteArrayToStructureLittleEndian <VMwareExtentHeader>(extentHdrB); if (extentHdr.magic != VMWARE_EXTENT_MAGIC) { throw new Exception($"{extent.Filter} is not an VMware extent."); } if (extentHdr.capacity < extent.Sectors) { throw new Exception($"Extent contains incorrect number of sectors, {extentHdr.capacity}. {extent.Sectors} were expected"); } // TODO: Support compressed extents if (extentHdr.compression != COMPRESSION_NONE) { throw new ImageNotSupportedException("Compressed extents are not yet supported."); } if (!vmEHdrSet) { _vmEHdr = extentHdr; _gdFilter = extent.Filter; vmEHdrSet = true; } oneNoFlat = true; } if (oneNoFlat && !vmEHdrSet && !cowD) { throw new Exception("There are sparse extents but there is no header to find the grain tables, cannot proceed."); } _imageInfo.Sectors = currentSector; uint grains = 0; uint gdEntries = 0; long gdOffset = 0; uint gtEsPerGt = 0; if (oneNoFlat && !cowD) { AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.magic = 0x{0:X8}", _vmEHdr.magic); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.version = {0}", _vmEHdr.version); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.flags = 0x{0:X8}", _vmEHdr.flags); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.capacity = {0}", _vmEHdr.capacity); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.grainSize = {0}", _vmEHdr.grainSize); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.descriptorOffset = {0}", _vmEHdr.descriptorOffset); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.descriptorSize = {0}", _vmEHdr.descriptorSize); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.GTEsPerGT = {0}", _vmEHdr.GTEsPerGT); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.rgdOffset = {0}", _vmEHdr.rgdOffset); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.gdOffset = {0}", _vmEHdr.gdOffset); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.overhead = {0}", _vmEHdr.overhead); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.uncleanShutdown = {0}", _vmEHdr.uncleanShutdown); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.singleEndLineChar = 0x{0:X2}", _vmEHdr.singleEndLineChar); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.nonEndLineChar = 0x{0:X2}", _vmEHdr.nonEndLineChar); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.doubleEndLineChar1 = 0x{0:X2}", _vmEHdr.doubleEndLineChar1); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.doubleEndLineChar2 = 0x{0:X2}", _vmEHdr.doubleEndLineChar2); AaruConsole.DebugWriteLine("VMware plugin", "vmEHdr.compression = 0x{0:X4}", _vmEHdr.compression); _grainSize = _vmEHdr.grainSize; grains = (uint)(_imageInfo.Sectors / _vmEHdr.grainSize) + 1; gdEntries = grains / _vmEHdr.GTEsPerGT; gtEsPerGt = _vmEHdr.GTEsPerGT; if ((_vmEHdr.flags & FLAGS_USE_REDUNDANT_TABLE) == FLAGS_USE_REDUNDANT_TABLE) { gdOffset = (long)_vmEHdr.rgdOffset; } else { gdOffset = (long)_vmEHdr.gdOffset; } } else if (oneNoFlat && cowD) { AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.magic = 0x{0:X8}", _vmCHdr.magic); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.version = {0}", _vmCHdr.version); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.flags = 0x{0:X8}", _vmCHdr.flags); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.sectors = {0}", _vmCHdr.sectors); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.grainSize = {0}", _vmCHdr.grainSize); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.gdOffset = {0}", _vmCHdr.gdOffset); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.numGDEntries = {0}", _vmCHdr.numGDEntries); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.freeSector = {0}", _vmCHdr.freeSector); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.cylinders = {0}", _vmCHdr.cylinders); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.heads = {0}", _vmCHdr.heads); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.spt = {0}", _vmCHdr.spt); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.generation = {0}", _vmCHdr.generation); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.name = {0}", StringHandlers.CToString(_vmCHdr.name)); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.description = {0}", StringHandlers.CToString(_vmCHdr.description)); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.savedGeneration = {0}", _vmCHdr.savedGeneration); AaruConsole.DebugWriteLine("VMware plugin", "vmCHdr.uncleanShutdown = {0}", _vmCHdr.uncleanShutdown); _grainSize = _vmCHdr.grainSize; grains = (uint)(_imageInfo.Sectors / _vmCHdr.grainSize) + 1; gdEntries = _vmCHdr.numGDEntries; gdOffset = _vmCHdr.gdOffset; gtEsPerGt = grains / gdEntries; _imageInfo.MediaTitle = StringHandlers.CToString(_vmCHdr.name); _imageInfo.Comments = StringHandlers.CToString(_vmCHdr.description); _version = _vmCHdr.version; } if (oneNoFlat) { if (grains == 0 || gdEntries == 0) { throw new Exception("Some error ocurred setting GD sizes"); } AaruConsole.DebugWriteLine("VMware plugin", "{0} sectors in {1} grains in {2} tables", _imageInfo.Sectors, grains, gdEntries); Stream gdStream = _gdFilter.GetDataForkStream(); gdStream.Seek(gdOffset * SECTOR_SIZE, SeekOrigin.Begin); AaruConsole.DebugWriteLine("VMware plugin", "Reading grain directory"); byte[] gdBytes = new byte[gdEntries * 4]; gdStream.Read(gdBytes, 0, gdBytes.Length); Span <uint> gd = MemoryMarshal.Cast <byte, uint>(gdBytes); AaruConsole.DebugWriteLine("VMware plugin", "Reading grain tables"); uint currentGrain = 0; _gTable = new uint[grains]; foreach (uint gtOff in gd) { byte[] gtBytes = new byte[gtEsPerGt * 4]; gdStream.Seek(gtOff * SECTOR_SIZE, SeekOrigin.Begin); gdStream.Read(gtBytes, 0, gtBytes.Length); uint[] currentGt = MemoryMarshal.Cast <byte, uint>(gtBytes).ToArray(); Array.Copy(currentGt, 0, _gTable, currentGrain, gtEsPerGt); currentGrain += gtEsPerGt; // TODO: Check speed here /* * for(int i = 0; i < gtEsPerGt; i++) * { * gTable[currentGrain] = BitConverter.ToUInt32(gtBytes, i * 4); * currentGrain++; * } */ } _maxCachedGrains = (uint)(MAX_CACHE_SIZE / (_grainSize * SECTOR_SIZE)); _grainCache = new Dictionary <ulong, byte[]>(); } if (_hasParent) { IFilter parentFilter = new FiltersList().GetFilter(Path.Combine(imageFilter.GetParentFolder(), _parentName)); if (parentFilter == null) { throw new Exception($"Cannot find parent \"{_parentName}\"."); } _parentImage = new VMware(); if (!_parentImage.Open(parentFilter)) { throw new Exception($"Cannot open parent \"{_parentName}\"."); } } _sectorCache = new Dictionary <ulong, byte[]>(); _imageInfo.CreationTime = imageFilter.GetCreationTime(); _imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); _imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); _imageInfo.SectorSize = SECTOR_SIZE; _imageInfo.XmlMediaType = XmlMediaType.BlockMedia; _imageInfo.MediaType = MediaType.GENERIC_HDD; _imageInfo.ImageSize = _imageInfo.Sectors * SECTOR_SIZE; // VMDK version 1 started on VMware 4, so there is a previous version, "COWD" _imageInfo.Version = cowD ? $"{_version}" : $"{_version + 3}"; if (cowD) { _imageInfo.Cylinders = _vmCHdr.cylinders; _imageInfo.Heads = _vmCHdr.heads; _imageInfo.SectorsPerTrack = _vmCHdr.spt; } else if (!matchedCyls || !matchedHds || !matchedSpt) { _imageInfo.Cylinders = (uint)(_imageInfo.Sectors / 16 / 63); _imageInfo.Heads = 16; _imageInfo.SectorsPerTrack = 63; } return(true); }