From 258e32d733080d3bc49189d6f3bf6703393a02a2 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sun, 31 Jul 2016 22:12:48 +0100 Subject: [PATCH] * DiscImageChef.DiscImages/DiskCopy42.cs: Swap tracks in second half of twiggy images. * DiscImageChef.Filesystems/UCSDPascal/File.cs: * DiscImageChef.Filesystems/UCSDPascal/Super.cs: Corrected file size calculation. --- DiscImageChef.DiscImages/ChangeLog | 4 + DiscImageChef.DiscImages/DiskCopy42.cs | 92 ++++++++++++++++--- DiscImageChef.Filesystems/ChangeLog | 5 + DiscImageChef.Filesystems/UCSDPascal/File.cs | 46 ++++++++-- DiscImageChef.Filesystems/UCSDPascal/Super.cs | 4 +- 5 files changed, 126 insertions(+), 25 deletions(-) diff --git a/DiscImageChef.DiscImages/ChangeLog b/DiscImageChef.DiscImages/ChangeLog index 23539e63..dda2adda 100644 --- a/DiscImageChef.DiscImages/ChangeLog +++ b/DiscImageChef.DiscImages/ChangeLog @@ -1,3 +1,7 @@ +2016-07-31 Natalia Portillo + + * DiskCopy42.cs: Swap tracks in second half of twiggy images. + 2016-07-29 Natalia Portillo * DiscImageChef.DiscImages.csproj: Bump to version 3.1.0. diff --git a/DiscImageChef.DiscImages/DiskCopy42.cs b/DiscImageChef.DiscImages/DiskCopy42.cs index 086a05d8..ac67dc93 100644 --- a/DiscImageChef.DiscImages/DiskCopy42.cs +++ b/DiscImageChef.DiscImages/DiskCopy42.cs @@ -124,6 +124,10 @@ namespace DiscImageChef.ImagePlugins /// Disk image file string dc42ImagePath; + byte[] twiggyCache; + byte[] twiggyCacheTags; + bool twiggy; + #endregion public DiskCopy42() @@ -369,6 +373,58 @@ namespace DiscImageChef.ImagePlugins break; } + 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]; + + twiggyCache = new byte[header.dataSize]; + twiggyCacheTags = new byte[header.tagSize]; + twiggy = true; + + FileStream datastream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + datastream.Seek((dataOffset), SeekOrigin.Begin); + datastream.Read(data, 0, (int)header.dataSize); + datastream.Close(); + + FileStream tagstream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + tagstream.Seek((tagOffset), SeekOrigin.Begin); + 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); + + int copiedSectors = 0; + int sectorsToCopy = 0; + + 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; + } + } + return true; } @@ -479,13 +535,17 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[length * ImageInfo.sectorSize]; - FileStream stream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); - - stream.Seek((long)(dataOffset + sectorAddress * ImageInfo.sectorSize), SeekOrigin.Begin); - - stream.Read(buffer, 0, (int)(length * ImageInfo.sectorSize)); - - stream.Close(); + if(twiggy) + { + Array.Copy(twiggyCache, (int)sectorAddress * ImageInfo.sectorSize, buffer, 0, length * ImageInfo.sectorSize); + } + else + { + FileStream stream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + stream.Seek((long)(dataOffset + sectorAddress * ImageInfo.sectorSize), SeekOrigin.Begin); + stream.Read(buffer, 0, (int)(length * ImageInfo.sectorSize)); + stream.Close(); + } return buffer; } @@ -506,13 +566,17 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[length * bptag]; - FileStream stream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); - - stream.Seek((long)(tagOffset + sectorAddress * bptag), SeekOrigin.Begin); - - stream.Read(buffer, 0, (int)(length * bptag)); - - stream.Close(); + if(twiggy) + { + Array.Copy(twiggyCacheTags, (int)sectorAddress * bptag, buffer, 0, length * bptag); + } + else + { + FileStream stream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + stream.Seek((long)(tagOffset + sectorAddress * bptag), SeekOrigin.Begin); + stream.Read(buffer, 0, (int)(length * bptag)); + stream.Close(); + } return buffer; } diff --git a/DiscImageChef.Filesystems/ChangeLog b/DiscImageChef.Filesystems/ChangeLog index ded919ec..3a27fdef 100644 --- a/DiscImageChef.Filesystems/ChangeLog +++ b/DiscImageChef.Filesystems/ChangeLog @@ -1,3 +1,8 @@ +2016-07-31 Natalia Portillo + + * File.cs: + * Super.cs: Corrected file size calculation. + 2016-07-31 Natalia Portillo * Dir.cs: diff --git a/DiscImageChef.Filesystems/UCSDPascal/File.cs b/DiscImageChef.Filesystems/UCSDPascal/File.cs index 1411968b..3b3edc5a 100644 --- a/DiscImageChef.Filesystems/UCSDPascal/File.cs +++ b/DiscImageChef.Filesystems/UCSDPascal/File.cs @@ -95,18 +95,15 @@ namespace DiscImageChef.Filesystems.UCSDPascal if(error != Errno.NoError) return error; - byte[] tmp = device.ReadSectors((ulong)entry.firstBlock, (uint)(entry.lastBlock - entry.firstBlock + 1)); - file = new byte[(entry.lastBlock - entry.firstBlock) * device.GetSectorSize() + entry.lastBytes]; + byte[] tmp = device.ReadSectors((ulong)entry.firstBlock, (uint)(entry.lastBlock - entry.firstBlock)); + file = new byte[(entry.lastBlock - entry.firstBlock - 1) * device.GetSectorSize() + entry.lastBytes]; Array.Copy(tmp, 0, file, 0, file.Length); } - if(offset >= file.Length || size == 0 || offset + size == file.Length) - { - buf = new byte[0]; - return Errno.NoError; - } + if(offset >= file.Length) + return Errno.EINVAL; - if(offset + size > file.Length) + if(size + offset >= file.Length) size = file.Length - offset; buf = new byte[size]; @@ -128,6 +125,37 @@ namespace DiscImageChef.Filesystems.UCSDPascal if(pathElements.Length != 1) return Errno.NotSupported; + if(debug) + { + if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0 || + string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0) + { + stat = new FileEntryInfo(); + stat.Attributes = new FileAttributes(); + stat.Attributes = FileAttributes.System; + stat.BlockSize = device.GetSectorSize(); + stat.DeviceNo = 0; + stat.GID = 0; + stat.Inode = 0; + stat.Links = 1; + stat.Mode = 0x124; + stat.UID = 0; + + if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0) + { + stat.Blocks = catalogBlocks.Length / stat.BlockSize; + stat.Length = catalogBlocks.Length; + } + else + { + stat.Blocks = bootBlocks.Length / stat.BlockSize; + stat.Length = bootBlocks.Length; + } + + return Errno.NoError; + } + } + PascalFileEntry entry; Errno error = GetFileEntry(path, out entry); @@ -137,7 +165,7 @@ namespace DiscImageChef.Filesystems.UCSDPascal stat = new FileEntryInfo(); stat.Attributes = new FileAttributes(); stat.Attributes = FileAttributes.File; - stat.Blocks = entry.lastBlock - entry.firstBlock + 1; + stat.Blocks = entry.lastBlock - entry.firstBlock; stat.BlockSize = device.GetSectorSize(); stat.DeviceNo = 0; stat.GID = 0; diff --git a/DiscImageChef.Filesystems/UCSDPascal/Super.cs b/DiscImageChef.Filesystems/UCSDPascal/Super.cs index 04832c2f..0155f72d 100644 --- a/DiscImageChef.Filesystems/UCSDPascal/Super.cs +++ b/DiscImageChef.Filesystems/UCSDPascal/Super.cs @@ -126,9 +126,9 @@ namespace DiscImageChef.Filesystems.UCSDPascal stat.PluginId = PluginUUID; stat.Type = "UCSD Pascal"; - stat.FreeBlocks = mountedVolEntry.blocks - (mountedVolEntry.lastBlock - mountedVolEntry.firstBlock + 1); + stat.FreeBlocks = mountedVolEntry.blocks - (mountedVolEntry.lastBlock - mountedVolEntry.firstBlock); foreach(PascalFileEntry entry in fileEntries) - stat.FreeBlocks -= (entry.lastBlock - entry.firstBlock + 1); + stat.FreeBlocks -= (entry.lastBlock - entry.firstBlock); return Errno.NotImplemented; }