private static byte[] extractFileFromPartition(IOpticalMediaImage opticalImage, Partition partition, string fileName) { var iso = new ISO9660(); try { //string information; //iso.GetInformation(opticalImage, partition, out information, Encoding.ASCII); var dict = new Dictionary <string, string>(); iso.Mount(opticalImage, partition, Encoding.ASCII, dict, "normal"); //System.Collections.Generic.List<string> strlist = null; //iso.ReadDir("/", out strlist); if (iso.Stat(fileName, out var stat) == Aaru.CommonTypes.Structs.Errno.NoError && stat.Length > 0) { //file exists var buff = new byte[stat.Length]; iso.Read(fileName, 0, stat.Length, ref buff); return(buff); } } finally { iso.Unmount(); } return(null); }
public frmImageEntropy(IMediaImage inputFormat) { this.inputFormat = inputFormat; XamlReader.Load(this); IOpticalMediaImage inputOptical = inputFormat as IOpticalMediaImage; if (inputOptical?.Tracks != null && inputOptical?.Tracks.Count > 0) { chkSeparatedTracks.Visible = true; chkWholeDisc.Visible = true; } else { chkSeparatedTracks.Checked = false; chkWholeDisc.Checked = true; } }
/// <summary>Creates a metadata sidecar for an optical disc (e.g. CD, DVD, GD, BD, XGD, GOD)</summary> /// <param name="image">Image</param> /// <param name="filterId">Filter uuid</param> /// <param name="imagePath">Image path</param> /// <param name="fi">Image file information</param> /// <param name="plugins">Image plugins</param> /// <param name="imgChecksums">List of image checksums</param> /// <param name="sidecar">Metadata sidecar</param> void OpticalDisc(IOpticalMediaImage image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins, List <ChecksumType> imgChecksums, ref CICMMetadataType sidecar, Encoding encoding) { if (aborted) { return; } sidecar.OpticalDisc = new[] { new OpticalDiscType { Checksums = imgChecksums.ToArray(), Image = new ImageType { format = image.Format, offset = 0, offsetSpecified = true, Value = Path.GetFileName(imagePath) }, Size = (ulong)fi.Length, Sequence = new SequenceType { MediaTitle = image.Info.MediaTitle } } }; if (image.Info.MediaSequence != 0 && image.Info.LastMediaSequence != 0) { sidecar.OpticalDisc[0].Sequence.MediaSequence = (uint)image.Info.MediaSequence; sidecar.OpticalDisc[0].Sequence.TotalMedia = (uint)image.Info.LastMediaSequence; } else { sidecar.OpticalDisc[0].Sequence.MediaSequence = 1; sidecar.OpticalDisc[0].Sequence.TotalMedia = 1; } MediaType dskType = image.Info.MediaType; UpdateStatus("Hashing media tags..."); foreach (MediaTagType tagType in image.Info.ReadableMediaTags) { if (aborted) { return; } switch (tagType) { case MediaTagType.CD_ATIP: sidecar.OpticalDisc[0].ATIP = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_ATIP)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.CD_ATIP).Length }; ATIP.CDATIP?atip = ATIP.Decode(image.ReadDiskTag(MediaTagType.CD_ATIP)); if (atip.HasValue) { if (atip.Value.DDCD) { dskType = atip.Value.DiscType ? MediaType.DDCDRW : MediaType.DDCDR; } else { dskType = atip.Value.DiscType ? MediaType.CDRW : MediaType.CDR; } } break; case MediaTagType.DVD_BCA: sidecar.OpticalDisc[0].BCA = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_BCA)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.DVD_BCA).Length }; break; case MediaTagType.BD_BCA: sidecar.OpticalDisc[0].BCA = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.BD_BCA)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.BD_BCA).Length }; break; case MediaTagType.DVD_CMI: sidecar.OpticalDisc[0].CMI = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_CMI)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.DVD_CMI).Length }; CSS_CPRM.LeadInCopyright?cmi = CSS_CPRM.DecodeLeadInCopyright(image.ReadDiskTag(MediaTagType.DVD_CMI)); if (cmi.HasValue) { switch (cmi.Value.CopyrightType) { case CopyrightType.AACS: sidecar.OpticalDisc[0].CopyProtection = "AACS"; break; case CopyrightType.CSS: sidecar.OpticalDisc[0].CopyProtection = "CSS"; break; case CopyrightType.CPRM: sidecar.OpticalDisc[0].CopyProtection = "CPRM"; break; } } break; case MediaTagType.DVD_DMI: sidecar.OpticalDisc[0].DMI = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_DMI)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.DVD_DMI).Length }; if (DMI.IsXbox(image.ReadDiskTag(MediaTagType.DVD_DMI))) { dskType = MediaType.XGD; sidecar.OpticalDisc[0].Dimensions = new DimensionsType { Diameter = 120, Thickness = 1.2 }; } else if (DMI.IsXbox360(image.ReadDiskTag(MediaTagType.DVD_DMI))) { dskType = MediaType.XGD2; sidecar.OpticalDisc[0].Dimensions = new DimensionsType { Diameter = 120, Thickness = 1.2 }; } break; case MediaTagType.DVD_PFI: sidecar.OpticalDisc[0].PFI = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_PFI)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.DVD_PFI).Length }; PFI.PhysicalFormatInformation?pfi = PFI.Decode(image.ReadDiskTag(MediaTagType.DVD_PFI)); if (pfi.HasValue) { if (dskType != MediaType.XGD && dskType != MediaType.XGD2 && dskType != MediaType.XGD3 && dskType != MediaType.PS2DVD && dskType != MediaType.PS3DVD && dskType != MediaType.Nuon) { switch (pfi.Value.DiskCategory) { case DiskCategory.DVDPR: dskType = MediaType.DVDPR; break; case DiskCategory.DVDPRDL: dskType = MediaType.DVDPRDL; break; case DiskCategory.DVDPRW: dskType = MediaType.DVDPRW; break; case DiskCategory.DVDPRWDL: dskType = MediaType.DVDPRWDL; break; case DiskCategory.DVDR: dskType = MediaType.DVDR; break; case DiskCategory.DVDRAM: dskType = MediaType.DVDRAM; break; case DiskCategory.DVDROM: dskType = MediaType.DVDROM; break; case DiskCategory.DVDRW: dskType = MediaType.DVDRW; break; case DiskCategory.HDDVDR: dskType = MediaType.HDDVDR; break; case DiskCategory.HDDVDRAM: dskType = MediaType.HDDVDRAM; break; case DiskCategory.HDDVDROM: dskType = MediaType.HDDVDROM; break; case DiskCategory.HDDVDRW: dskType = MediaType.HDDVDRW; break; case DiskCategory.Nintendo: dskType = MediaType.GOD; break; case DiskCategory.UMD: dskType = MediaType.UMD; break; } if (dskType == MediaType.DVDR && pfi.Value.PartVersion == 6) { dskType = MediaType.DVDRDL; } if (dskType == MediaType.DVDRW && pfi.Value.PartVersion == 3) { dskType = MediaType.DVDRWDL; } if (dskType == MediaType.GOD && pfi.Value.DiscSize == DVDSize.OneTwenty) { dskType = MediaType.WOD; } sidecar.OpticalDisc[0].Dimensions = new DimensionsType(); if (dskType == MediaType.UMD) { sidecar.OpticalDisc[0].Dimensions.Height = 64; sidecar.OpticalDisc[0].Dimensions.HeightSpecified = true; sidecar.OpticalDisc[0].Dimensions.Width = 63; sidecar.OpticalDisc[0].Dimensions.WidthSpecified = true; sidecar.OpticalDisc[0].Dimensions.Thickness = 4; } else { switch (pfi.Value.DiscSize) { case DVDSize.Eighty: sidecar.OpticalDisc[0].Dimensions.Diameter = 80; sidecar.OpticalDisc[0].Dimensions.DiameterSpecified = true; sidecar.OpticalDisc[0].Dimensions.Thickness = 1.2; break; case DVDSize.OneTwenty: sidecar.OpticalDisc[0].Dimensions.Diameter = 120; sidecar.OpticalDisc[0].Dimensions.DiameterSpecified = true; sidecar.OpticalDisc[0].Dimensions.Thickness = 1.2; break; } } } } break; case MediaTagType.CD_PMA: sidecar.OpticalDisc[0].PMA = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_PMA)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.CD_PMA).Length }; break; case MediaTagType.CD_FullTOC: sidecar.OpticalDisc[0].TOC = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_FullTOC)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.CD_FullTOC).Length }; break; case MediaTagType.CD_FirstTrackPregap: sidecar.OpticalDisc[0].FirstTrackPregrap = new[] { new BorderType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_FirstTrackPregap)). ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.CD_FirstTrackPregap).Length } }; break; case MediaTagType.CD_LeadIn: sidecar.OpticalDisc[0].LeadIn = new[] { new BorderType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_LeadIn)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.CD_LeadIn).Length } }; break; case MediaTagType.Xbox_SecuritySector: if (sidecar.OpticalDisc[0].Xbox == null) { sidecar.OpticalDisc[0].Xbox = new XboxType(); } sidecar.OpticalDisc[0].Xbox.SecuritySectors = new[] { new XboxSecuritySectorsType { RequestNumber = 0, RequestVersion = 1, SecuritySectors = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum. GetChecksums(image.ReadDiskTag(MediaTagType.Xbox_SecuritySector)). ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.Xbox_SecuritySector).Length } } }; break; case MediaTagType.Xbox_PFI: if (sidecar.OpticalDisc[0].Xbox == null) { sidecar.OpticalDisc[0].Xbox = new XboxType(); } sidecar.OpticalDisc[0].Xbox.PFI = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.Xbox_PFI)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.Xbox_PFI).Length }; break; case MediaTagType.Xbox_DMI: if (sidecar.OpticalDisc[0].Xbox == null) { sidecar.OpticalDisc[0].Xbox = new XboxType(); } sidecar.OpticalDisc[0].Xbox.DMI = new DumpType { Image = Path.GetFileName(imagePath), Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.Xbox_DMI)).ToArray(), Size = (ulong)image.ReadDiskTag(MediaTagType.Xbox_DMI).Length }; break; } } try { List <Session> sessions = image.Sessions; sidecar.OpticalDisc[0].Sessions = (uint)(sessions?.Count ?? 1); } catch { sidecar.OpticalDisc[0].Sessions = 1; } List <Track> tracks = image.Tracks; List <TrackType> trksLst = null; if (tracks != null) { sidecar.OpticalDisc[0].Tracks = new uint[1]; sidecar.OpticalDisc[0].Tracks[0] = (uint)tracks.Count; trksLst = new List <TrackType>(); } if (sidecar.OpticalDisc[0].Dimensions == null && image.Info.MediaType != MediaType.Unknown) { sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(image.Info.MediaType); } if (aborted) { return; } InitProgress(); UpdateStatus("Checking filesystems"); List <Partition> partitions = Partitions.GetAll(image); Partitions.AddSchemesToStats(partitions); UpdateStatus("Hashing tracks..."); foreach (Track trk in tracks) { if (aborted) { EndProgress(); return; } var xmlTrk = new TrackType(); switch (trk.TrackType) { case CommonTypes.Enums.TrackType.Audio: xmlTrk.TrackType1 = TrackTypeTrackType.audio; break; case CommonTypes.Enums.TrackType.CdMode2Form2: xmlTrk.TrackType1 = TrackTypeTrackType.m2f2; break; case CommonTypes.Enums.TrackType.CdMode2Formless: xmlTrk.TrackType1 = TrackTypeTrackType.mode2; break; case CommonTypes.Enums.TrackType.CdMode2Form1: xmlTrk.TrackType1 = TrackTypeTrackType.m2f1; break; case CommonTypes.Enums.TrackType.CdMode1: xmlTrk.TrackType1 = TrackTypeTrackType.mode1; break; case CommonTypes.Enums.TrackType.Data: switch (sidecar.OpticalDisc[0].DiscType) { case "BD": xmlTrk.TrackType1 = TrackTypeTrackType.bluray; break; case "DDCD": xmlTrk.TrackType1 = TrackTypeTrackType.ddcd; break; case "DVD": xmlTrk.TrackType1 = TrackTypeTrackType.dvd; break; case "HD DVD": xmlTrk.TrackType1 = TrackTypeTrackType.hddvd; break; default: xmlTrk.TrackType1 = TrackTypeTrackType.mode1; break; } break; } xmlTrk.Sequence = new TrackSequenceType { Session = trk.TrackSession, TrackNumber = trk.TrackSequence }; xmlTrk.StartSector = trk.TrackStartSector; xmlTrk.EndSector = trk.TrackEndSector; if (trk.Indexes != null && trk.Indexes.ContainsKey(0)) { if (trk.Indexes.TryGetValue(0, out ulong idx0)) { xmlTrk.StartSector = idx0; } } switch (sidecar.OpticalDisc[0].DiscType) { case "CD": case "GD": xmlTrk.StartMSF = LbaToMsf((long)xmlTrk.StartSector); xmlTrk.EndMSF = LbaToMsf((long)xmlTrk.EndSector); break; case "DDCD": xmlTrk.StartMSF = DdcdLbaToMsf((long)xmlTrk.StartSector); xmlTrk.EndMSF = DdcdLbaToMsf((long)xmlTrk.EndSector); break; } xmlTrk.Image = new ImageType { Value = Path.GetFileName(trk.TrackFile), format = trk.TrackFileType }; if (trk.TrackFileOffset > 0) { xmlTrk.Image.offset = trk.TrackFileOffset; xmlTrk.Image.offsetSpecified = true; } xmlTrk.Size = ((xmlTrk.EndSector - xmlTrk.StartSector) + 1) * (ulong)trk.TrackRawBytesPerSector; xmlTrk.BytesPerSector = (uint)trk.TrackBytesPerSector; uint sectorsToRead = 512; ulong sectors = (xmlTrk.EndSector - xmlTrk.StartSector) + 1; ulong doneSectors = 0; // If there is only one track, and it's the same as the image file (e.g. ".iso" files), don't re-checksum. if (image.Id == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") && // Only if filter is none... (filterId == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") || // ...or AppleDouble filterId == new Guid("1b2165ee-c9df-4b21-bbbb-9e5892b2df4d"))) { xmlTrk.Checksums = sidecar.OpticalDisc[0].Checksums; } else { UpdateProgress("Track {0} of {1}", trk.TrackSequence, tracks.Count); // For fast debugging, skip checksum //goto skipChecksum; var trkChkWorker = new Checksum(); InitProgress2(); while (doneSectors < sectors) { if (aborted) { EndProgress(); EndProgress2(); return; } byte[] sector; if (sectors - doneSectors >= sectorsToRead) { sector = image.ReadSectorsLong(doneSectors, sectorsToRead, xmlTrk.Sequence.TrackNumber); UpdateProgress2("Hashings sector {0} of {1}", (long)doneSectors, (long)((trk.TrackEndSector - trk.TrackStartSector) + 1)); doneSectors += sectorsToRead; } else { sector = image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), xmlTrk.Sequence.TrackNumber); UpdateProgress2("Hashings sector {0} of {1}", (long)doneSectors, (long)((trk.TrackEndSector - trk.TrackStartSector) + 1)); doneSectors += sectors - doneSectors; } trkChkWorker.Update(sector); } List <ChecksumType> trkChecksums = trkChkWorker.End(); xmlTrk.Checksums = trkChecksums.ToArray(); EndProgress2(); } if (trk.TrackSubchannelType != TrackSubchannelType.None) { xmlTrk.SubChannel = new SubChannelType { Image = new ImageType { Value = trk.TrackSubchannelFile }, // TODO: Packed subchannel has different size? Size = ((xmlTrk.EndSector - xmlTrk.StartSector) + 1) * 96 }; switch (trk.TrackSubchannelType) { case TrackSubchannelType.Packed: case TrackSubchannelType.PackedInterleaved: xmlTrk.SubChannel.Image.format = "rw"; break; case TrackSubchannelType.Raw: case TrackSubchannelType.RawInterleaved: xmlTrk.SubChannel.Image.format = "rw_raw"; break; case TrackSubchannelType.Q16: case TrackSubchannelType.Q16Interleaved: xmlTrk.SubChannel.Image.format = "q16"; break; } if (trk.TrackFileOffset > 0) { xmlTrk.SubChannel.Image.offset = trk.TrackSubchannelOffset; xmlTrk.SubChannel.Image.offsetSpecified = true; } var subChkWorker = new Checksum(); sectors = (xmlTrk.EndSector - xmlTrk.StartSector) + 1; doneSectors = 0; InitProgress2(); while (doneSectors < sectors) { if (aborted) { EndProgress(); EndProgress2(); return; } byte[] sector; if (sectors - doneSectors >= sectorsToRead) { sector = image.ReadSectorsTag(doneSectors, sectorsToRead, xmlTrk.Sequence.TrackNumber, SectorTagType.CdSectorSubchannel); UpdateProgress2("Hashings subchannel sector {0} of {1}", (long)doneSectors, (long)((trk.TrackEndSector - trk.TrackStartSector) + 1)); doneSectors += sectorsToRead; } else { sector = image.ReadSectorsTag(doneSectors, (uint)(sectors - doneSectors), xmlTrk.Sequence.TrackNumber, SectorTagType.CdSectorSubchannel); UpdateProgress2("Hashings subchannel sector {0} of {1}", (long)doneSectors, (long)((trk.TrackEndSector - trk.TrackStartSector) + 1)); doneSectors += sectors - doneSectors; } subChkWorker.Update(sector); } List <ChecksumType> subChecksums = subChkWorker.End(); xmlTrk.SubChannel.Checksums = subChecksums.ToArray(); EndProgress2(); } // For fast debugging, skip checksum //skipChecksum: List <Partition> trkPartitions = partitions. Where(p => p.Start >= trk.TrackStartSector && p.End <= trk.TrackEndSector).ToList(); xmlTrk.FileSystemInformation = new PartitionType[1]; if (trkPartitions.Count > 0) { xmlTrk.FileSystemInformation = new PartitionType[trkPartitions.Count]; for (int i = 0; i < trkPartitions.Count; i++) { xmlTrk.FileSystemInformation[i] = new PartitionType { Description = trkPartitions[i].Description, EndSector = trkPartitions[i].End, Name = trkPartitions[i].Name, Sequence = (uint)trkPartitions[i].Sequence, StartSector = trkPartitions[i].Start, Type = trkPartitions[i].Type }; List <FileSystemType> lstFs = new List <FileSystemType>(); foreach (IFilesystem plugin in plugins.PluginsList.Values) { try { if (aborted) { EndProgress(); return; } if (!plugin.Identify(image, trkPartitions[i])) { continue; } plugin.GetInformation(image, trkPartitions[i], out _, encoding); lstFs.Add(plugin.XmlFsType); Statistics.AddFilesystem(plugin.XmlFsType.Type); switch (plugin.XmlFsType.Type) { case "Opera": dskType = MediaType.ThreeDO; break; case "PC Engine filesystem": dskType = MediaType.SuperCDROM2; break; case "Nintendo Wii filesystem": dskType = MediaType.WOD; break; case "Nintendo Gamecube filesystem": dskType = MediaType.GOD; break; } } }
public void Test() { // How many sectors to read at once const uint sectorsToRead = 256; Environment.CurrentDirectory = Path.Combine(Consts.TEST_FILES_ROOT, "Media image formats", "MagicISO", "Cuesheet"); IFilter[] filters = new IFilter[_testFiles.Length]; for (int i = 0; i < _testFiles.Length; i++) { filters[i] = new ZZZNoFilter(); filters[i].Open(_testFiles[i]); } IOpticalMediaImage[] images = new IOpticalMediaImage[_testFiles.Length]; for (int i = 0; i < _testFiles.Length; i++) { images[i] = new CdrWin(); Assert.AreEqual(true, images[i].Open(filters[i]), $"Open: {_testFiles[i]}"); } for (int i = 0; i < _testFiles.Length; i++) { Assert.AreEqual(_sectors[i], images[i].Info.Sectors, $"Sectors: {_testFiles[i]}"); } for (int i = 0; i < _testFiles.Length; i++) { Assert.AreEqual(_mediaTypes[i], images[i].Info.MediaType, $"Media type: {_testFiles[i]}"); } for (int i = 0; i < _testFiles.Length; i++) { Assert.AreEqual(_tracks[i], images[i].Tracks.Count, $"Tracks: {_testFiles[i]}"); } for (int i = 0; i < _testFiles.Length; i++) { images[i].Tracks.Select(t => t.TrackSession).Should(). BeEquivalentTo(_trackSessions[i], $"Track session: {_testFiles[i]}"); } for (int i = 0; i < _testFiles.Length; i++) { images[i].Tracks.Select(t => t.TrackStartSector).Should(). BeEquivalentTo(_trackStarts[i], $"Track start: {_testFiles[i]}"); } for (int i = 0; i < _testFiles.Length; i++) { images[i].Tracks.Select(t => t.TrackEndSector).Should(). BeEquivalentTo(_trackEnds[i], $"Track end: {_testFiles[i]}"); } for (int i = 0; i < _testFiles.Length; i++) { images[i].Tracks.Select(t => t.TrackPregap).Should(). BeEquivalentTo(_trackPregaps[i], $"Track pregap: {_testFiles[i]}"); } for (int i = 0; i < _testFiles.Length; i++) { int trackNo = 0; foreach (Track currentTrack in images[i].Tracks) { if (images[i].Info.ReadableSectorTags.Contains(SectorTagType.CdTrackFlags)) { Assert.AreEqual(_trackFlags[i][trackNo], images[i].ReadSectorTag(currentTrack.TrackSequence, SectorTagType.CdTrackFlags) [0], $"Track flags: {_testFiles[i]}, track {currentTrack.TrackSequence}"); } trackNo++; } } foreach (bool @long in new[] { false, true }) { for (int i = 0; i < _testFiles.Length; i++) { var ctx = new Md5Context(); foreach (Track currentTrack in images[i].Tracks) { ulong sectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1; ulong doneSectors = 0; while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= sectorsToRead) { sector = @long ? images[i]. ReadSectorsLong(doneSectors, sectorsToRead, currentTrack.TrackSequence) : images[i]. ReadSectors(doneSectors, sectorsToRead, currentTrack.TrackSequence); doneSectors += sectorsToRead; } else { sector = @long ? images[i].ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence) : images[i].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]}"); } } for (int i = 0; i < _testFiles.Length; i++) { if (images[i].Info.ReadableSectorTags.Contains(SectorTagType.CdSectorSubchannel)) { var ctx = new Md5Context(); foreach (Track currentTrack in images[i].Tracks) { ulong sectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1; ulong doneSectors = 0; while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= sectorsToRead) { sector = images[i].ReadSectorsTag(doneSectors, sectorsToRead, currentTrack.TrackSequence, SectorTagType.CdSectorSubchannel); doneSectors += sectorsToRead; } else { sector = images[i].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]}"); } } }
void DoWork() { IOpticalMediaImage opticalMediaImage = inputFormat as IOpticalMediaImage; bool formatHasTracks = false; if (opticalMediaImage != null) { try { formatHasTracks = opticalMediaImage.Tracks?.Count > 0; } catch { formatHasTracks = false; } } // Setup progress bars Application.Instance.Invoke(() => { stkProgress.Visible = true; prgProgress.MaxValue = 1; prgProgress2.MaxValue = (int)(inputFormat.Info.Sectors / SECTORS_TO_READ); if (formatHasTracks && chkChecksumTracks.Checked == true && opticalMediaImage != null) { prgProgress.MaxValue += opticalMediaImage.Tracks.Count; } else { prgProgress.MaxValue = 2; prgProgress2.Visible = false; lblProgress2.Visible = false; } }); EnableChecksum enabledChecksums = new EnableChecksum(); if (chkAdler32.Checked == true) { enabledChecksums |= EnableChecksum.Adler32; } if (chkCrc16.Checked == true) { enabledChecksums |= EnableChecksum.Crc16; } if (chkCrc32.Checked == true) { enabledChecksums |= EnableChecksum.Crc32; } if (chkCrc64.Checked == true) { enabledChecksums |= EnableChecksum.Crc64; } if (chkMd5.Checked == true) { enabledChecksums |= EnableChecksum.Md5; } if (chkSha1.Checked == true) { enabledChecksums |= EnableChecksum.Sha1; } if (chkSha256.Checked == true) { enabledChecksums |= EnableChecksum.Sha256; } if (chkSha384.Checked == true) { enabledChecksums |= EnableChecksum.Sha384; } if (chkSha512.Checked == true) { enabledChecksums |= EnableChecksum.Sha512; } if (chkSpamsum.Checked == true) { enabledChecksums |= EnableChecksum.SpamSum; } if (chkFletcher16.Checked == true) { enabledChecksums |= EnableChecksum.Fletcher16; } if (chkFletcher32.Checked == true) { enabledChecksums |= EnableChecksum.Fletcher32; } Checksum mediaChecksum = null; TreeGridItemCollection trackHashes = new TreeGridItemCollection(); TreeGridItemCollection mediaHashes = new TreeGridItemCollection(); if (opticalMediaImage != null) { try { Checksum trackChecksum = null; if (chkChecksumMedia.Checked == true) { mediaChecksum = new Checksum(enabledChecksums); } ulong previousTrackEnd = 0; foreach (Track currentTrack in opticalMediaImage.Tracks) { Application.Instance.Invoke(() => { lblProgress.Text = $"Hashing track {currentTrack.TrackSequence} of {opticalMediaImage.Tracks.Count}"; prgProgress.Value++; }); if (currentTrack.TrackStartSector - previousTrackEnd != 0 && chkChecksumMedia.Checked == true) { for (ulong i = previousTrackEnd + 1; i < currentTrack.TrackStartSector; i++) { ulong sector = i; Application.Instance.Invoke(() => { prgProgress2.Value = (int)(sector / SECTORS_TO_READ); lblProgress2.Text = $"Hashing track-less sector {sector}"; }); byte[] hiddenSector = opticalMediaImage.ReadSector(i); mediaChecksum?.Update(hiddenSector); } } DicConsole.DebugWriteLine("Checksum command", "Track {0} starts at sector {1} and ends at sector {2}", currentTrack.TrackSequence, currentTrack.TrackStartSector, currentTrack.TrackEndSector); if (chkChecksumTracks.Checked == true) { trackChecksum = new Checksum(enabledChecksums); } ulong sectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1; ulong doneSectors = 0; while (doneSectors < sectors) { if (cancel) { Application.Instance.Invoke(() => { btnClose.Visible = true; btnStart.Visible = false; btnStop.Visible = false; }); return; } byte[] sector; if (sectors - doneSectors >= SECTORS_TO_READ) { sector = opticalMediaImage.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.TrackSequence); ulong doneSectorsToInvoke = doneSectors; Application.Instance.Invoke(() => { prgProgress2.Value = (int)(doneSectorsToInvoke / SECTORS_TO_READ); lblProgress2.Text = $"Hashings sectors {doneSectorsToInvoke} to {doneSectorsToInvoke + SECTORS_TO_READ} of track {currentTrack.TrackSequence}"; }); doneSectors += SECTORS_TO_READ; } else { sector = opticalMediaImage.ReadSectors(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence); ulong doneSectorsToInvoke = doneSectors; Application.Instance.Invoke(() => { prgProgress2.Value = (int)(doneSectorsToInvoke / SECTORS_TO_READ); lblProgress2.Text = $"Hashings sectors {doneSectorsToInvoke} to {doneSectorsToInvoke + (sectors - doneSectorsToInvoke)} of track {currentTrack.TrackSequence}"; }); doneSectors += sectors - doneSectors; } if (chkChecksumMedia.Checked == true) { mediaChecksum?.Update(sector); } if (chkChecksumTracks.Checked == true) { trackChecksum?.Update(sector); } } if (chkChecksumTracks.Checked == true) { if (trackChecksum != null) { foreach (ChecksumType chk in trackChecksum.End()) { trackHashes.Add(new TreeGridItem { Values = new object[] { currentTrack.TrackSequence, chk.type, chk.Value } }); } } } previousTrackEnd = currentTrack.TrackEndSector; } if (opticalMediaImage.Info.Sectors - previousTrackEnd != 0 && chkChecksumMedia.Checked == true) { for (ulong i = previousTrackEnd + 1; i < opticalMediaImage.Info.Sectors; i++) { ulong sector = i; Application.Instance.Invoke(() => { prgProgress2.Value = (int)(sector / SECTORS_TO_READ); lblProgress2.Text = $"Hashing track-less sector {sector}"; }); byte[] hiddenSector = opticalMediaImage.ReadSector(i); mediaChecksum?.Update(hiddenSector); } } if (chkChecksumMedia.Checked == true) { if (mediaChecksum != null) { foreach (ChecksumType chk in mediaChecksum.End()) { mediaHashes.Add(new TreeGridItem { Values = new object[] { chk.type, chk.Value } }); } } } } catch (Exception ex) { DicConsole.DebugWriteLine("Could not get tracks because {0}", ex.Message); DicConsole.WriteLine("Unable to get separate tracks, not checksumming them"); } } else { Application.Instance.Invoke(() => { stkProgress1.Visible = false; }); mediaChecksum = new Checksum(enabledChecksums); ulong doneSectors = 0; while (doneSectors < inputFormat.Info.Sectors) { if (cancel) { Application.Instance.Invoke(() => { btnClose.Visible = true; btnStart.Visible = false; btnStop.Visible = false; }); return; } byte[] sector; if (inputFormat.Info.Sectors - doneSectors >= SECTORS_TO_READ) { sector = inputFormat.ReadSectors(doneSectors, SECTORS_TO_READ); ulong doneSectorsToInvoke = doneSectors; Application.Instance.Invoke(() => { prgProgress2.Value = (int)(doneSectorsToInvoke / SECTORS_TO_READ); lblProgress2.Text = $"Hashings sectors {doneSectorsToInvoke} to {doneSectorsToInvoke + SECTORS_TO_READ}"; }); doneSectors += SECTORS_TO_READ; } else { sector = inputFormat.ReadSectors(doneSectors, (uint)(inputFormat.Info.Sectors - doneSectors)); ulong doneSectorsToInvoke = doneSectors; Application.Instance.Invoke(() => { prgProgress2.Value = (int)(doneSectorsToInvoke / SECTORS_TO_READ); lblProgress2.Text = $"Hashings sectors {doneSectorsToInvoke} to {doneSectorsToInvoke + (inputFormat.Info.Sectors - doneSectorsToInvoke)}"; }); doneSectors += inputFormat.Info.Sectors - doneSectors; } mediaChecksum.Update(sector); } foreach (ChecksumType chk in mediaChecksum.End()) { mediaHashes.Add(new TreeGridItem { Values = new object[] { chk.type, chk.Value } }); } } if (chkChecksumTracks.Checked == true) { Application.Instance.Invoke(() => { grpTrackChecksums.Text = "Track checksums:"; stkTrackChecksums.Visible = true; treeTrackChecksums.Columns.Add(new GridColumn { HeaderText = "Track", DataCell = new TextBoxCell(0) }); treeTrackChecksums.Columns.Add(new GridColumn { HeaderText = "Algorithm", DataCell = new TextBoxCell(1) }); treeTrackChecksums.Columns.Add(new GridColumn { HeaderText = "Hash", DataCell = new TextBoxCell(2) }); treeTrackChecksums.AllowMultipleSelection = false; treeTrackChecksums.ShowHeader = true; treeTrackChecksums.DataStore = trackHashes; }); } if (chkChecksumMedia.Checked == true) { Application.Instance.Invoke(() => { grpMediaChecksums.Text = "Media checksums:"; stkMediaChecksums.Visible = true; treeMediaChecksums.Columns.Add(new GridColumn { HeaderText = "Algorithm", DataCell = new TextBoxCell(0) }); treeMediaChecksums.Columns.Add(new GridColumn { HeaderText = "Hash", DataCell = new TextBoxCell(1) }); treeMediaChecksums.AllowMultipleSelection = false; treeMediaChecksums.ShowHeader = true; treeMediaChecksums.DataStore = mediaHashes; }); } Statistics.AddCommand("checksum"); Application.Instance.Invoke(() => { stkOptions.Visible = false; stkResults.Visible = true; stkProgress.Visible = false; btnStart.Visible = false; btnStop.Visible = false; btnClose.Visible = true; }); }
private static Task <IpBin> GetIpData(IOpticalMediaImage opticalImage, Partition partition) { return(Task.Run(() => GetIpData(opticalImage.ReadSector(partition.Start)))); }
void DoWork() { bool?correctDisc = null; long totalSectors = 0; long errorSectors = 0; long correctSectors = 0; long unknownSectors = 0; bool formatHasTracks; IOpticalMediaImage inputOptical = inputFormat as IOpticalMediaImage; IVerifiableSectorsImage verifiableSectorsImage = inputFormat as IVerifiableSectorsImage; try { formatHasTracks = inputOptical?.Tracks?.Count > 0; } catch { formatHasTracks = false; } // Setup progress bars Application.Instance.Invoke(() => { stkProgress.Visible = true; prgProgress.MaxValue = 0; if (chkVerifyImage.Checked == true || chkVerifySectors.Checked == true) { prgProgress.MaxValue = 1; } if (formatHasTracks && inputOptical != null) { prgProgress.MaxValue += inputOptical.Tracks.Count; } else { if (chkVerifySectors.Checked == true) { prgProgress.MaxValue = 2; prgProgress2.Visible = false; lblProgress2.Visible = false; } else { prgProgress2.Visible = true; lblProgress2.Visible = true; } } prgProgress.MaxValue++; }); if (chkVerifyImage.Checked == true) { if (!(inputFormat is IVerifiableImage verifiableImage)) { Application.Instance.Invoke(() => { lblImageResult.Visible = true; lblImageResult.Text = "Disc image does not support verification."; }); } else { Application.Instance.Invoke(() => { lblProgress.Text = "Checking media image..."; if (chkVerifySectors.Checked == true) { prgProgress.Value = 1; } else { prgProgress.Indeterminate = true; } prgProgress2.Indeterminate = true; }); DateTime startCheck = DateTime.UtcNow; bool? discCheckStatus = verifiableImage.VerifyMediaImage(); DateTime endCheck = DateTime.UtcNow; TimeSpan checkTime = endCheck - startCheck; Application.Instance.Invoke(() => { lblImageResult.Visible = true; switch (discCheckStatus) { case true: lblImageResult.Text = "Disc image checksums are correct"; break; case false: lblImageResult.Text = "Disc image checksums are incorrect"; break; case null: lblImageResult.Text = "Disc image does not contain checksums"; break; } }); correctDisc = discCheckStatus; DicConsole.VerboseWriteLine("Checking disc image checksums took {0} seconds", checkTime.TotalSeconds); } }