public void Test() { for (int i = 0; i < _testFiles.Length; i++) { string location = Path.Combine(Consts.TEST_FILES_ROOT, "Filesystems", "QNX 4 filesystem (MBR)", _testFiles[i]); IFilter filter = new ZZZNoFilter(); filter.Open(location); IMediaImage image = new AaruFormat(); Assert.AreEqual(true, image.Open(filter), _testFiles[i]); Assert.AreEqual(_sectors[i], image.Info.Sectors, _testFiles[i]); Assert.AreEqual(_sectorSize[i], image.Info.SectorSize, _testFiles[i]); List <Partition> partitions = Core.Partitions.GetAll(image); IFilesystem fs = new QNX4(); int part = -1; for (int j = 0; j < partitions.Count; j++) { if (partitions[j].Type == "0x4D") { part = j; break; } } Assert.AreNotEqual(-1, part, $"Partition not found on {_testFiles[i]}"); Assert.AreEqual(true, fs.Identify(image, partitions[part]), _testFiles[i]); fs.GetInformation(image, partitions[part], out _, null); Assert.AreEqual(_clusters[i], fs.XmlFsType.Clusters, _testFiles[i]); Assert.AreEqual(_clusterSize[i], fs.XmlFsType.ClusterSize, _testFiles[i]); Assert.AreEqual("QNX4 filesystem", fs.XmlFsType.Type, _testFiles[i]); } }
public void Test() { for (int i = 0; i < _testFiles.Length; i++) { string location = Path.Combine(Consts.TEST_FILES_ROOT, "Partitioning schemes", "MINIX", _testFiles[i]); IFilter filter = new ZZZNoFilter(); filter.Open(location); IMediaImage image = new AaruFormat(); Assert.AreEqual(true, image.Open(filter), _testFiles[i]); List <Partition> partitions = Core.Partitions.GetAll(image); Assert.AreEqual(_wanted[i].Length, partitions.Count, _testFiles[i]); for (int j = 0; j < partitions.Count; j++) { // Too chatty //Assert.AreEqual(wanted[i][j].PartitionDescription, partitions[j].PartitionDescription, testfiles[i]); Assert.AreEqual(_wanted[i][j].Size, partitions[j].Size, _testFiles[i]); // Assert.AreEqual(wanted[i][j].Name, partitions[j].Name, testfiles[i]); Assert.AreEqual(_wanted[i][j].Type, partitions[j].Type, _testFiles[i]); Assert.AreEqual(_wanted[i][j].Offset, partitions[j].Offset, _testFiles[i]); Assert.AreEqual(_wanted[i][j].Length, partitions[j].Length, _testFiles[i]); Assert.AreEqual(_wanted[i][j].Sequence, partitions[j].Sequence, _testFiles[i]); Assert.AreEqual(_wanted[i][j].Start, partitions[j].Start, _testFiles[i]); } } }
public void Test() { for (int i = 0; i < _testFiles.Length; i++) { string location = Path.Combine(Consts.TEST_FILES_ROOT, "Filesystems", "Universal Disc Format", _testFiles[i]); IFilter filter = new ZZZNoFilter(); filter.Open(location); IMediaImage image = new AaruFormat(); Assert.AreEqual(true, image.Open(filter), _testFiles[i]); Assert.AreEqual(_sectors[i], image.Info.Sectors, _testFiles[i]); Assert.AreEqual(_sectorSize[i], image.Info.SectorSize, _testFiles[i]); IFilesystem fs = new UDF(); var wholePart = new Partition { Name = "Whole device", Length = image.Info.Sectors, Size = image.Info.Sectors * image.Info.SectorSize }; Assert.AreEqual(true, fs.Identify(image, wholePart), _testFiles[i]); fs.GetInformation(image, wholePart, out _, null); Assert.AreEqual(_clusters[i], fs.XmlFsType.Clusters, _testFiles[i]); Assert.AreEqual(_clusterSize[i], fs.XmlFsType.ClusterSize, _testFiles[i]); Assert.AreEqual(_udfversion[i], fs.XmlFsType.Type, _testFiles[i]); Assert.AreEqual(_volumeName[i], fs.XmlFsType.VolumeName, _testFiles[i]); Assert.AreEqual(_volumeSerial[i], fs.XmlFsType.VolumeSetIdentifier, _testFiles[i]); Assert.AreEqual(_oemId[i], fs.XmlFsType.SystemIdentifier, _testFiles[i]); } }
public void Test() { for (int i = 0; i < _testFiles.Length; i++) { string location = Path.Combine(Consts.TEST_FILES_ROOT, "Filesystems", "ISO9660", _testFiles[i]); IFilter filter = new ZZZNoFilter(); filter.Open(location); IMediaImage image = new AaruFormat(); Assert.AreEqual(true, image.Open(filter), $"{_testFiles[i]}: Open()"); Assert.AreEqual(_mediaTypes[i], image.Info.MediaType, $"{_testFiles[i]}: MediaType"); Assert.AreEqual(_sectors[i], image.Info.Sectors, $"{_testFiles[i]}: Sectors"); Assert.AreEqual(_sectorSize[i], image.Info.SectorSize, $"{_testFiles[i]}: SectorSize"); IFilesystem fs = new ISO9660(); var wholePart = new Partition { Name = "Whole device", Length = image.Info.Sectors, Size = image.Info.Sectors * image.Info.SectorSize }; Assert.AreEqual(true, fs.Identify(image, wholePart), $"{_testFiles[i]}: Identify()"); fs.GetInformation(image, wholePart, out _, null); Assert.AreEqual(_clusters[i], fs.XmlFsType.Clusters, $"{_testFiles[i]}: Clusters"); Assert.AreEqual(_clusterSize[i], fs.XmlFsType.ClusterSize, $"{_testFiles[i]}: ClusterSize"); Assert.AreEqual("ISO9660", fs.XmlFsType.Type, $"{_testFiles[i]}: Type"); Assert.AreEqual(_volumeName[i], fs.XmlFsType.VolumeName, $"{_testFiles[i]}: VolumeName"); Assert.AreEqual(_volumeSerial[i], fs.XmlFsType.VolumeSerial, $"{_testFiles[i]}: VolumeSerial"); Assert.AreEqual(_sysid[i], fs.XmlFsType.SystemIdentifier, $"{_testFiles[i]}: SystemIdentifier"); Assert.AreEqual(_appid[i], fs.XmlFsType.ApplicationIdentifier, $"{_testFiles[i]}: ApplicationIdentifier"); } }
public void Test() { for (int i = 0; i < _testFiles.Length; i++) { string location = Path.Combine(Consts.TEST_FILES_ROOT, "Filesystems", "High Performance File System", _testFiles[i]); IFilter filter = new ZZZNoFilter(); filter.Open(location); IMediaImage image = new AaruFormat(); Assert.AreEqual(true, image.Open(filter), _testFiles[i]); Assert.AreEqual(_sectors[i], image.Info.Sectors, _testFiles[i]); Assert.AreEqual(_sectorSize[i], image.Info.SectorSize, _testFiles[i]); List <Partition> partitions = Core.Partitions.GetAll(image); IFilesystem fs = new HPFS(); Assert.AreEqual(true, fs.Identify(image, partitions[0]), _testFiles[i]); fs.GetInformation(image, partitions[0], out _, null); Assert.AreEqual(_clusters[i], fs.XmlFsType.Clusters, _testFiles[i]); Assert.AreEqual(_clusterSize[i], fs.XmlFsType.ClusterSize, _testFiles[i]); Assert.AreEqual("HPFS", fs.XmlFsType.Type, _testFiles[i]); Assert.AreEqual(_volumeName[i], fs.XmlFsType.VolumeName, _testFiles[i]); Assert.AreEqual(_volumeSerial[i], fs.XmlFsType.VolumeSerial, _testFiles[i]); Assert.AreEqual(_oemId[i], fs.XmlFsType.SystemIdentifier, _testFiles[i]); } }
public async void LoadButton_Click(object sender, RoutedEventArgs e) { string path = await GetPath(); if (path == null) { return; } await Task.Run(() => { AaruFormat image = new AaruFormat(); IFilter filter = new ZZZNoFilter(); filter.Open(path); image.Open(filter); Player.Init(image, App.Settings.AutoPlay); }); await Dispatcher.UIThread.InvokeAsync(() => { MainWindow.Instance.Title = "RedBookPlayer - " + path.Split('/').Last().Split('\\').Last(); } ); }
public void Test() { Environment.CurrentDirectory = Path.Combine(Consts.TEST_FILES_ROOT, "Media image formats", "UltraISO", "Alcohol"); for (int i = 0; i < _testFiles.Length; i++) { var filter = new ZZZNoFilter(); filter.Open(_testFiles[i]); var image = new DiscImages.Alcohol120(); bool opened = image.Open(filter); Assert.AreEqual(true, opened, $"Open: {_testFiles[i]}"); using (new AssertionScope()) { Assert.Multiple(() => { Assert.AreEqual(_sectors[i], image.Info.Sectors, $"Sectors: {_testFiles[i]}"); Assert.AreEqual(_mediaTypes[i], image.Info.MediaType, $"Media type: {_testFiles[i]}"); Assert.AreEqual(_tracks[i], image.Tracks.Count, $"Tracks: {_testFiles[i]}"); image.Tracks.Select(t => t.TrackSession).Should(). BeEquivalentTo(_trackSessions[i], $"Track session: {_testFiles[i]}"); image.Tracks.Select(t => t.TrackStartSector).Should(). BeEquivalentTo(_trackStarts[i], $"Track start: {_testFiles[i]}"); image.Tracks.Select(t => t.TrackEndSector).Should(). BeEquivalentTo(_trackEnds[i], $"Track end: {_testFiles[i]}"); image.Tracks.Select(t => t.TrackPregap).Should(). BeEquivalentTo(_trackPregaps[i], $"Track pregap: {_testFiles[i]}"); int trackNo = 0; byte[] flags = new byte[image.Tracks.Count]; foreach (Track currentTrack in image.Tracks) { if (image.Info.ReadableSectorTags.Contains(SectorTagType.CdTrackFlags)) { flags[trackNo] = image.ReadSectorTag(currentTrack.TrackSequence, SectorTagType.CdTrackFlags)[0]; } trackNo++; } flags.Should().BeEquivalentTo(_trackFlags[i], $"Track flags: {_testFiles[i]}"); }); } } }
public void Test() { for (int i = 0; i < _testFiles.Length; i++) { string location = Path.Combine(Consts.TEST_FILES_ROOT, "Filesystems", "UNIX filesystem (MBR)", _testFiles[i]); IFilter filter = new ZZZNoFilter(); filter.Open(location); IMediaImage image = new AaruFormat(); Assert.AreEqual(true, image.Open(filter), _testFiles[i]); Assert.AreEqual(_sectors[i], image.Info.Sectors, _testFiles[i]); Assert.AreEqual(_sectorSize[i], image.Info.SectorSize, _testFiles[i]); List <Partition> partitions = Core.Partitions.GetAll(image); IFilesystem fs = new FFSPlugin(); int part = -1; for (int j = 0; j < partitions.Count; j++) { if (partitions[j].Type == "0x63" || partitions[j].Type == "0xA8" || partitions[j].Type == "0xA5" || partitions[j].Type == "0xA9" || partitions[j].Type == "0x82" || partitions[j].Type == "0x83" || partitions[j].Type == "4.2BSD Fast File System" || partitions[j].Type == "Sun boot") { part = j; break; } } Assert.AreNotEqual(-1, part, $"Partition not found on {_testFiles[i]}"); Assert.AreEqual(true, fs.Identify(image, partitions[part]), _testFiles[i]); fs.GetInformation(image, partitions[part], out _, null); Assert.AreEqual(_clusters[i], fs.XmlFsType.Clusters, _testFiles[i]); Assert.AreEqual(_clusterSize[i], fs.XmlFsType.ClusterSize, _testFiles[i]); Assert.AreEqual(_type[i], fs.XmlFsType.Type, _testFiles[i]); Assert.AreEqual(_volumeName[i], fs.XmlFsType.VolumeName, _testFiles[i]); Assert.AreEqual(_volumeSerial[i], fs.XmlFsType.VolumeSerial, _testFiles[i]); } }
public void Test() { for (int i = 0; i < _testFiles.Length; i++) { string location = Path.Combine(Consts.TEST_FILES_ROOT, "Filesystems", "New Technology File System (MBR)", _testFiles[i]); IFilter filter = new ZZZNoFilter(); filter.Open(location); IMediaImage image = new AaruFormat(); Assert.AreEqual(true, image.Open(filter), _testFiles[i]); Assert.AreEqual(_sectors[i], image.Info.Sectors, _testFiles[i]); Assert.AreEqual(_sectorSize[i], image.Info.SectorSize, _testFiles[i]); List <Partition> partitions = Core.Partitions.GetAll(image); IFilesystem fs = new NTFS(); int part = -1; for (int j = 0; j < partitions.Count; j++) { if (partitions[j].Type == "0x07" || // Value incorrectly set by Haiku partitions[j].Type == "0x86") { part = j; break; } } Assert.AreNotEqual(-1, part, $"Partition not found on {_testFiles[i]}"); Assert.AreEqual(true, fs.Identify(image, partitions[part]), _testFiles[i]); fs.GetInformation(image, partitions[part], out _, null); Assert.AreEqual(_clusters[i], fs.XmlFsType.Clusters, _testFiles[i]); Assert.AreEqual(_clusterSize[i], fs.XmlFsType.ClusterSize, _testFiles[i]); Assert.AreEqual("NTFS", fs.XmlFsType.Type, _testFiles[i]); Assert.AreEqual(_volumeName[i], fs.XmlFsType.VolumeName, _testFiles[i]); Assert.AreEqual(_volumeSerial[i], fs.XmlFsType.VolumeSerial, _testFiles[i]); Assert.AreEqual(_oemId[i], fs.XmlFsType.SystemIdentifier, _testFiles[i]); } }
public void Test() { for (int i = 0; i < _testFiles.Length; i++) { string location = Path.Combine(Consts.TEST_FILES_ROOT, "Filesystems", "ext2", _testFiles[i]); IFilter filter = new ZZZNoFilter(); filter.Open(location); IMediaImage image = new AaruFormat(); Assert.AreEqual(true, image.Open(filter), _testFiles[i]); Assert.AreEqual(_sectors[i], image.Info.Sectors, _testFiles[i]); Assert.AreEqual(_sectorSize[i], image.Info.SectorSize, _testFiles[i]); IPartition parts = new MBR(); Assert.AreEqual(true, parts.GetInformation(image, out List <Partition> partitions, 0), _testFiles[i]); IFilesystem fs = new ext2FS(); int part = -1; for (int j = 0; j < partitions.Count; j++) { if (partitions[j].Type == "0x83") { part = j; break; } } Assert.AreNotEqual(-1, part, $"Partition not found on {_testFiles[i]}"); Assert.AreEqual(true, fs.Identify(image, partitions[part]), _testFiles[i]); fs.GetInformation(image, partitions[part], out _, null); Assert.AreEqual(_clusters[i], fs.XmlFsType.Clusters, _testFiles[i]); Assert.AreEqual(_clusterSize[i], fs.XmlFsType.ClusterSize, _testFiles[i]); Assert.AreEqual(_extversion[i], fs.XmlFsType.Type, _testFiles[i]); Assert.AreEqual(_volumeName[i], fs.XmlFsType.VolumeName, _testFiles[i]); Assert.AreEqual(_volumeSerial[i], fs.XmlFsType.VolumeSerial, _testFiles[i]); } }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); imageHeader = new A2ImgHeader(); byte[] header = new byte[64]; stream.Read(header, 0, 64); byte[] magic = new byte[4]; byte[] creator = new byte[4]; Array.Copy(header, 0, magic, 0, 4); Array.Copy(header, 4, creator, 0, 4); imageHeader = Marshal.SpanToStructureLittleEndian <A2ImgHeader>(header); if (imageHeader.DataSize == 0x00800C00) { imageHeader.DataSize = 0x000C8000; AaruConsole.DebugWriteLine("2MG plugin", "Detected incorrect endian on data size field, correcting."); } AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.magic = \"{0}\"", Encoding.ASCII.GetString(magic)); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.creator = \"{0}\"", Encoding.ASCII.GetString(creator)); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.headerSize = {0}", imageHeader.HeaderSize); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.version = {0}", imageHeader.Version); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.imageFormat = {0}", imageHeader.ImageFormat); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.flags = 0x{0:X8}", imageHeader.Flags); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.blocks = {0}", imageHeader.Blocks); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.dataOffset = 0x{0:X8}", imageHeader.DataOffset); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.dataSize = {0}", imageHeader.DataSize); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.commentOffset = 0x{0:X8}", imageHeader.CommentOffset); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.commentSize = {0}", imageHeader.CommentSize); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.creatorSpecificOffset = 0x{0:X8}", imageHeader.CreatorSpecificOffset); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.creatorSpecificSize = {0}", imageHeader.CreatorSpecificSize); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.reserved1 = 0x{0:X8}", imageHeader.Reserved1); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.reserved2 = 0x{0:X8}", imageHeader.Reserved2); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.reserved3 = 0x{0:X8}", imageHeader.Reserved3); AaruConsole.DebugWriteLine("2MG plugin", "ImageHeader.reserved4 = 0x{0:X8}", imageHeader.Reserved4); if (imageHeader.DataSize == 0 && imageHeader.Blocks == 0 && imageHeader.ImageFormat != SectorOrder.ProDos) { return(false); } byte[] tmp; int[] offsets; switch (imageHeader.ImageFormat) { case SectorOrder.Nibbles: tmp = new byte[imageHeader.DataSize]; stream.Seek(imageHeader.DataOffset, SeekOrigin.Begin); stream.Read(tmp, 0, tmp.Length); var nibPlugin = new AppleNib(); var noFilter = new ZZZNoFilter(); noFilter.Open(tmp); nibPlugin.Open(noFilter); decodedImage = nibPlugin.ReadSectors(0, (uint)nibPlugin.Info.Sectors); imageInfo.Sectors = nibPlugin.Info.Sectors; imageInfo.SectorSize = nibPlugin.Info.SectorSize; break; case SectorOrder.Dos when imageHeader.DataSize == 143360: case SectorOrder.ProDos when imageHeader.DataSize == 143360: stream.Seek(imageHeader.DataOffset, SeekOrigin.Begin); tmp = new byte[imageHeader.DataSize]; stream.Read(tmp, 0, tmp.Length); bool isDos = tmp[0x11001] == 17 && tmp[0x11002] < 16 && tmp[0x11027] <= 122 && tmp[0x11034] == 35 && tmp[0x11035] == 16 && tmp[0x11036] == 0 && tmp[0x11037] == 1; decodedImage = new byte[imageHeader.DataSize]; offsets = imageHeader.ImageFormat == SectorOrder.Dos ? isDos ? deinterleave : interleave : isDos ? interleave : deinterleave; for (int t = 0; t < 35; t++) { for (int s = 0; s < 16; s++) { Array.Copy(tmp, (t * 16 * 256) + (s * 256), decodedImage, (t * 16 * 256) + (offsets[s] * 256), 256); } } imageInfo.Sectors = 560; imageInfo.SectorSize = 256; break; case SectorOrder.Dos when imageHeader.DataSize == 819200: stream.Seek(imageHeader.DataOffset, SeekOrigin.Begin); tmp = new byte[imageHeader.DataSize]; stream.Read(tmp, 0, tmp.Length); decodedImage = new byte[imageHeader.DataSize]; offsets = interleave; for (int t = 0; t < 200; t++) { for (int s = 0; s < 16; s++) { Array.Copy(tmp, (t * 16 * 256) + (s * 256), decodedImage, (t * 16 * 256) + (offsets[s] * 256), 256); } } imageInfo.Sectors = 1600; imageInfo.SectorSize = 512; break; default: decodedImage = null; imageInfo.SectorSize = 512; imageInfo.Sectors = imageHeader.DataSize / 512; break; } imageInfo.ImageSize = imageHeader.DataSize; switch (imageHeader.Creator) { case CREATOR_ASIMOV: imageInfo.Application = "ASIMOV2"; break; case CREATOR_BERNIE: imageInfo.Application = "Bernie ][ the Rescue"; break; case CREATOR_CATAKIG: imageInfo.Application = "Catakig"; break; case CREATOR_SHEPPY: imageInfo.Application = "Sheppy's ImageMaker"; break; case CREATOR_SWEET: imageInfo.Application = "Sweet16"; break; case CREATOR_XGS: imageInfo.Application = "XGS"; break; case CREATOR_CIDER: imageInfo.Application = "CiderPress"; break; case CREATOR_DIC: imageInfo.Application = "DiscImageChef"; break; case CREATOR_AARU: imageInfo.Application = "Aaru"; break; default: imageInfo.Application = $"Unknown creator code \"{Encoding.ASCII.GetString(creator)}\""; break; } imageInfo.Version = imageHeader.Version.ToString(); if (imageHeader.CommentOffset != 0 && imageHeader.CommentSize != 0) { stream.Seek(imageHeader.CommentOffset, SeekOrigin.Begin); byte[] comments = new byte[imageHeader.CommentSize]; stream.Read(comments, 0, (int)imageHeader.CommentSize); imageInfo.Comments = Encoding.ASCII.GetString(comments); } imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.MediaType = GetMediaType(); a2MgImageFilter = imageFilter; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; AaruConsole.VerboseWriteLine("2MG image contains a disk of type {0}", imageInfo.MediaType); if (!string.IsNullOrEmpty(imageInfo.Comments)) { AaruConsole.VerboseWriteLine("2MG comments: {0}", imageInfo.Comments); } switch (imageInfo.MediaType) { case MediaType.Apple32SS: imageInfo.Cylinders = 35; imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 13; break; case MediaType.Apple32DS: imageInfo.Cylinders = 35; imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 13; break; case MediaType.Apple33SS: imageInfo.Cylinders = 35; imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 16; break; case MediaType.Apple33DS: imageInfo.Cylinders = 35; imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 16; break; case MediaType.AppleSonySS: imageInfo.Cylinders = 80; imageInfo.Heads = 1; // Variable sectors per track, this suffices imageInfo.SectorsPerTrack = 10; break; case MediaType.AppleSonyDS: imageInfo.Cylinders = 80; imageInfo.Heads = 2; // Variable sectors per track, this suffices imageInfo.SectorsPerTrack = 10; break; case MediaType.DOS_35_HD: imageInfo.Cylinders = 80; imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 18; break; } return(true); }
public void Test() { Environment.CurrentDirectory = Path.Combine(Consts.TEST_FILES_ROOT, "Media image formats", "CDRWin"); for (int i = 0; i < _testFiles.Length; i++) { IFilter filter = new ZZZNoFilter(); filter.Open(_testFiles[i]); IOpticalMediaImage image = new CdrWin(); Assert.AreEqual(true, image.Open(filter), _testFiles[i]); Assert.AreEqual(_sectors[i], image.Info.Sectors, _testFiles[i]); Assert.AreEqual(_mediaTypes[i], image.Info.MediaType, _testFiles[i]); Assert.AreEqual(_tracks[i], image.Tracks.Count, _testFiles[i]); // How many sectors to read at once const uint sectorsToRead = 256; int trackNo = 0; foreach (Track currentTrack in image.Tracks) { Assert.AreEqual(_trackSessions[i][trackNo], currentTrack.TrackSession, _testFiles[i]); Assert.AreEqual(_trackStarts[i][trackNo], currentTrack.TrackStartSector, _testFiles[i]); Assert.AreEqual(_trackEnds[i][trackNo], currentTrack.TrackEndSector, _testFiles[i]); Assert.AreEqual(_trackPregaps[i][trackNo], currentTrack.TrackPregap, _testFiles[i]); if (image.Info.ReadableSectorTags.Contains(SectorTagType.CdTrackFlags)) { Assert.AreEqual(_trackFlags[i][trackNo], image.ReadSectorTag(currentTrack.TrackSequence, SectorTagType.CdTrackFlags)[0], _testFiles[i]); } trackNo++; } foreach (bool @long in new[] { false, true }) { var ctx = new Md5Context(); foreach (Track currentTrack in image.Tracks) { ulong sectors = (currentTrack.TrackEndSector - currentTrack.TrackStartSector) + 1; ulong doneSectors = 0; while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= sectorsToRead) { sector = @long ? image.ReadSectorsLong(doneSectors, sectorsToRead, currentTrack.TrackSequence) : image.ReadSectors(doneSectors, sectorsToRead, currentTrack.TrackSequence); doneSectors += sectorsToRead; } else { sector = @long ? image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence) : image.ReadSectors(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence); doneSectors += sectors - doneSectors; } ctx.Update(sector); } } Assert.AreEqual(@long ? _longMd5S[i] : _md5S[i], ctx.End(), _testFiles[i]); } if (image.Info.ReadableSectorTags.Contains(SectorTagType.CdSectorSubchannel)) { var ctx = new Md5Context(); foreach (Track currentTrack in image.Tracks) { ulong sectors = (currentTrack.TrackEndSector - currentTrack.TrackStartSector) + 1; ulong doneSectors = 0; while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= sectorsToRead) { sector = image.ReadSectorsTag(doneSectors, sectorsToRead, currentTrack.TrackSequence, SectorTagType.CdSectorSubchannel); doneSectors += sectorsToRead; } else { sector = image.ReadSectorsTag(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence, SectorTagType.CdSectorSubchannel); doneSectors += sectors - doneSectors; } ctx.Update(sector); } } Assert.AreEqual(_subchannelMd5S[i], ctx.End(), _testFiles[i]); } } }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if (stream.Length < Marshal.SizeOf <OobBlock>()) { return(false); } byte[] hdr = new byte[Marshal.SizeOf <OobBlock>()]; stream.Read(hdr, 0, Marshal.SizeOf <OobBlock>()); OobBlock header = Marshal.ByteArrayToStructureLittleEndian <OobBlock>(hdr); stream.Seek(-Marshal.SizeOf <OobBlock>(), SeekOrigin.End); hdr = new byte[Marshal.SizeOf <OobBlock>()]; stream.Read(hdr, 0, Marshal.SizeOf <OobBlock>()); OobBlock footer = Marshal.ByteArrayToStructureLittleEndian <OobBlock>(hdr); if (header.blockId != BlockIds.Oob || header.blockType != OobTypes.KFInfo || footer.blockId != BlockIds.Oob || footer.blockType != OobTypes.EOF || footer.length != 0x0D0D) { return(false); } // TODO: This is supposing NoFilter, shouldn't tracks = new SortedDictionary <byte, IFilter>(); byte step = 1; byte heads = 2; bool topHead = false; string basename = Path.Combine(imageFilter.GetParentFolder(), imageFilter.GetFilename(). Substring(0, imageFilter.GetFilename().Length - 8)); for (byte t = 0; t < 166; t += step) { int cylinder = t / heads; int head = topHead ? 1 : t % heads; string trackfile = Directory.Exists(basename) ? Path.Combine(basename, $"{cylinder:D2}.{head:D1}.raw") : $"{basename}{cylinder:D2}.{head:D1}.raw"; if (!File.Exists(trackfile)) { if (cylinder == 0) { if (head == 0) { AaruConsole.DebugWriteLine("KryoFlux plugin", "Cannot find cyl 0 hd 0, supposing only top head was dumped"); topHead = true; heads = 1; continue; } AaruConsole.DebugWriteLine("KryoFlux plugin", "Cannot find cyl 0 hd 1, supposing only bottom head was dumped"); heads = 1; continue; } else if (cylinder == 1) { AaruConsole.DebugWriteLine("KryoFlux plugin", "Cannot find cyl 1, supposing double stepping"); step = 2; continue; } else { AaruConsole.DebugWriteLine("KryoFlux plugin", "Arrived end of disk at cylinder {0}", cylinder); break; } } var trackFilter = new ZZZNoFilter(); trackFilter.Open(trackfile); if (!trackFilter.IsOpened()) { throw new IOException("Could not open KryoFlux track file."); } imageInfo.CreationTime = DateTime.MaxValue; imageInfo.LastModificationTime = DateTime.MinValue; Stream trackStream = trackFilter.GetDataForkStream(); while (trackStream.Position < trackStream.Length) { byte blockId = (byte)trackStream.ReadByte(); switch (blockId) { case (byte)BlockIds.Oob: { trackStream.Position--; byte[] oob = new byte[Marshal.SizeOf <OobBlock>()]; trackStream.Read(oob, 0, Marshal.SizeOf <OobBlock>()); OobBlock oobBlk = Marshal.ByteArrayToStructureLittleEndian <OobBlock>(oob); if (oobBlk.blockType == OobTypes.EOF) { trackStream.Position = trackStream.Length; break; } if (oobBlk.blockType != OobTypes.KFInfo) { trackStream.Position += oobBlk.length; break; } byte[] kfinfo = new byte[oobBlk.length]; trackStream.Read(kfinfo, 0, oobBlk.length); string kfinfoStr = StringHandlers.CToString(kfinfo); string[] lines = kfinfoStr.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); DateTime blockDate = DateTime.Now; DateTime blockTime = DateTime.Now; bool foundDate = false; foreach (string[] kvp in lines.Select(line => line.Split('=')).Where(kvp => kvp.Length == 2)) { kvp[0] = kvp[0].Trim(); kvp[1] = kvp[1].Trim(); AaruConsole.DebugWriteLine("KryoFlux plugin", "\"{0}\" = \"{1}\"", kvp[0], kvp[1]); switch (kvp[0]) { case _hostDate: if (DateTime.TryParseExact(kvp[1], "yyyy.MM.dd", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out blockDate)) { foundDate = true; } break; case _hostTime: DateTime.TryParseExact(kvp[1], "HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out blockTime); break; case _kfName: imageInfo.Application = kvp[1]; break; case _kfVersion: imageInfo.ApplicationVersion = kvp[1]; break; } } if (foundDate) { var blockTimestamp = new DateTime(blockDate.Year, blockDate.Month, blockDate.Day, blockTime.Hour, blockTime.Minute, blockTime.Second); AaruConsole.DebugWriteLine("KryoFlux plugin", "Found timestamp: {0}", blockTimestamp); if (blockTimestamp < Info.CreationTime) { imageInfo.CreationTime = blockTimestamp; } if (blockTimestamp > Info.LastModificationTime) { imageInfo.LastModificationTime = blockTimestamp; } } break; } case (byte)BlockIds.Flux2: case (byte)BlockIds.Flux2_1: case (byte)BlockIds.Flux2_2: case (byte)BlockIds.Flux2_3: case (byte)BlockIds.Flux2_4: case (byte)BlockIds.Flux2_5: case (byte)BlockIds.Flux2_6: case (byte)BlockIds.Flux2_7: case (byte)BlockIds.Nop2: trackStream.Position++; continue; case (byte)BlockIds.Nop3: case (byte)BlockIds.Flux3: trackStream.Position += 2; continue; default: continue; } } tracks.Add(t, trackFilter); } imageInfo.Heads = heads; imageInfo.Cylinders = (uint)(tracks.Count / heads); throw new NotImplementedException("Flux decoding is not yet implemented."); }
public void Hashes() { // How many sectors to read at once const uint sectorsToRead = 256; Environment.CurrentDirectory = Path.Combine(Consts.TEST_FILES_ROOT, "Media image formats", "UltraISO", "Alcohol"); Assert.Multiple(() => { for (int i = 0; i < _testFiles.Length; i++) { var filter = new ZZZNoFilter(); filter.Open(_testFiles[i]); var image = new DiscImages.Alcohol120(); bool opened = image.Open(filter); Assert.AreEqual(true, opened, $"Open: {_testFiles[i]}"); Md5Context ctx; foreach (bool @long in new[] { false, true }) { ctx = new Md5Context(); foreach (Track currentTrack in image.Tracks) { ulong sectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1; ulong doneSectors = 0; while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= sectorsToRead) { sector = @long ? image.ReadSectorsLong(doneSectors, sectorsToRead, currentTrack.TrackSequence) : image.ReadSectors(doneSectors, sectorsToRead, currentTrack.TrackSequence); doneSectors += sectorsToRead; } else { sector = @long ? image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence) : image.ReadSectors(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence); doneSectors += sectors - doneSectors; } ctx.Update(sector); } } Assert.AreEqual(@long ? _longMd5S[i] : _md5S[i], ctx.End(), $"{(@long ? "Long hash" : "Hash")}: {_testFiles[i]}"); } if (!image.Info.ReadableSectorTags.Contains(SectorTagType.CdSectorSubchannel)) { continue; } ctx = new Md5Context(); foreach (Track currentTrack in image.Tracks) { ulong sectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1; ulong doneSectors = 0; while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= sectorsToRead) { sector = image.ReadSectorsTag(doneSectors, sectorsToRead, currentTrack.TrackSequence, SectorTagType.CdSectorSubchannel); doneSectors += sectorsToRead; } else { sector = image.ReadSectorsTag(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence, SectorTagType.CdSectorSubchannel); doneSectors += sectors - doneSectors; } ctx.Update(sector); } } Assert.AreEqual(_subchannelMd5S[i], ctx.End(), $"Subchannel hash: {_testFiles[i]}"); } }); }