From d3fca2a4a22093cf84255159087e0f344771662d Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Tue, 19 Sep 2017 19:53:03 +0100 Subject: [PATCH] Added support for devices with sectors bigger than 512bytes in ext1/2/3/4. --- DiscImageChef.Filesystems/ext2FS.cs | 43 +++++++++++++++++------------ DiscImageChef.Filesystems/extFS.cs | 24 +++++++++++++--- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/DiscImageChef.Filesystems/ext2FS.cs b/DiscImageChef.Filesystems/ext2FS.cs index 5a372d34e..4535dd11c 100644 --- a/DiscImageChef.Filesystems/ext2FS.cs +++ b/DiscImageChef.Filesystems/ext2FS.cs @@ -41,6 +41,8 @@ namespace DiscImageChef.Filesystems // Information from the Linux kernel public class ext2FS : Filesystem { + const int sbPos = 0x400; + public ext2FS() { Name = "Linux extended Filesystem 2, 3 and 4"; @@ -60,12 +62,22 @@ namespace DiscImageChef.Filesystems public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, Partition partition) { - if((2 + partition.Start) >= partition.End) + ulong sbSector = sbPos / imagePlugin.GetSectorSize(); + uint sbOff = sbPos % imagePlugin.GetSectorSize(); + + if((sbSector + partition.Start) >= partition.End) return false; - byte[] sb_sector = imagePlugin.ReadSector(2 + partition.Start); + int sb_size_in_bytes = Marshal.SizeOf(typeof(ext2FSSuperBlock)); + uint sb_size_in_sectors = (uint)(sb_size_in_bytes / imagePlugin.GetSectorSize()); + if(sb_size_in_bytes % imagePlugin.GetSectorSize() > 0) + sb_size_in_sectors++; - ushort magic = BitConverter.ToUInt16(sb_sector, 0x038); + byte[] sb_sector = imagePlugin.ReadSectors(sbSector + partition.Start, sb_size_in_sectors); + byte[] sb = new byte[sb_size_in_bytes]; + Array.Copy(sb_sector, sbOff, sb, 0, sb_size_in_bytes); + + ushort magic = BitConverter.ToUInt16(sb, 0x038); if(magic == ext2FSMagic || magic == ext2OldFSMagic) return true; @@ -87,22 +99,19 @@ namespace DiscImageChef.Filesystems byte[] guid_a = new byte[16]; byte[] guid_b = new byte[16]; - uint sb_size_in_sectors; + int sb_size_in_bytes = Marshal.SizeOf(typeof(ext2FSSuperBlock)); + uint sb_size_in_sectors = (uint)(sb_size_in_bytes / imagePlugin.GetSectorSize()); + if(sb_size_in_bytes % imagePlugin.GetSectorSize() > 0) + sb_size_in_sectors++; - if(imagePlugin.GetSectorSize() < 1024) - sb_size_in_sectors = 1024 / imagePlugin.GetSectorSize(); - else - sb_size_in_sectors = 1; + ulong sbSector = sbPos / imagePlugin.GetSectorSize(); + uint sbOff = sbPos % imagePlugin.GetSectorSize(); - if(sb_size_in_sectors == 0) - { - information = "Error calculating size in sectors of ext2/3/4 superblocks"; - return; - } - - byte[] sb_sector = imagePlugin.ReadSectors(2 + partition.Start, sb_size_in_sectors); - IntPtr sbPtr = Marshal.AllocHGlobal(512); - Marshal.Copy(sb_sector, 0, sbPtr, 512); + byte[] sb_sector = imagePlugin.ReadSectors(sbSector + partition.Start, sb_size_in_sectors); + byte[] sblock = new byte[sb_size_in_bytes]; + Array.Copy(sb_sector, sbOff, sblock, 0, sb_size_in_bytes); + IntPtr sbPtr = Marshal.AllocHGlobal(sb_size_in_bytes); + Marshal.Copy(sblock, 0, sbPtr, sb_size_in_bytes); supblk = (ext2FSSuperBlock)Marshal.PtrToStructure(sbPtr, typeof(ext2FSSuperBlock)); Marshal.FreeHGlobal(sbPtr); diff --git a/DiscImageChef.Filesystems/extFS.cs b/DiscImageChef.Filesystems/extFS.cs index a81ec11bb..e36969c52 100644 --- a/DiscImageChef.Filesystems/extFS.cs +++ b/DiscImageChef.Filesystems/extFS.cs @@ -40,6 +40,8 @@ namespace DiscImageChef.Filesystems // Information from the Linux kernel public class extFS : Filesystem { + const int sbPos = 0x400; + public extFS() { Name = "Linux extended Filesystem"; @@ -59,12 +61,17 @@ namespace DiscImageChef.Filesystems public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, Partition partition) { - if((2 + partition.Start) >= partition.End) + ulong sbSector = sbPos / imagePlugin.GetSectorSize(); + uint sbOff = sbPos % imagePlugin.GetSectorSize(); + + if((sbSector + partition.Start) >= partition.End) return false; - byte[] sb_sector = imagePlugin.ReadSector(2 + partition.Start); // Superblock resides at 0x400 + byte[] sb_sector = imagePlugin.ReadSector(sbSector + partition.Start); + byte[] sb = new byte[512]; + Array.Copy(sb_sector, sbOff, sb, 0, 512); - ushort magic = BitConverter.ToUInt16(sb_sector, 0x038); // Here should reside magic number + ushort magic = BitConverter.ToUInt16(sb, 0x038); return magic == extFSMagic; } @@ -75,7 +82,16 @@ namespace DiscImageChef.Filesystems StringBuilder sb = new StringBuilder(); - byte[] sb_sector = imagePlugin.ReadSector(2 + partition.Start); // Superblock resides at 0x400 + ulong sbSector = sbPos / imagePlugin.GetSectorSize(); + uint sbOff = sbPos % imagePlugin.GetSectorSize(); + + if((sbSector + partition.Start) >= partition.End) + return; + + byte[] sblock = imagePlugin.ReadSector(sbSector + partition.Start); + byte[] sb_sector = new byte[512]; + Array.Copy(sblock, sbOff, sb_sector, 0, 512); + extFSSuperBlock ext_sb = new extFSSuperBlock(); ext_sb.inodes = BitConverter.ToUInt32(sb_sector, 0x000);