From f5e90756a283b1ab603d74c33afc61f1db65787f Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 1 Aug 2016 18:52:34 +0100 Subject: [PATCH] * DiscImageChef.DiscImages/DiskCopy42.cs: Lisa Twiggies and Macintosh Twiggies use a different track order. Detect a Macintosh File System to know which re-ordering to use. * DiscImageChef.Filesystems/AppleMFS/Dir.cs: Remove spurious debug leftover. "Entries are always an integral number of words" solved. * DiscImageChef.Filesystems/AppleMFS/Super.cs: When filling volume block map, check we are not going out of bounds. * DiscImageChef.Partitions/NeXT.cs: * DiscImageChef.Filesystems/HPFS.cs: * DiscImageChef.Filesystems/SysV.cs: Do not try to read past device. --- DiscImageChef.DiscImages/ChangeLog | 6 ++ DiscImageChef.DiscImages/DiskCopy42.cs | 67 +++++++++++++-------- DiscImageChef.Filesystems/AppleMFS/Dir.cs | 8 ++- DiscImageChef.Filesystems/AppleMFS/Super.cs | 13 +++- DiscImageChef.Filesystems/ChangeLog | 11 ++++ DiscImageChef.Filesystems/HPFS.cs | 3 + DiscImageChef.Filesystems/SysV.cs | 3 + DiscImageChef.Partitions/ChangeLog | 4 ++ DiscImageChef.Partitions/NeXT.cs | 6 +- 9 files changed, 87 insertions(+), 34 deletions(-) diff --git a/DiscImageChef.DiscImages/ChangeLog b/DiscImageChef.DiscImages/ChangeLog index dda2adda..948e5eb4 100644 --- a/DiscImageChef.DiscImages/ChangeLog +++ b/DiscImageChef.DiscImages/ChangeLog @@ -1,3 +1,9 @@ +2016-08-01 Natalia Portillo + + * DiskCopy42.cs: Lisa Twiggies and Macintosh Twiggies use a + different track order. Detect a Macintosh File System to know + which re-ordering to use. + 2016-07-31 Natalia Portillo * DiskCopy42.cs: Swap tracks in second half of twiggy images. diff --git a/DiscImageChef.DiscImages/DiskCopy42.cs b/DiscImageChef.DiscImages/DiskCopy42.cs index ac67dc93..21e1a989 100644 --- a/DiscImageChef.DiscImages/DiskCopy42.cs +++ b/DiscImageChef.DiscImages/DiskCopy42.cs @@ -375,7 +375,6 @@ namespace DiscImageChef.ImagePlugins if(ImageInfo.mediaType == MediaType.AppleFileWare) { - DicConsole.DebugWriteLine("DC42 plugin", "Twiggy detected, reversing second half of disk", bptag); byte[] data = new byte[header.dataSize]; byte[] tags = new byte[header.tagSize]; @@ -393,35 +392,51 @@ namespace DiscImageChef.ImagePlugins tagstream.Read(tags, 0, (int)header.tagSize); tagstream.Close(); - Array.Copy(data, 0, twiggyCache, 0, header.dataSize / 2); - Array.Copy(tags, 0, twiggyCacheTags, 0, header.tagSize / 2); + ushort MFS_Magic = BigEndianBitConverter.ToUInt16(data, (int)((data.Length / 2) + 0x400)); + ushort MFS_AllBlocks = BigEndianBitConverter.ToUInt16(data, (int)((data.Length / 2) + 0x412)); - int copiedSectors = 0; - int sectorsToCopy = 0; - - for(int i = 0; i < 46; i++) + // Detect a Macintosh Twiggy + if(MFS_Magic == 0xD2D7 && MFS_AllBlocks == 422) { - if(i >= 0 && i <= 3) - sectorsToCopy = 22; - if(i >= 4 && i <= 10) - sectorsToCopy = 21; - if(i >= 11 && i <= 16) - sectorsToCopy = 20; - if(i >= 17 && i <= 22) - sectorsToCopy = 19; - if(i >= 23 && i <= 28) - sectorsToCopy = 18; - if(i >= 29 && i <= 34) - sectorsToCopy = 17; - if(i >= 35 && i <= 41) - sectorsToCopy = 16; - if(i >= 42 && i <= 45) - sectorsToCopy = 15; + DicConsole.DebugWriteLine("DC42 plugin", "Macintosh Twiggy detected, reversing disk sides"); + Array.Copy(data, (header.dataSize / 2), twiggyCache, 0, header.dataSize / 2); + Array.Copy(tags, (header.tagSize / 2), twiggyCacheTags, 0, header.tagSize / 2); + Array.Copy(data, 0, twiggyCache, header.dataSize / 2, header.dataSize / 2); + Array.Copy(tags, 0, twiggyCacheTags, header.tagSize / 2, header.tagSize / 2); + } + else + { + DicConsole.DebugWriteLine("DC42 plugin", "Lisa Twiggy detected, reversing second half of disk"); + Array.Copy(data, 0, twiggyCache, 0, header.dataSize / 2); + Array.Copy(tags, 0, twiggyCacheTags, 0, header.tagSize / 2); - Array.Copy(data, header.dataSize / 2 + copiedSectors * 512, twiggyCache, twiggyCache.Length - copiedSectors * 512 - sectorsToCopy * 512, sectorsToCopy * 512); - Array.Copy(tags, header.tagSize / 2 + copiedSectors * bptag, twiggyCacheTags, twiggyCacheTags.Length - copiedSectors * bptag - sectorsToCopy * bptag, sectorsToCopy * bptag); + int copiedSectors = 0; + int sectorsToCopy = 0; - copiedSectors += sectorsToCopy; + for(int i = 0; i < 46; i++) + { + if(i >= 0 && i <= 3) + sectorsToCopy = 22; + if(i >= 4 && i <= 10) + sectorsToCopy = 21; + if(i >= 11 && i <= 16) + sectorsToCopy = 20; + if(i >= 17 && i <= 22) + sectorsToCopy = 19; + if(i >= 23 && i <= 28) + sectorsToCopy = 18; + if(i >= 29 && i <= 34) + sectorsToCopy = 17; + if(i >= 35 && i <= 41) + sectorsToCopy = 16; + if(i >= 42 && i <= 45) + sectorsToCopy = 15; + + Array.Copy(data, header.dataSize / 2 + copiedSectors * 512, twiggyCache, twiggyCache.Length - copiedSectors * 512 - sectorsToCopy * 512, sectorsToCopy * 512); + Array.Copy(tags, header.tagSize / 2 + copiedSectors * bptag, twiggyCacheTags, twiggyCacheTags.Length - copiedSectors * bptag - sectorsToCopy * bptag, sectorsToCopy * bptag); + + copiedSectors += sectorsToCopy; + } } } diff --git a/DiscImageChef.Filesystems/AppleMFS/Dir.cs b/DiscImageChef.Filesystems/AppleMFS/Dir.cs index 3a03dfb2..381ca9ea 100644 --- a/DiscImageChef.Filesystems/AppleMFS/Dir.cs +++ b/DiscImageChef.Filesystems/AppleMFS/Dir.cs @@ -95,7 +95,6 @@ namespace DiscImageChef.Filesystems.AppleMFS Array.Copy(directoryBlocks, offset + 50, entry.flNam, 0, entry.flNam.Length); lowerFilename = GetStringFromPascal(entry.flNam).ToLowerInvariant().Replace('/', ':'); - if(entry.flFlags.HasFlag(MFS_FileFlags.Used) && !idToFilename.ContainsKey(entry.flFlNum) && !idToEntry.ContainsKey(entry.flFlNum) && !filenameToId.ContainsKey(lowerFilename) && entry.flFlNum > 0) @@ -104,7 +103,6 @@ namespace DiscImageChef.Filesystems.AppleMFS idToFilename.Add(entry.flFlNum, GetStringFromPascal(entry.flNam).Replace('/', ':')); filenameToId.Add(lowerFilename, entry.flFlNum); - System.Console.WriteLine("{0}", offset); DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flFlags = {0}", entry.flFlags); DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flTyp = {0}", entry.flTyp); DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flFlNum = {0}", entry.flFlNum); @@ -120,6 +118,12 @@ namespace DiscImageChef.Filesystems.AppleMFS } offset += (50 + entry.flNam.Length); + + // "Entries are always an integral number of words" + if((offset % 2) != 0) + offset++; + + // TODO: "Entries don't cross logical block boundaries" } return true; diff --git a/DiscImageChef.Filesystems/AppleMFS/Super.cs b/DiscImageChef.Filesystems/AppleMFS/Super.cs index d60d8085..bc36325c 100644 --- a/DiscImageChef.Filesystems/AppleMFS/Super.cs +++ b/DiscImageChef.Filesystems/AppleMFS/Super.cs @@ -84,9 +84,16 @@ namespace DiscImageChef.Filesystems.AppleMFS blockMap = new uint[volMDB.drNmAlBlks + 2 + 1]; for(int i = 2; i < volMDB.drNmAlBlks + 2; i+=8) { - uint tmp1 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset); - uint tmp2 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 4); - uint tmp3 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 8); + uint tmp1 = 0; + uint tmp2 = 0; + uint tmp3 = 0; + + if(offset + 4 <= blockMapBytes.Length) + tmp1 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset); + if(offset + 4 + 4 <= blockMapBytes.Length) + tmp2 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 4); + if(offset + 8 + 4 <= blockMapBytes.Length) + tmp3 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 8); if(i < blockMap.Length) blockMap[i] = (tmp1 & 0xFFF00000) >> 20; diff --git a/DiscImageChef.Filesystems/ChangeLog b/DiscImageChef.Filesystems/ChangeLog index 2557b10f..5d51db16 100644 --- a/DiscImageChef.Filesystems/ChangeLog +++ b/DiscImageChef.Filesystems/ChangeLog @@ -1,3 +1,14 @@ +2016-08-01 Natalia Portillo + + * Dir.cs: Remove spurious debug leftover. + "Entries are always an integral number of words" solved. + + * Super.cs: When filling volume block map, check we are not + going out of bounds. + + * HPFS.cs: + * SysV.cs: Do not try to read past device. + 2016-08-01 Natalia Portillo * Dir.cs: diff --git a/DiscImageChef.Filesystems/HPFS.cs b/DiscImageChef.Filesystems/HPFS.cs index 927d70d1..87da4b40 100644 --- a/DiscImageChef.Filesystems/HPFS.cs +++ b/DiscImageChef.Filesystems/HPFS.cs @@ -56,6 +56,9 @@ namespace DiscImageChef.Filesystems if((2 + partitionStart) >= imagePlugin.GetSectors()) return false; + if(imagePlugin.ImageInfo.sectors <= 16) + return false; + uint magic1, magic2; byte[] hpfs_sb_sector = imagePlugin.ReadSector(16 + partitionStart); // Seek to superblock, on logical sector 16 diff --git a/DiscImageChef.Filesystems/SysV.cs b/DiscImageChef.Filesystems/SysV.cs index b41e5d49..68ba6ec3 100644 --- a/DiscImageChef.Filesystems/SysV.cs +++ b/DiscImageChef.Filesystems/SysV.cs @@ -109,6 +109,9 @@ namespace DiscImageChef.Filesystems // Superblock can start on 0x000, 0x200, 0x600 and 0x800, not aligned, so we assume 16 (128 bytes/sector) sectors as a safe value for(int i = 0; i <= 16; i++) { + if(i + sb_size_in_sectors >= (int)imagePlugin.ImageInfo.sectors) + break; + byte[] sb_sector = imagePlugin.ReadSectors((ulong)i + partitionStart, sb_size_in_sectors); magic = BitConverter.ToUInt32(sb_sector, 0x3F8); // XENIX magic location diff --git a/DiscImageChef.Partitions/ChangeLog b/DiscImageChef.Partitions/ChangeLog index 5c7d072c..ca03d1bd 100644 --- a/DiscImageChef.Partitions/ChangeLog +++ b/DiscImageChef.Partitions/ChangeLog @@ -1,3 +1,7 @@ +2016-08-01 Natalia Portillo + + * NeXT.cs: Do not try to read past device. + 2016-07-29 Natalia Portillo * DiscImageChef.Partitions.csproj: Bump to version 3.1.0. diff --git a/DiscImageChef.Partitions/NeXT.cs b/DiscImageChef.Partitions/NeXT.cs index 1fa1ccac..0329d679 100644 --- a/DiscImageChef.Partitions/NeXT.cs +++ b/DiscImageChef.Partitions/NeXT.cs @@ -58,7 +58,7 @@ namespace DiscImageChef.PartPlugins public override bool GetInformation(ImagePlugins.ImagePlugin imagePlugin, out List partitions) { byte[] cString; - bool magic_found; + bool magic_found = false; byte[] entry_sector; uint magic; @@ -77,7 +77,7 @@ namespace DiscImageChef.PartPlugins if(magic == NEXT_MAGIC1 || magic == NEXT_MAGIC2 || magic == NEXT_MAGIC3) magic_found = true; - else + else if(imagePlugin.ImageInfo.sectors > 15) { entry_sector = imagePlugin.ReadSector(15); // Starts on sector 15 on MBR machines magic = BigEndianBitConverter.ToUInt32(entry_sector, 0x00); @@ -88,7 +88,7 @@ namespace DiscImageChef.PartPlugins { if(sector_size == 2048) entry_sector = imagePlugin.ReadSector(4); // Starts on sector 4 on RISC CDs - else + else if(imagePlugin.ImageInfo.sectors > 16) entry_sector = imagePlugin.ReadSector(16); // Starts on sector 16 on RISC disks magic = BigEndianBitConverter.ToUInt32(entry_sector, 0x00);