From 0024671731fe2dbd14d0a81c26471e3d235cb62a Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 7 Jun 2014 23:32:59 +0100 Subject: [PATCH] * FileSystemIDandChk/TODO: * FileSystemIDandChk/Main.cs: * FileSystemIDandChk/README.md: * FileSystemIDandChk/FileSystemIDandChk.csproj: * FileSystemIDandChk/ImagePlugins/ZZZRawImage.cs: Adds support for RAW (sector by sector) disk images. * FileSystemIDandChk/ImagePlugins/ImagePlugin.cs: Add definitions for BD-R, BD-RE XL and FDFORMAT disk types. * FileSystemIDandChk/ImagePlugins/TeleDisk.cs: Add bounding checks on ReadSectors() --- FileSystemIDandChk/FileSystemIDandChk.csproj | 1 + .../ImagePlugins/ImagePlugin.cs | 21 +- FileSystemIDandChk/ImagePlugins/TeleDisk.cs | 6 + .../ImagePlugins/ZZZRawImage.cs | 618 ++++++++++++++++++ FileSystemIDandChk/Main.cs | 32 +- FileSystemIDandChk/README.md | 1 + FileSystemIDandChk/TODO | 6 +- 7 files changed, 674 insertions(+), 11 deletions(-) create mode 100644 FileSystemIDandChk/ImagePlugins/ZZZRawImage.cs diff --git a/FileSystemIDandChk/FileSystemIDandChk.csproj b/FileSystemIDandChk/FileSystemIDandChk.csproj index 05a75503b..a9e3afe4b 100644 --- a/FileSystemIDandChk/FileSystemIDandChk.csproj +++ b/FileSystemIDandChk/FileSystemIDandChk.csproj @@ -76,6 +76,7 @@ + diff --git a/FileSystemIDandChk/ImagePlugins/ImagePlugin.cs b/FileSystemIDandChk/ImagePlugins/ImagePlugin.cs index a1b75d03e..9afd6b112 100644 --- a/FileSystemIDandChk/ImagePlugins/ImagePlugin.cs +++ b/FileSystemIDandChk/ImagePlugins/ImagePlugin.cs @@ -469,6 +469,10 @@ namespace FileSystemIDandChk.ImagePlugins BDR, /// BD-RE BDRE, + /// BD-R XL + BDRXL, + /// BD-RE XL + BDREXL, // Rare or uncommon standards /// Enhanced Versatile Disc @@ -599,11 +603,11 @@ namespace FileSystemIDandChk.ImagePlugins IBM43FD_128, /// 8", DS, SD, 74 tracks, 26 spt, 256 bytes/sector, FM, track 0 = 26 sectors, 128 bytes/sector IBM43FD_256, - /// 8", DS, DD, 74 tracks, 26 spt, 256 bytes/sector, MFM, track 0 side 0 = 26 sectors, 128 bytes/sector, track 0 side 1 = 26 sectors, 128 bytes/sector + /// 8", DS, DD, 74 tracks, 26 spt, 256 bytes/sector, MFM, track 0 side 0 = 26 sectors, 128 bytes/sector, track 0 side 1 = 26 sectors, 256 bytes/sector IBM53FD_256, - /// 8", DS, DD, 74 tracks, 15 spt, 512 bytes/sector, MFM, track 0 side 0 = 26 sectors, 128 bytes/sector, track 0 side 1 = 26 sectors, 128 bytes/sector + /// 8", DS, DD, 74 tracks, 15 spt, 512 bytes/sector, MFM, track 0 side 0 = 26 sectors, 128 bytes/sector, track 0 side 1 = 26 sectors, 256 bytes/sector IBM53FD_512, - /// 8", DS, DD, 74 tracks, 8 spt, 1024 bytes/sector, MFM, track 0 side 0 = 26 sectors, 128 bytes/sector, track 0 side 1 = 26 sectors, 128 bytes/sector + /// 8", DS, DD, 74 tracks, 8 spt, 1024 bytes/sector, MFM, track 0 side 0 = 26 sectors, 128 bytes/sector, track 0 side 1 = 26 sectors, 256 bytes/sector IBM53FD_1024, // DEC standard floppy formats @@ -704,7 +708,16 @@ namespace FileSystemIDandChk.ImagePlugins // FDFORMAT, non-standard floppy formats /// 5,25", DS, DD, 82 tracks, 10 spt, 512 bytes/sector, MFM - FDFORMAT_525_DD + FDFORMAT_525_DD, + /// 5,25", DS, HD, 82 tracks, 17 spt, 512 bytes/sector, MFM + FDFORMAT_525_HD, + /// 5,25", DS, DD, 82 tracks, 10 spt, 512 bytes/sector, MFM + FDFORMAT_35_DD, + /// 5,25", DS, HD, 82 tracks, 21 spt, 512 bytes/sector, MFM + FDFORMAT_35_HD, + + // Generic hard disks + GENERIC_HDD }; /// diff --git a/FileSystemIDandChk/ImagePlugins/TeleDisk.cs b/FileSystemIDandChk/ImagePlugins/TeleDisk.cs index 1d648524a..e62f8c198 100644 --- a/FileSystemIDandChk/ImagePlugins/TeleDisk.cs +++ b/FileSystemIDandChk/ImagePlugins/TeleDisk.cs @@ -594,6 +594,12 @@ namespace FileSystemIDandChk.ImagePlugins public override byte[] ReadSectors(UInt64 sectorAddress, UInt32 length) { + if (sectorAddress > (ulong)sectorsData.Count - 1) + throw new ArgumentOutOfRangeException("sectorAddress", "Sector address not found"); + + if (sectorAddress + length > (ulong)sectorsData.Count) + throw new ArgumentOutOfRangeException("length", "Requested more sectors than available"); + byte[] data = new byte[1]; // To make compiler happy bool first = true; int dataPosition = 0; diff --git a/FileSystemIDandChk/ImagePlugins/ZZZRawImage.cs b/FileSystemIDandChk/ImagePlugins/ZZZRawImage.cs new file mode 100644 index 000000000..fa744d362 --- /dev/null +++ b/FileSystemIDandChk/ImagePlugins/ZZZRawImage.cs @@ -0,0 +1,618 @@ +/*************************************************************************** +FileSystem identifier and checker +---------------------------------------------------------------------------- + +Filename : ZZZRawImage.cs +Version : 1.0 +Author(s) : Natalia Portillo + +Component : Disc image plugins + +Revision : $Revision$ +Last change by : $Author$ +Date : $Date$ + +--[ Description ] ---------------------------------------------------------- + +Manages raw image, that is, user data sector by sector copy. + +--[ License ] -------------------------------------------------------------- + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +---------------------------------------------------------------------------- +Copyright (C) 2011-2014 Claunia.com +****************************************************************************/ +//$Id$ + +using System; +using System.IO; +using System.Collections.Generic; + +namespace FileSystemIDandChk.ImagePlugins +{ + // Checked using several images and strings inside Apple's DiskImages.framework + class ZZZRawImage : ImagePlugin + { + #region Internal variables + + UInt64 imageSize; + UInt64 sectors; + UInt32 sectorSize; + DateTime creationTime; + DateTime modificationTime; + string imageName; + string rawImagePath; + bool differentTrackZeroSize; + #endregion + + public ZZZRawImage(PluginBase Core) + { + Name = "Raw Disk Image"; + // Non-random UUID to recognize this specific plugin + PluginUUID = new Guid("12345678-AAAA-BBBB-CCCC-123456789000"); + } + + public override bool IdentifyImage(string imagePath) + { + FileInfo fi = new FileInfo(imagePath); + + // Check if file is not multiple of 512 + if ((fi.Length % 512) != 0) + { + // Check known disk sizes with sectors smaller than 512 + switch (fi.Length) + { + case 81664: + case 116480: + case 242944: + case 256256: + case 287488: + case 306432: + case 495872: + case 988416: + case 995072: + case 1021696: + case 1146624: + case 1177344: + case 1222400: + case 1304320: + case 1255168: + return true; + default: + return false; + } + } + + return true; + } + + public override bool OpenImage(string imagePath) + { + FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + stream.Seek(0, SeekOrigin.Begin); + + FileInfo fi = new FileInfo(imagePath); + string extension = Path.GetExtension(imagePath).ToLower(); + if (extension == ".iso" && (fi.Length % 2048) == 0) + sectorSize = 2048; + else + { + switch (fi.Length) + { + case 242944: + case 256256: + case 495872: + case 92160: + case 133120: + sectorSize = 128; + break; + case 116480: + case 287488: // T0S0 = 128bps + case 988416: // T0S0 = 128bps + case 995072: // T0S0 = 128bps, T0S1 = 256bps + case 1021696: // T0S0 = 128bps, T0S1 = 256bps + case 232960: + case 143360: + case 286720: + case 512512: + case 102400: + case 204800: + case 163840: + case 327680: + case 655360: + case 80384: // T0S0 = 128bps + case 325632: // T0S0 = 128bps, T0S1 = 256bps + case 653312: // T0S0 = 128bps, T0S1 = 256bps + sectorSize = 256; + break; + case 81664: + sectorSize = 319; + break; + case 306432: // T0S0 = 128bps + case 1146624: // T0S0 = 128bps, T0S1 = 256bps + case 1177344: // T0S0 = 128bps, T0S1 = 256bps + sectorSize = 512; + break; + case 1222400: // T0S0 = 128bps, T0S1 = 256bps + case 1304320: // T0S0 = 128bps, T0S1 = 256bps + case 1255168: // T0S0 = 128bps, T0S1 = 256bps + case 1261568: + case 1310720: + sectorSize = 1024; + break; + default: + sectorSize = 512; + break; + } + } + + imageSize = (ulong)fi.Length; + creationTime = fi.CreationTimeUtc; + modificationTime = fi.LastWriteTimeUtc; + imageName = Path.GetFileNameWithoutExtension(imagePath); + differentTrackZeroSize = false; + rawImagePath = imagePath; + + switch (fi.Length) + { + case 242944: + sectors = 1898; + break; + case 256256: + sectors = 2002; + break; + case 495872: + sectors = 3874; + break; + case 116480: + sectors = 455; + break; + case 287488: // T0S0 = 128bps + sectors = 1136; + differentTrackZeroSize = true; + break; + case 988416: // T0S0 = 128bps + sectors = 3874; + differentTrackZeroSize = true; + break; + case 995072: // T0S0 = 128bps, T0S1 = 256bps + sectors = 3900; + differentTrackZeroSize = true; + break; + case 1021696: // T0S0 = 128bps, T0S1 = 256bps + sectors = 4004; + differentTrackZeroSize = true; + break; + case 81664: + sectors = 256; + break; + case 306432: // T0S0 = 128bps + sectors = 618; + differentTrackZeroSize = true; + break; + case 1146624: // T0S0 = 128bps, T0S1 = 256bps + sectors = 2272; + differentTrackZeroSize = true; + break; + case 1177344: // T0S0 = 128bps, T0S1 = 256bps + sectors = 2332; + differentTrackZeroSize = true; + break; + case 1222400: // T0S0 = 128bps, T0S1 = 256bps + sectors = 1236; + differentTrackZeroSize = true; + break; + case 1304320: // T0S0 = 128bps, T0S1 = 256bps + sectors = 1316; + differentTrackZeroSize = true; + break; + case 1255168: // T0S0 = 128bps, T0S1 = 256bps + sectors = 1268; + differentTrackZeroSize = true; + break; + case 80384: // T0S0 = 128bps + sectors = 322; + differentTrackZeroSize = true; + break; + case 325632: // T0S0 = 128bps, T0S1 = 256bps + sectors = 1280; + differentTrackZeroSize = true; + break; + case 653312: // T0S0 = 128bps, T0S1 = 256bps + sectors = 2560; + differentTrackZeroSize = true; + break; + case 1880064: // IBM XDF, 3,5", real number of sectors + sectors = 670; + sectorSize = 8192; // Biggest sector size + differentTrackZeroSize = true; + break; + default: + sectors = imageSize / sectorSize; + break; + } + + return true; + } + + public override bool ImageHasPartitions() + { + return false; + } + + public override UInt64 GetImageSize() + { + return imageSize; + } + + public override UInt64 GetSectors() + { + return sectors; + } + + public override UInt32 GetSectorSize() + { + return sectorSize; + } + + public override byte[] ReadSector(UInt64 sectorAddress) + { + return ReadSectors(sectorAddress, 1); + } + + public override byte[] ReadSectors(UInt64 sectorAddress, UInt32 length) + { + if (differentTrackZeroSize) + { + throw new NotImplementedException("Not yet implemented"); + } + else + { + if (sectorAddress > sectors - 1) + throw new ArgumentOutOfRangeException("sectorAddress", "Sector address not found"); + + if (sectorAddress + length > sectors) + throw new ArgumentOutOfRangeException("length", "Requested more sectors than available"); + + byte[] buffer = new byte[length * sectorSize]; + + FileStream stream = new FileStream(rawImagePath, FileMode.Open, FileAccess.Read); + + stream.Seek((long)(sectorAddress * sectorSize), SeekOrigin.Begin); + + stream.Read(buffer, 0, (int)(length * sectorSize)); + + return buffer; + + } + } + + public override string GetImageFormat() + { + return "Raw disk image (sector by sector copy)"; + } + + public override DateTime GetImageCreationTime() + { + return creationTime; + } + + public override DateTime GetImageLastModificationTime() + { + return modificationTime; + } + + public override string GetImageName() + { + return imageName; + } + + public override DiskType GetDiskType() + { + if (sectorSize == 2048) + { + if (sectors <= 360000) + return DiskType.CD; + if (sectors <= 2295104) + return DiskType.DVDPR; + if (sectors <= 2298496) + return DiskType.DVDR; + if (sectors <= 4171712) + return DiskType.DVDRDL; + if (sectors <= 4173824) + return DiskType.DVDPRDL; + if (sectors <= 24438784) + return DiskType.BDR; + if (sectors <= 62500864) + return DiskType.BDRXL; + return DiskType.Unknown; + } + else + { + switch (imageSize) + { + case 80384: + return DiskType.ECMA_66; + case 81664: + return DiskType.IBM23FD; + case 92160: + return DiskType.ATARI_525_SD; + case 102400: + return DiskType.ACORN_525_SS_SD_40; + case 116480: + return DiskType.Apple32SS; + case 133120: + return DiskType.ATARI_525_ED; + case 143360: + return DiskType.Apple33SS; + case 163840: + return DiskType.DOS_525_SS_DD_8; + case 184320: + return DiskType.DOS_525_SS_DD_9; + case 204800: + return DiskType.ACORN_525_SS_SD_80; + case 232960: + return DiskType.Apple32DS; + case 242944: + return DiskType.IBM33FD_128; + case 256256: + return DiskType.ECMA_54; + case 286720: + return DiskType.Apple33DS; + case 287488: + return DiskType.IBM33FD_256; + case 306432: + return DiskType.IBM33FD_512; + case 325632: + return DiskType.ECMA_70; + case 327680: + return DiskType.DOS_525_DS_DD_8; + case 368640: + return DiskType.DOS_525_DS_DD_9; + case 409600: + return DiskType.AppleSonySS; + case 495872: + return DiskType.IBM43FD_128; + case 512512: + return DiskType.ECMA_59; + case 653312: + return DiskType.ECMA_78; + case 655360: + return DiskType.ACORN_525_DS_DD; + case 737280: + return DiskType.DOS_35_DS_DD_9; + case 819200: + return DiskType.AppleSonyDS; + case 839680: + return DiskType.FDFORMAT_35_DD; + case 901120: + return DiskType.CBM_AMIGA_35_DD; + case 988416: + return DiskType.IBM43FD_256; + case 995072: + return DiskType.IBM53FD_256; + case 1021696: + return DiskType.ECMA_99_26; + case 1146624: + return DiskType.IBM53FD_512; + case 1177344: + return DiskType.ECMA_99_15; + case 1222400: + return DiskType.IBM53FD_1024; + case 1228800: + return DiskType.DOS_525_HD; + case 1255168: + return DiskType.ECMA_69_8; + case 1261568: + return DiskType.NEC_8_DD; + case 1304320: + return DiskType.ECMA_99_8; + case 1310720: + return DiskType.NEC_525_HD; + case 1427456: + return DiskType.FDFORMAT_525_HD; + case 1474560: + return DiskType.DOS_35_HD; + case 1720320: + return DiskType.DMF; + case 1763328: + return DiskType.FDFORMAT_35_HD; + case 1802240: + return DiskType.CBM_AMIGA_35_HD; + case 1880064: + return DiskType.XDF_35; + case 1884160: + return DiskType.XDF_35; + case 2949120: + return DiskType.DOS_35_ED; + case 128000000: + return DiskType.ECMA_154; + case 229632000: + return DiskType.ECMA_201; + case 481520640: + return DiskType.ECMA_183_512; + case 533403648: + return DiskType.ECMA_183_1024; + case 596787200: + return DiskType.ECMA_184_512; + case 654540800: + return DiskType.ECMA_184_1024; + default: + return DiskType.GENERIC_HDD; + } + } + } + + #region Unsupported features + + public override byte[] ReadSectorTag(UInt64 sectorAddress, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSectorsTag(UInt64 sectorAddress, UInt32 length, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSectorLong(UInt64 sectorAddress) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSectorsLong(UInt64 sectorAddress, UInt32 length) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetImageVersion() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetImageApplication() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetImageApplicationVersion() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadDiskTag(DiskTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetImageCreator() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetImageComments() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetDiskManufacturer() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetDiskModel() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetDiskSerialNumber() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetDiskBarcode() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetDiskPartNumber() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override int GetDiskSequence() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override int GetLastDiskSequence() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetDriveManufacturer() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetDriveModel() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override string GetDriveSerialNumber() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override List GetPartitions() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override List GetTracks() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override List GetSessionTracks(Session session) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override List GetSessionTracks(UInt16 session) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override List GetSessions() + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSector(UInt64 sectorAddress, UInt32 track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSectorTag(UInt64 sectorAddress, UInt32 track, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSectors(UInt64 sectorAddress, UInt32 length, UInt32 track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSectorsTag(UInt64 sectorAddress, UInt32 length, UInt32 track, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSectorLong(UInt64 sectorAddress, UInt32 track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public override byte[] ReadSectorsLong(UInt64 sectorAddress, UInt32 length, UInt32 track) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + #endregion Unsupported features + } +} + diff --git a/FileSystemIDandChk/Main.cs b/FileSystemIDandChk/Main.cs index 11b385188..0d3a758e5 100644 --- a/FileSystemIDandChk/Main.cs +++ b/FileSystemIDandChk/Main.cs @@ -69,7 +69,7 @@ namespace FileSystemIDandChk if (isDebug) { plugins.RegisterAllPlugins(); - Runner("/Users/claunia/Desktop/disk_images/teledisk.td0"); + Runner(""); } else { @@ -139,16 +139,38 @@ namespace FileSystemIDandChk { _imageFormat = null; + // Check all but RAW plugin foreach (ImagePlugin _imageplugin in plugins.ImagePluginsList.Values) { - if (_imageplugin.IdentifyImage(filename)) + if(_imageplugin.PluginUUID != new Guid("12345678-AAAA-BBBB-CCCC-123456789000")) { - _imageFormat = _imageplugin; - Console.WriteLine("Image format identified by {0}.", _imageplugin.Name); - break; + if (_imageplugin.IdentifyImage(filename)) + { + _imageFormat = _imageplugin; + Console.WriteLine("Image format identified by {0}.", _imageplugin.Name); + break; + } } } + // Check only RAW plugin + if (_imageFormat == null) + { + foreach (ImagePlugin _imageplugin in plugins.ImagePluginsList.Values) + { + if(_imageplugin.PluginUUID == new Guid("12345678-AAAA-BBBB-CCCC-123456789000")) + { + if (_imageplugin.IdentifyImage(filename)) + { + _imageFormat = _imageplugin; + Console.WriteLine("Image format identified by {0}.", _imageplugin.Name); + break; + } + } + } + } + + // Still not recognized if (_imageFormat == null) { Console.WriteLine("Image format not identified, not proceeding."); diff --git a/FileSystemIDandChk/README.md b/FileSystemIDandChk/README.md index 3db19ef93..9bc59eb94 100644 --- a/FileSystemIDandChk/README.md +++ b/FileSystemIDandChk/README.md @@ -18,6 +18,7 @@ Features ======== * Supports reading CDRWin cue/bin cuesheets, Apple DiskCopy 4.2 and TeleDisk disk images. +* Supports reading all raw (sector by sector copy) disk images with a multiple of 512 bytes/sector, and a few known formats that are 256, 128 and variable bytes per sector. * Supports traversing MBR, Apple and NeXT partitioning schemes. * Identifies HFS, HFS+, MFS, BeFS, ext/2/3/4, FAT12/16/32, FFS/UFS/UFS2, HPFS, ISO9660, LisaFS, MinixFS, NTFS, ODS11, Opera, PCEngine, SolarFS, System V and UnixWare boot filesystem. diff --git a/FileSystemIDandChk/TODO b/FileSystemIDandChk/TODO index 6062d0372..d181a538d 100644 --- a/FileSystemIDandChk/TODO +++ b/FileSystemIDandChk/TODO @@ -1,5 +1,4 @@ Disc image plugins: ---- Add support for no disc image, that is, raw. --- Add support for BlindWrite images --- Add support for CloneCD images --- Add support for DiscJuggler images @@ -66,4 +65,7 @@ Other things: Teledisk plugin: --- Add support for "advanced compression" ---- Handle variable sectors per track situation. Teledisk seems to be able to read garbage from previous formattings. \ No newline at end of file +--- Handle variable sectors per track situation. Teledisk seems to be able to read garbage from previous formattings. + +RAW plugin: +--- Finish support for reading sectors of variable bytes/sector images \ No newline at end of file