public DvdInfoViewModel(MediaType mediaType, [CanBeNull] byte[] pfi, [CanBeNull] byte[] dmi, [CanBeNull] byte[] cmi, [CanBeNull] byte[] hdCopyrightInformation, [CanBeNull] byte[] bca, [CanBeNull] byte[] aacs, PFI.PhysicalFormatInformation?decodedPfi, Window view) { _dvdPfi = pfi; _dvdDmi = dmi; _dvdCmi = cmi; _hddvdCopyrightInformation = hdCopyrightInformation; _dvdBca = bca; _dvdAacs = aacs; _view = view; SaveDvdPfiCommand = ReactiveCommand.Create(ExecuteSaveDvdPfiCommand); SaveDvdDmiCommand = ReactiveCommand.Create(ExecuteSaveDvdDmiCommand); SaveDvdCmiCommand = ReactiveCommand.Create(ExecuteSaveDvdCmiCommand); SaveHdDvdCmiCommand = ReactiveCommand.Create(ExecuteSaveHdDvdCmiCommand); SaveDvdBcaCommand = ReactiveCommand.Create(ExecuteSaveDvdBcaCommand); SaveDvdAacsCommand = ReactiveCommand.Create(ExecuteSaveDvdAacsCommand); /* TODO: Pass back * switch(mediaType) * { * case MediaType.HDDVDROM: * case MediaType.HDDVDRAM: * case MediaType.HDDVDR: * case MediaType.HDDVDRW: * case MediaType.HDDVDRDL: * case MediaType.HDDVDRWDL: * Text = "HD DVD"; * * break; * default: * Text = "DVD"; * * break; * } */ if (decodedPfi.HasValue) { DvdPfiText = PFI.Prettify(decodedPfi); } if (cmi != null) { DvdCmiText = CSS_CPRM.PrettifyLeadInCopyright(cmi); } SaveDvdPfiVisible = pfi != null; SaveDvdDmiVisible = dmi != null; SaveDvdCmiVisible = cmi != null; SaveHdDvdCmiVisible = hdCopyrightInformation != null; SaveDvdBcaVisible = bca != null; SaveDvdAacsVisible = aacs != null; }
internal void LoadData(MediaType mediaType, byte[] pfi, byte[] dmi, byte[] cmi, byte[] hdCopyrightInformation, byte[] bca, byte[] aacs, PFI.PhysicalFormatInformation?decodedPfi) { DvdPfi = pfi; DvdDmi = dmi; DvdCmi = cmi; HddvdCopyrightInformation = hdCopyrightInformation; DvdBca = bca; DvdAacs = aacs; switch (mediaType) { case MediaType.HDDVDROM: case MediaType.HDDVDRAM: case MediaType.HDDVDR: case MediaType.HDDVDRW: case MediaType.HDDVDRDL: case MediaType.HDDVDRWDL: Text = "HD DVD"; break; default: Text = "DVD"; break; } if (decodedPfi.HasValue) { grpDvdPfi.Visible = true; txtDvdPfi.Text = PFI.Prettify(decodedPfi); } if (cmi != null) { grpDvdCmi.Visible = true; txtDvdCmi.Text = CSS_CPRM.PrettifyLeadInCopyright(cmi); btnSaveDvdCmi.Visible = true; } btnSaveDvdPfi.Visible = pfi != null; btnSaveDvdDmi.Visible = dmi != null; btnSaveDvdCmi.Visible = cmi != null; btnSaveHdDvdCmi.Visible = hdCopyrightInformation != null; btnSaveDvdBca.Visible = bca != null; btnSaveDvdAacs.Visible = aacs != null; Visible = grpDvdPfi.Visible || grpDvdCmi.Visible || btnSaveDvdPfi.Visible || btnSaveDvdDmi.Visible || btnSaveDvdCmi.Visible || btnSaveHdDvdCmi.Visible || btnSaveDvdBca.Visible || btnSaveDvdAacs.Visible; }
/// <summary>Dumps an optical disc</summary> void Mmc(ref MediaType dskType) { bool sense; byte[] tmpBuf; bool compactDisc = true; bool isXbox = false; _speedMultiplier = 1; // TODO: Log not only what is it reading, but if it was read correctly or not. sense = _dev.GetConfiguration(out byte[] cmdBuf, out _, 0, MmcGetConfigurationRt.Current, _dev.Timeout, out _); if (!sense) { Features.SeparatedFeatures ftr = Features.Separate(cmdBuf); _dumpLog.WriteLine("Device reports current profile is 0x{0:X4}", ftr.CurrentProfile); switch (ftr.CurrentProfile) { case 0x0001: dskType = MediaType.GENERIC_HDD; _speedMultiplier = -1; goto default; case 0x0002: dskType = MediaType.PD650; _speedMultiplier = -1; goto default; case 0x0005: dskType = MediaType.CDMO; break; case 0x0008: dskType = MediaType.CD; break; case 0x0009: dskType = MediaType.CDR; break; case 0x000A: dskType = MediaType.CDRW; break; case 0x0010: dskType = MediaType.DVDROM; _speedMultiplier = 9; goto default; case 0x0011: dskType = MediaType.DVDR; _speedMultiplier = 9; goto default; case 0x0012: dskType = MediaType.DVDRAM; _speedMultiplier = 9; goto default; case 0x0013: case 0x0014: dskType = MediaType.DVDRW; _speedMultiplier = 9; goto default; case 0x0015: case 0x0016: dskType = MediaType.DVDRDL; _speedMultiplier = 9; goto default; case 0x0017: dskType = MediaType.DVDRWDL; _speedMultiplier = 9; goto default; case 0x0018: dskType = MediaType.DVDDownload; _speedMultiplier = 9; goto default; case 0x001A: dskType = MediaType.DVDPRW; _speedMultiplier = 9; goto default; case 0x001B: dskType = MediaType.DVDPR; _speedMultiplier = 9; goto default; case 0x0020: dskType = MediaType.DDCD; goto default; case 0x0021: dskType = MediaType.DDCDR; goto default; case 0x0022: dskType = MediaType.DDCDRW; goto default; case 0x002A: dskType = MediaType.DVDPRWDL; _speedMultiplier = 9; goto default; case 0x002B: dskType = MediaType.DVDPRDL; _speedMultiplier = 9; goto default; case 0x0040: dskType = MediaType.BDROM; _speedMultiplier = 30; goto default; case 0x0041: case 0x0042: dskType = MediaType.BDR; _speedMultiplier = 30; goto default; case 0x0043: dskType = MediaType.BDRE; _speedMultiplier = 30; goto default; case 0x0050: dskType = MediaType.HDDVDROM; _speedMultiplier = 30; goto default; case 0x0051: dskType = MediaType.HDDVDR; _speedMultiplier = 30; goto default; case 0x0052: dskType = MediaType.HDDVDRAM; _speedMultiplier = 30; goto default; case 0x0053: dskType = MediaType.HDDVDRW; _speedMultiplier = 30; goto default; case 0x0058: dskType = MediaType.HDDVDRDL; _speedMultiplier = 30; goto default; case 0x005A: dskType = MediaType.HDDVDRWDL; _speedMultiplier = 30; goto default; default: compactDisc = false; break; } } if (compactDisc) { CompactDisc(out dskType); return; } var scsiReader = new Reader(_dev, _dev.Timeout, null, _dumpRaw); ulong blocks = scsiReader.GetDeviceBlocks(); _dumpLog.WriteLine("Device reports disc has {0} blocks", blocks); Dictionary <MediaTagType, byte[]> mediaTags = new Dictionary <MediaTagType, byte[]>(); if (dskType == MediaType.PD650) { switch (blocks + 1) { case 1281856: dskType = MediaType.PD650_WORM; break; case 58620544: dskType = MediaType.REV120; break; case 17090880: dskType = MediaType.REV35; break; // TODO: Unknown value default: dskType = MediaType.REV70; break; } } #region Nintendo switch (dskType) { case MediaType.Unknown when blocks > 0: _dumpLog.WriteLine("Reading Physical Format Information"); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _); if (!sense) { PFI.PhysicalFormatInformation?nintendoPfi = PFI.Decode(cmdBuf); if (nintendoPfi != null) { if (nintendoPfi.Value.DiskCategory == DiskCategory.Nintendo && nintendoPfi.Value.PartVersion == 15) { _dumpLog.WriteLine("Dumping Nintendo GameCube or Wii discs is not yet implemented."); StoppingErrorMessage?. Invoke("Dumping Nintendo GameCube or Wii discs is not yet implemented."); return; } } } break; case MediaType.DVDDownload: case MediaType.DVDPR: case MediaType.DVDPRDL: case MediaType.DVDPRW: case MediaType.DVDPRWDL: case MediaType.DVDR: case MediaType.DVDRAM: case MediaType.DVDRDL: case MediaType.DVDROM: case MediaType.DVDRW: case MediaType.DVDRWDL: case MediaType.HDDVDR: case MediaType.HDDVDRAM: case MediaType.HDDVDRDL: case MediaType.HDDVDROM: case MediaType.HDDVDRW: case MediaType.HDDVDRWDL: _dumpLog.WriteLine("Reading Physical Format Information"); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _); if (!sense) { if (PFI.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_PFI, tmpBuf); PFI.PhysicalFormatInformation decPfi = PFI.Decode(cmdBuf).Value; UpdateStatus?.Invoke($"PFI:\n{PFI.Prettify(decPfi)}"); // False book types if (dskType == MediaType.DVDROM) { switch (decPfi.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 = decPfi.PartVersion == 6 ? MediaType.DVDRDL : MediaType.DVDR; break; case DiskCategory.DVDRAM: dskType = MediaType.DVDRAM; break; default: dskType = MediaType.DVDROM; break; case DiskCategory.DVDRW: dskType = decPfi.PartVersion == 3 ? MediaType.DVDRWDL : 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 = decPfi.DiscSize == DVDSize.Eighty ? MediaType.GOD : MediaType.WOD; break; case DiskCategory.UMD: dskType = MediaType.UMD; break; } } } } _dumpLog.WriteLine("Reading Disc Manufacturing Information"); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, _dev.Timeout, out _); if (!sense) { if (DMI.IsXbox(cmdBuf) || DMI.IsXbox360(cmdBuf)) { if (DMI.IsXbox(cmdBuf)) { dskType = MediaType.XGD; } else if (DMI.IsXbox360(cmdBuf)) { dskType = MediaType.XGD2; // All XGD3 all have the same number of blocks if (blocks == 25063 || // Locked (or non compatible drive) blocks == 4229664 || // Xtreme unlock blocks == 4246304) // Wxripper unlock { dskType = MediaType.XGD3; } } sense = _dev.ScsiInquiry(out byte[] inqBuf, out _); if (sense || !Inquiry.Decode(inqBuf).HasValue || (Inquiry.Decode(inqBuf).HasValue&& !Inquiry.Decode(inqBuf).Value.KreonPresent)) { _dumpLog.WriteLine("Dumping Xbox Game Discs requires a drive with Kreon firmware."); StoppingErrorMessage?. Invoke("Dumping Xbox Game Discs requires a drive with Kreon firmware."); return; } if (_dumpRaw && !_force) { StoppingErrorMessage?. Invoke("Not continuing. If you want to continue reading cooked data when raw is not available use the force option."); // TODO: Exit more gracefully return; } isXbox = true; } if (cmdBuf.Length == 2052) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_DMI, tmpBuf); } } break; } #endregion Nintendo #region All DVD and HD DVD types #endregion All DVD and HD DVD types #region DVD-ROM if (dskType == MediaType.DVDDownload || dskType == MediaType.DVDROM) { _dumpLog.WriteLine("Reading Lead-in Copyright Information."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, _dev.Timeout, out _); if (!sense) { if (CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_CMI, tmpBuf); } } } #endregion DVD-ROM switch (dskType) { #region DVD-ROM and HD DVD-ROM case MediaType.DVDDownload: case MediaType.DVDROM: case MediaType.HDDVDROM: _dumpLog.WriteLine("Reading Burst Cutting Area."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_BCA, tmpBuf); } break; #endregion DVD-ROM and HD DVD-ROM #region DVD-RAM and HD DVD-RAM case MediaType.DVDRAM: case MediaType.HDDVDRAM: _dumpLog.WriteLine("Reading Disc Description Structure."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DvdramDds, 0, _dev.Timeout, out _); if (!sense) { if (DDS.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDRAM_DDS, tmpBuf); } } _dumpLog.WriteLine("Reading Spare Area Information."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, _dev.Timeout, out _); if (!sense) { if (Spare.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDRAM_SpareArea, tmpBuf); } } break; #endregion DVD-RAM and HD DVD-RAM #region DVD-R and DVD-RW case MediaType.DVDR: case MediaType.DVDRW: _dumpLog.WriteLine("Reading Pre-Recorded Information."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.PreRecordedInfo, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDR_PreRecordedInfo, tmpBuf); } break; #endregion DVD-R and DVD-RW } switch (dskType) { #region DVD-R, DVD-RW and HD DVD-R case MediaType.DVDR: case MediaType.DVDRW: case MediaType.HDDVDR: _dumpLog.WriteLine("Reading Media Identifier."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DvdrMediaIdentifier, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDR_MediaIdentifier, tmpBuf); } _dumpLog.WriteLine("Reading Recordable Physical Information."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DvdrPhysicalInformation, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDR_PFI, tmpBuf); } break; #endregion DVD-R, DVD-RW and HD DVD-R #region All DVD+ case MediaType.DVDPR: case MediaType.DVDPRDL: case MediaType.DVDPRW: case MediaType.DVDPRWDL: _dumpLog.WriteLine("Reading ADdress In Pregroove."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.Adip, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_ADIP, tmpBuf); } _dumpLog.WriteLine("Reading Disc Control Blocks."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.Dcb, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DCB, tmpBuf); } break; #endregion All DVD+ #region HD DVD-ROM case MediaType.HDDVDROM: _dumpLog.WriteLine("Reading Lead-in Copyright Information."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.HddvdCopyrightInformation, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.HDDVD_CPI, tmpBuf); } break; #endregion HD DVD-ROM #region All Blu-ray case MediaType.BDR: case MediaType.BDRE: case MediaType.BDROM: case MediaType.BDRXL: case MediaType.BDREXL: _dumpLog.WriteLine("Reading Disc Information."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, MmcDiscStructureFormat.DiscInformation, 0, _dev.Timeout, out _); if (!sense) { if (DI.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.BD_DI, tmpBuf); } } // TODO: PAC /* * dumpLog.WriteLine("Reading PAC."); * sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, * MmcDiscStructureFormat.Pac, 0, dev.Timeout, out _); * if(!sense) * { * tmpBuf = new byte[cmdBuf.Length - 4]; * Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); * mediaTags.Add(MediaTagType.PAC, tmpBuf); * }*/ break; #endregion All Blu-ray } switch (dskType) { #region BD-ROM only case MediaType.BDROM: _dumpLog.WriteLine("Reading Burst Cutting Area."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, MmcDiscStructureFormat.BdBurstCuttingArea, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.BD_BCA, tmpBuf); } break; #endregion BD-ROM only #region Writable Blu-ray only case MediaType.BDR: case MediaType.BDRE: case MediaType.BDRXL: case MediaType.BDREXL: _dumpLog.WriteLine("Reading Disc Definition Structure."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, MmcDiscStructureFormat.BdDds, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.BD_DDS, tmpBuf); } _dumpLog.WriteLine("Reading Spare Area Information."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, MmcDiscStructureFormat.BdSpareAreaInformation, 0, _dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.BD_SpareArea, tmpBuf); } break; #endregion Writable Blu-ray only } if (isXbox) { Xgd(mediaTags, ref dskType); return; } Sbc(mediaTags, ref dskType, 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 pnlImageInfo(string imagePath, IFilter filter, IMediaImage imageFormat) { this.imagePath = imagePath; this.filter = filter; this.imageFormat = imageFormat; XamlReader.Load(this); Stream logo = ResourceHandler .GetResourceStream($"DiscImageChef.Gui.Assets.Logos.Media.{imageFormat.Info.MediaType}.svg"); /* if(logo != null) * { * svgMediaLogo.SvgStream = logo; * svgMediaLogo.Visible = true; * } * else * {*/ logo = ResourceHandler .GetResourceStream($"DiscImageChef.Gui.Assets.Logos.Media.{imageFormat.Info.MediaType}.png"); if (logo != null) { imgMediaLogo.Image = new Bitmap(logo); imgMediaLogo.Visible = true; } //} lblImagePath.Text = $"Path: {imagePath}"; lblFilter.Text = $"Filter: {filter.Name}"; lblImageFormat.Text = $"Image format identified by {imageFormat.Name} ({imageFormat.Id})."; lblImageFormat.Text = !string.IsNullOrWhiteSpace(imageFormat.Info.Version) ? $"Format: {imageFormat.Format} version {imageFormat.Info.Version}" : $"Format: {imageFormat.Format}"; lblImageSize.Text = $"Image without headers is {imageFormat.Info.ImageSize} bytes long"; lblSectors.Text = $"Contains a media of {imageFormat.Info.Sectors} sectors with a maximum sector size of {imageFormat.Info.SectorSize} bytes (if all sectors are of the same size this would be {imageFormat.Info.Sectors * imageFormat.Info.SectorSize} bytes)"; lblMediaType.Text = $"Contains a media of type {imageFormat.Info.MediaType} and XML type {imageFormat.Info.XmlMediaType}"; lblHasPartitions.Text = $"{(imageFormat.Info.HasPartitions ? "Has" : "Doesn't have")} partitions"; lblHasSessions.Text = $"{(imageFormat.Info.HasSessions ? "Has" : "Doesn't have")} sessions"; if (!string.IsNullOrWhiteSpace(imageFormat.Info.Application)) { lblApplication.Visible = true; lblApplication.Text = !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion) ? $"Was created with {imageFormat.Info.Application} version {imageFormat.Info.ApplicationVersion}" : $"Was created with {imageFormat.Info.Application}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.Creator)) { lblCreator.Visible = true; lblCreator.Text = $"Created by: {imageFormat.Info.Creator}"; } if (imageFormat.Info.CreationTime != DateTime.MinValue) { lblCreationTime.Visible = true; lblCreationTime.Text = $"Created on {imageFormat.Info.CreationTime}"; } if (imageFormat.Info.LastModificationTime != DateTime.MinValue) { lblLastModificationTime.Visible = true; lblLastModificationTime.Text = $"Last modified on {imageFormat.Info.LastModificationTime}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.Comments)) { grpComments.Visible = true; txtComments.Text = imageFormat.Info.Comments; } if (imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0) { lblMediaSequence.Visible = true; lblMediaSequence.Text = $"Media is number {imageFormat.Info.MediaSequence} on a set of {imageFormat.Info.LastMediaSequence} medias"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle)) { lblMediaTitle.Visible = true; lblMediaTitle.Text = $"Media title: {imageFormat.Info.MediaTitle}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer)) { lblMediaManufacturer.Visible = true; lblMediaManufacturer.Text = $"Media manufacturer: {imageFormat.Info.MediaManufacturer}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel)) { lblMediaModel.Visible = true; lblMediaModel.Text = $"Media model: {imageFormat.Info.MediaModel}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber)) { lblMediaSerialNumber.Visible = true; lblMediaSerialNumber.Text = $"Media serial number: {imageFormat.Info.MediaSerialNumber}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode)) { lblMediaBarcode.Visible = true; lblMediaBarcode.Text = $"Media barcode: {imageFormat.Info.MediaBarcode}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber)) { lblMediaPartNumber.Visible = true; lblMediaPartNumber.Text = $"Media part number: {imageFormat.Info.MediaPartNumber}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer)) { lblDriveManufacturer.Visible = true; lblDriveManufacturer.Text = $"Drive manufacturer: {imageFormat.Info.DriveManufacturer}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel)) { lblDriveModel.Visible = true; lblDriveModel.Text = $"Drive model: {imageFormat.Info.DriveModel}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber)) { lblDriveSerialNumber.Visible = true; lblDriveSerialNumber.Text = $"Drive serial number: {imageFormat.Info.DriveSerialNumber}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision)) { lblDriveFirmwareRevision.Visible = true; lblDriveFirmwareRevision.Text = $"Drive firmware info: {imageFormat.Info.DriveFirmwareRevision}"; } if (imageFormat.Info.Cylinders > 0 && imageFormat.Info.Heads > 0 && imageFormat.Info.SectorsPerTrack > 0 && imageFormat.Info.XmlMediaType != XmlMediaType.OpticalDisc && (!(imageFormat is ITapeImage tapeImage) || !tapeImage.IsTape)) { lblMediaGeometry.Visible = true; lblMediaGeometry.Text = $"Media geometry: {imageFormat.Info.Cylinders} cylinders, {imageFormat.Info.Heads} heads, {imageFormat.Info.SectorsPerTrack} sectors per track"; } grpMediaInfo.Visible = lblMediaSequence.Visible || lblMediaTitle.Visible || lblMediaManufacturer.Visible || lblMediaModel.Visible || lblMediaSerialNumber.Visible || lblMediaBarcode.Visible || lblMediaPartNumber.Visible; grpDriveInfo.Visible = lblDriveManufacturer.Visible || lblDriveModel.Visible || lblDriveSerialNumber.Visible || lblDriveFirmwareRevision.Visible || lblMediaGeometry.Visible; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Count > 0) { TreeGridItemCollection mediaTagList = new TreeGridItemCollection(); treeMediaTags.Columns.Add(new GridColumn { HeaderText = "Tag", DataCell = new TextBoxCell(0) }); treeMediaTags.AllowMultipleSelection = false; treeMediaTags.ShowHeader = false; treeMediaTags.DataStore = mediaTagList; foreach (MediaTagType tag in imageFormat.Info.ReadableMediaTags.OrderBy(t => t)) { mediaTagList.Add(new TreeGridItem { Values = new object[] { tag.ToString() } }); } grpMediaTags.Visible = true; } if (imageFormat.Info.ReadableSectorTags != null && imageFormat.Info.ReadableSectorTags.Count > 0) { TreeGridItemCollection sectorTagList = new TreeGridItemCollection(); treeSectorTags.Columns.Add(new GridColumn { HeaderText = "Tag", DataCell = new TextBoxCell(0) }); treeSectorTags.AllowMultipleSelection = false; treeSectorTags.ShowHeader = false; treeSectorTags.DataStore = sectorTagList; foreach (SectorTagType tag in imageFormat.Info.ReadableSectorTags.OrderBy(t => t)) { sectorTagList.Add(new TreeGridItem { Values = new object[] { tag.ToString() } }); } grpSectorTags.Visible = true; } PeripheralDeviceTypes scsiDeviceType = PeripheralDeviceTypes.DirectAccess; byte[] scsiInquiryData = null; Inquiry.SCSIInquiry?scsiInquiry = null; Modes.DecodedMode? scsiMode = null; byte[] scsiModeSense6 = null; byte[] scsiModeSense10 = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_INQUIRY)) { scsiInquiryData = imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY); scsiDeviceType = (PeripheralDeviceTypes)(scsiInquiryData[0] & 0x1F); scsiInquiry = Inquiry.Decode(scsiInquiryData); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6)) { scsiModeSense6 = imageFormat.ReadDiskTag(MediaTagType.SCSI_MODESENSE_6); scsiMode = Modes.DecodeMode6(scsiModeSense6, scsiDeviceType); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10)) { scsiModeSense10 = imageFormat.ReadDiskTag(MediaTagType.SCSI_MODESENSE_10); scsiMode = Modes.DecodeMode10(scsiModeSense10, scsiDeviceType); } tabScsiInfo tabScsiInfo = new tabScsiInfo(); tabScsiInfo.LoadData(scsiInquiryData, scsiInquiry, null, scsiMode, scsiDeviceType, scsiModeSense6, scsiModeSense10, null); tabInfos.Pages.Add(tabScsiInfo); byte[] ataIdentify = null; byte[] atapiIdentify = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) { ataIdentify = imageFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY)) { atapiIdentify = imageFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY); } tabAtaInfo tabAtaInfo = new tabAtaInfo(); tabAtaInfo.LoadData(ataIdentify, atapiIdentify, null); tabInfos.Pages.Add(tabAtaInfo); byte[] toc = null; TOC.CDTOC? decodedToc = null; byte[] fullToc = null; FullTOC.CDFullTOC? decodedFullToc = null; byte[] pma = null; byte[] atip = null; ATIP.CDATIP? decodedAtip = null; byte[] cdtext = null; CDTextOnLeadIn.CDText?decodedCdText = null; string mediaCatalogueNumber = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_TOC)) { toc = imageFormat.ReadDiskTag(MediaTagType.CD_TOC); if (toc.Length > 0) { ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(toc, 0)); if (dataLen + 2 != toc.Length) { byte[] tmp = new byte[toc.Length + 2]; Array.Copy(toc, 0, tmp, 2, toc.Length); tmp[0] = (byte)((toc.Length & 0xFF00) >> 8); tmp[1] = (byte)(toc.Length & 0xFF); toc = tmp; } decodedToc = TOC.Decode(toc); } } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_FullTOC)) { fullToc = imageFormat.ReadDiskTag(MediaTagType.CD_FullTOC); if (fullToc.Length > 0) { ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(fullToc, 0)); if (dataLen + 2 != fullToc.Length) { byte[] tmp = new byte[fullToc.Length + 2]; Array.Copy(fullToc, 0, tmp, 2, fullToc.Length); tmp[0] = (byte)((fullToc.Length & 0xFF00) >> 8); tmp[1] = (byte)(fullToc.Length & 0xFF); fullToc = tmp; } decodedFullToc = FullTOC.Decode(fullToc); } } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_PMA)) { pma = imageFormat.ReadDiskTag(MediaTagType.CD_PMA); if (pma.Length > 0) { ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(pma, 0)); if (dataLen + 2 != pma.Length) { byte[] tmp = new byte[pma.Length + 2]; Array.Copy(pma, 0, tmp, 2, pma.Length); tmp[0] = (byte)((pma.Length & 0xFF00) >> 8); tmp[1] = (byte)(pma.Length & 0xFF); pma = tmp; } } } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_ATIP)) { atip = imageFormat.ReadDiskTag(MediaTagType.CD_ATIP); uint dataLen = Swapping.Swap(BitConverter.ToUInt32(atip, 0)); if (dataLen + 4 != atip.Length) { byte[] tmp = new byte[atip.Length + 4]; Array.Copy(atip, 0, tmp, 4, atip.Length); tmp[0] = (byte)((atip.Length & 0xFF000000) >> 24); tmp[1] = (byte)((atip.Length & 0xFF0000) >> 16); tmp[2] = (byte)((atip.Length & 0xFF00) >> 8); tmp[3] = (byte)(atip.Length & 0xFF); atip = tmp; } decodedAtip = ATIP.Decode(atip); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_TEXT)) { cdtext = imageFormat.ReadDiskTag(MediaTagType.CD_TEXT); uint dataLen = Swapping.Swap(BitConverter.ToUInt32(cdtext, 0)); if (dataLen + 4 != cdtext.Length) { byte[] tmp = new byte[cdtext.Length + 4]; Array.Copy(cdtext, 0, tmp, 4, cdtext.Length); tmp[0] = (byte)((cdtext.Length & 0xFF000000) >> 24); tmp[1] = (byte)((cdtext.Length & 0xFF0000) >> 16); tmp[2] = (byte)((cdtext.Length & 0xFF00) >> 8); tmp[3] = (byte)(cdtext.Length & 0xFF); cdtext = tmp; } decodedCdText = CDTextOnLeadIn.Decode(cdtext); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_MCN)) { byte[] mcn = imageFormat.ReadDiskTag(MediaTagType.CD_MCN); mediaCatalogueNumber = Encoding.UTF8.GetString(mcn); } tabCompactDiscInfo tabCompactDiscInfo = new tabCompactDiscInfo(); tabCompactDiscInfo.LoadData(toc, atip, null, null, fullToc, pma, cdtext, decodedToc, decodedAtip, null, decodedFullToc, decodedCdText, null, mediaCatalogueNumber, null); tabInfos.Pages.Add(tabCompactDiscInfo); byte[] dvdPfi = null; byte[] dvdDmi = null; byte[] dvdCmi = null; byte[] hddvdCopyrightInformation = null; byte[] dvdBca = null; PFI.PhysicalFormatInformation?decodedPfi = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_PFI)) { dvdPfi = imageFormat.ReadDiskTag(MediaTagType.DVD_PFI); decodedPfi = PFI.Decode(dvdPfi); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_DMI)) { dvdDmi = imageFormat.ReadDiskTag(MediaTagType.DVD_DMI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_CMI)) { dvdCmi = imageFormat.ReadDiskTag(MediaTagType.DVD_CMI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.HDDVD_CPI)) { hddvdCopyrightInformation = imageFormat.ReadDiskTag(MediaTagType.HDDVD_CPI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_BCA)) { dvdBca = imageFormat.ReadDiskTag(MediaTagType.DVD_BCA); } tabDvdInfo tabDvdInfo = new tabDvdInfo(); tabDvdInfo.LoadData(imageFormat.Info.MediaType, dvdPfi, dvdDmi, dvdCmi, hddvdCopyrightInformation, dvdBca, null, decodedPfi); tabInfos.Pages.Add(tabDvdInfo); byte[] dvdRamDds = null; byte[] dvdRamCartridgeStatus = null; byte[] dvdRamSpareArea = null; byte[] lastBorderOutRmd = null; byte[] dvdPreRecordedInfo = null; byte[] dvdrMediaIdentifier = null; byte[] dvdrPhysicalInformation = null; byte[] hddvdrMediumStatus = null; byte[] dvdrLayerCapacity = null; byte[] dvdrDlMiddleZoneStart = null; byte[] dvdrDlJumpIntervalSize = null; byte[] dvdrDlManualLayerJumpStartLba = null; byte[] dvdPlusAdip = null; byte[] dvdPlusDcb = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_DDS)) { dvdRamDds = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_DDS); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_MediumStatus)) { dvdRamCartridgeStatus = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_MediumStatus); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_SpareArea)) { dvdRamSpareArea = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_SpareArea); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_RMD)) { lastBorderOutRmd = imageFormat.ReadDiskTag(MediaTagType.DVDR_RMD); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_PreRecordedInfo)) { dvdPreRecordedInfo = imageFormat.ReadDiskTag(MediaTagType.DVDR_PreRecordedInfo); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_MediaIdentifier)) { dvdrMediaIdentifier = imageFormat.ReadDiskTag(MediaTagType.DVDR_MediaIdentifier); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_PFI)) { dvdrPhysicalInformation = imageFormat.ReadDiskTag(MediaTagType.DVDR_PFI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.HDDVD_MediumStatus)) { hddvdrMediumStatus = imageFormat.ReadDiskTag(MediaTagType.HDDVD_MediumStatus); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_LayerCapacity)) { dvdrLayerCapacity = imageFormat.ReadDiskTag(MediaTagType.DVDDL_LayerCapacity); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_MiddleZoneAddress)) { dvdrDlMiddleZoneStart = imageFormat.ReadDiskTag(MediaTagType.DVDDL_MiddleZoneAddress); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_JumpIntervalSize)) { dvdrDlJumpIntervalSize = imageFormat.ReadDiskTag(MediaTagType.DVDDL_JumpIntervalSize); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_ManualLayerJumpLBA)) { dvdrDlManualLayerJumpStartLba = imageFormat.ReadDiskTag(MediaTagType.DVDDL_ManualLayerJumpLBA); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_ADIP)) { dvdPlusAdip = imageFormat.ReadDiskTag(MediaTagType.DVD_ADIP); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DCB)) { dvdPlusDcb = imageFormat.ReadDiskTag(MediaTagType.DCB); } tabDvdWritableInfo tabDvdWritableInfo = new tabDvdWritableInfo(); tabDvdWritableInfo.LoadData(imageFormat.Info.MediaType, dvdRamDds, dvdRamCartridgeStatus, dvdRamSpareArea, lastBorderOutRmd, dvdPreRecordedInfo, dvdrMediaIdentifier, dvdrPhysicalInformation, hddvdrMediumStatus, null, dvdrLayerCapacity, dvdrDlMiddleZoneStart, dvdrDlJumpIntervalSize, dvdrDlManualLayerJumpStartLba, null, dvdPlusAdip, dvdPlusDcb); tabInfos.Pages.Add(tabDvdWritableInfo); byte[] blurayBurstCuttingArea = null; byte[] blurayCartridgeStatus = null; byte[] blurayDds = null; byte[] blurayDiscInformation = null; byte[] blurayPowResources = null; byte[] bluraySpareAreaInformation = null; byte[] blurayTrackResources = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_BCA)) { blurayBurstCuttingArea = imageFormat.ReadDiskTag(MediaTagType.BD_BCA); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_CartridgeStatus)) { blurayCartridgeStatus = imageFormat.ReadDiskTag(MediaTagType.BD_CartridgeStatus); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_DDS)) { blurayDds = imageFormat.ReadDiskTag(MediaTagType.BD_DDS); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_DI)) { blurayDiscInformation = imageFormat.ReadDiskTag(MediaTagType.BD_DI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_POWResourcesInformation)) { blurayPowResources = imageFormat.ReadDiskTag(MediaTagType.MMC_POWResourcesInformation); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_SpareArea)) { bluraySpareAreaInformation = imageFormat.ReadDiskTag(MediaTagType.BD_SpareArea); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_TrackResourcesInformation)) { bluraySpareAreaInformation = imageFormat.ReadDiskTag(MediaTagType.MMC_TrackResourcesInformation); } tabBlurayInfo tabBlurayInfo = new tabBlurayInfo(); tabBlurayInfo.LoadData(blurayDiscInformation, blurayBurstCuttingArea, blurayDds, blurayCartridgeStatus, bluraySpareAreaInformation, blurayPowResources, blurayTrackResources, null, null); tabInfos.Pages.Add(tabBlurayInfo); byte[] xboxDmi = null; byte[] xboxSecuritySector = null; SS.SecuritySector?decodedXboxSecuritySector = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.Xbox_DMI)) { xboxDmi = imageFormat.ReadDiskTag(MediaTagType.Xbox_DMI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.Xbox_SecuritySector)) { xboxSecuritySector = imageFormat.ReadDiskTag(MediaTagType.Xbox_SecuritySector); decodedXboxSecuritySector = SS.Decode(xboxSecuritySector); } tabXboxInfo tabXboxInfo = new tabXboxInfo(); tabXboxInfo.LoadData(null, xboxDmi, xboxSecuritySector, decodedXboxSecuritySector); tabInfos.Pages.Add(tabXboxInfo); byte[] pcmciaCis = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.PCMCIA_CIS)) { pcmciaCis = imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS); } tabPcmciaInfo tabPcmciaInfo = new tabPcmciaInfo(); tabPcmciaInfo.LoadData(pcmciaCis); tabInfos.Pages.Add(tabPcmciaInfo); DeviceType deviceType = DeviceType.Unknown; byte[] cid = null; byte[] csd = null; byte[] ocr = null; byte[] extendedCsd = null; byte[] scr = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_CID)) { cid = imageFormat.ReadDiskTag(MediaTagType.SD_CID); deviceType = DeviceType.SecureDigital; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_CSD)) { csd = imageFormat.ReadDiskTag(MediaTagType.SD_CSD); deviceType = DeviceType.SecureDigital; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_OCR)) { ocr = imageFormat.ReadDiskTag(MediaTagType.SD_OCR); deviceType = DeviceType.SecureDigital; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_SCR)) { scr = imageFormat.ReadDiskTag(MediaTagType.SD_SCR); deviceType = DeviceType.SecureDigital; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_CID)) { cid = imageFormat.ReadDiskTag(MediaTagType.MMC_CID); deviceType = DeviceType.MMC; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_CSD)) { csd = imageFormat.ReadDiskTag(MediaTagType.MMC_CSD); deviceType = DeviceType.MMC; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_OCR)) { ocr = imageFormat.ReadDiskTag(MediaTagType.MMC_OCR); deviceType = DeviceType.MMC; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_ExtendedCSD)) { extendedCsd = imageFormat.ReadDiskTag(MediaTagType.MMC_ExtendedCSD); deviceType = DeviceType.MMC; } tabSdMmcInfo tabSdMmcInfo = new tabSdMmcInfo(); tabSdMmcInfo.LoadData(deviceType, cid, csd, ocr, extendedCsd, scr); tabInfos.Pages.Add(tabSdMmcInfo); if (imageFormat is IOpticalMediaImage opticalMediaImage) { try { if (opticalMediaImage.Sessions != null && opticalMediaImage.Sessions.Count > 0) { TreeGridItemCollection sessionList = new TreeGridItemCollection(); treeSessions.Columns.Add(new GridColumn { HeaderText = "Session", DataCell = new TextBoxCell(0) }); treeSessions.Columns.Add(new GridColumn { HeaderText = "First track", DataCell = new TextBoxCell(1) }); treeSessions.Columns.Add(new GridColumn { HeaderText = "Last track", DataCell = new TextBoxCell(2) }); treeSessions.Columns.Add(new GridColumn { HeaderText = "Start", DataCell = new TextBoxCell(3) }); treeSessions.Columns.Add(new GridColumn { HeaderText = "End", DataCell = new TextBoxCell(4) }); treeSessions.AllowMultipleSelection = false; treeSessions.ShowHeader = true; treeSessions.DataStore = sessionList; foreach (Session session in opticalMediaImage.Sessions) { sessionList.Add(new TreeGridItem { Values = new object[] { session.SessionSequence, session.StartTrack, session.EndTrack, session.StartSector, session.EndSector } }); } tabSessions.Visible = true; } } catch { // ignored } try { if (opticalMediaImage.Tracks != null && opticalMediaImage.Tracks.Count > 0) { TreeGridItemCollection tracksList = new TreeGridItemCollection(); treeTracks.Columns.Add(new GridColumn { HeaderText = "Track", DataCell = new TextBoxCell(0) }); treeTracks.Columns.Add(new GridColumn { HeaderText = "Type", DataCell = new TextBoxCell(1) }); treeTracks.Columns.Add(new GridColumn { HeaderText = "Bps", DataCell = new TextBoxCell(2) }); treeTracks.Columns.Add(new GridColumn { HeaderText = "Raw bps", DataCell = new TextBoxCell(3) }); treeTracks.Columns.Add(new GridColumn { HeaderText = "Subchannel", DataCell = new TextBoxCell(4) }); treeTracks.Columns.Add(new GridColumn { HeaderText = "Pregap", DataCell = new TextBoxCell(5) }); treeTracks.Columns.Add(new GridColumn { HeaderText = "Start", DataCell = new TextBoxCell(6) }); treeTracks.Columns.Add(new GridColumn { HeaderText = "End", DataCell = new TextBoxCell(7) }); treeTracks.AllowMultipleSelection = false; treeTracks.ShowHeader = true; treeTracks.DataStore = tracksList; foreach (Track track in opticalMediaImage.Tracks) { tracksList.Add(new TreeGridItem { Values = new object[] { track.TrackSequence, track.TrackType, track.TrackBytesPerSector, track.TrackRawBytesPerSector, track.TrackSubchannelType, track.TrackPregap, track.TrackStartSector, track.TrackEndSector } }); } tabTracks.Visible = true; } } catch { // ignored } } if (imageFormat.DumpHardware == null) { return; } TreeGridItemCollection dumpHardwareList = new TreeGridItemCollection(); treeDumpHardware.Columns.Add(new GridColumn { HeaderText = "Manufacturer", DataCell = new TextBoxCell(0) }); treeDumpHardware.Columns.Add(new GridColumn { HeaderText = "Model", DataCell = new TextBoxCell(1) }); treeDumpHardware.Columns.Add(new GridColumn { HeaderText = "Serial", DataCell = new TextBoxCell(2) }); treeDumpHardware.Columns.Add(new GridColumn { HeaderText = "Software", DataCell = new TextBoxCell(3) }); treeDumpHardware.Columns.Add(new GridColumn { HeaderText = "Version", DataCell = new TextBoxCell(4) }); treeDumpHardware.Columns.Add(new GridColumn { HeaderText = "Operating system", DataCell = new TextBoxCell(5) }); treeDumpHardware.Columns.Add(new GridColumn { HeaderText = "Start", DataCell = new TextBoxCell(6) }); treeDumpHardware.Columns.Add(new GridColumn { HeaderText = "End", DataCell = new TextBoxCell(7) }); treeDumpHardware.AllowMultipleSelection = false; treeDumpHardware.ShowHeader = true; treeDumpHardware.DataStore = dumpHardwareList; foreach (DumpHardwareType dump in imageFormat.DumpHardware) { foreach (ExtentType extent in dump.Extents) { dumpHardwareList.Add(new TreeGridItem { Values = new object[] { dump.Manufacturer, dump.Model, dump.Serial, dump.Software.Name, dump.Software.Version, dump.Software.OperatingSystem, extent.Start, extent.End } }); } } tabDumpHardware.Visible = true; }
/// <summary> /// Dumps an optical disc /// </summary> /// <param name="dev">Device</param> /// <param name="devicePath">Path to the device</param> /// <param name="outputPrefix">Prefix for output data files</param> /// <param name="outputPlugin">Plugin for output file</param> /// <param name="retryPasses">How many times to retry</param> /// <param name="force">Force to continue dump whenever possible</param> /// <param name="dumpRaw">Dump raw/long sectors</param> /// <param name="persistent">Store whatever data the drive returned on error</param> /// <param name="stopOnError">Stop dump on first error</param> /// <param name="resume">Information for dump resuming</param> /// <param name="dumpLog">Dump logger</param> /// <param name="encoding">Encoding to use when analyzing dump</param> /// <param name="dskType">Disc type as detected in MMC layer</param> /// <param name="dumpLeadIn">Try to read and dump as much Lead-in as possible</param> /// <param name="outputPath">Path to output file</param> /// <param name="formatOptions">Formats to pass to output file plugin</param> /// <exception cref="NotImplementedException">If trying to dump GOD or WOD, or XGDs without a Kreon drive</exception> internal static void Dump(Device dev, string devicePath, IWritableImage outputPlugin, ushort retryPasses, bool force, bool dumpRaw, bool persistent, bool stopOnError, ref MediaType dskType, ref Resume resume, ref DumpLog dumpLog, bool dumpLeadIn, Encoding encoding, string outputPrefix, string outputPath, Dictionary <string, string> formatOptions, CICMMetadataType preSidecar, uint skip, bool nometadata, bool notrim) { bool sense; ulong blocks; byte[] tmpBuf; bool compactDisc = true; bool isXbox = false; // TODO: Log not only what is it reading, but if it was read correctly or not. sense = dev.GetConfiguration(out byte[] cmdBuf, out _, 0, MmcGetConfigurationRt.Current, dev.Timeout, out _); if (!sense) { Features.SeparatedFeatures ftr = Features.Separate(cmdBuf); dumpLog.WriteLine("Device reports current profile is 0x{0:X4}", ftr.CurrentProfile); switch (ftr.CurrentProfile) { case 0x0001: dskType = MediaType.GENERIC_HDD; goto default; case 0x0005: dskType = MediaType.CDMO; break; case 0x0008: dskType = MediaType.CD; break; case 0x0009: dskType = MediaType.CDR; break; case 0x000A: dskType = MediaType.CDRW; break; case 0x0010: dskType = MediaType.DVDROM; goto default; case 0x0011: dskType = MediaType.DVDR; goto default; case 0x0012: dskType = MediaType.DVDRAM; goto default; case 0x0013: case 0x0014: dskType = MediaType.DVDRW; goto default; case 0x0015: case 0x0016: dskType = MediaType.DVDRDL; goto default; case 0x0017: dskType = MediaType.DVDRWDL; goto default; case 0x0018: dskType = MediaType.DVDDownload; goto default; case 0x001A: dskType = MediaType.DVDPRW; goto default; case 0x001B: dskType = MediaType.DVDPR; goto default; case 0x0020: dskType = MediaType.DDCD; goto default; case 0x0021: dskType = MediaType.DDCDR; goto default; case 0x0022: dskType = MediaType.DDCDRW; goto default; case 0x002A: dskType = MediaType.DVDPRWDL; goto default; case 0x002B: dskType = MediaType.DVDPRDL; goto default; case 0x0040: dskType = MediaType.BDROM; goto default; case 0x0041: case 0x0042: dskType = MediaType.BDR; goto default; case 0x0043: dskType = MediaType.BDRE; goto default; case 0x0050: dskType = MediaType.HDDVDROM; goto default; case 0x0051: dskType = MediaType.HDDVDR; goto default; case 0x0052: dskType = MediaType.HDDVDRAM; goto default; case 0x0053: dskType = MediaType.HDDVDRW; goto default; case 0x0058: dskType = MediaType.HDDVDRDL; goto default; case 0x005A: dskType = MediaType.HDDVDRWDL; goto default; default: compactDisc = false; break; } } if (compactDisc) { CompactDisc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath, formatOptions, preSidecar, skip, nometadata, notrim); return; } Reader scsiReader = new Reader(dev, dev.Timeout, null, dumpRaw); blocks = scsiReader.GetDeviceBlocks(); dumpLog.WriteLine("Device reports disc has {0} blocks", blocks); Dictionary <MediaTagType, byte[]> mediaTags = new Dictionary <MediaTagType, byte[]>(); #region Nintendo switch (dskType) { case MediaType.Unknown when blocks > 0: dumpLog.WriteLine("Reading Physical Format Information"); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out _); if (!sense) { PFI.PhysicalFormatInformation?nintendoPfi = PFI.Decode(cmdBuf); if (nintendoPfi != null) { if (nintendoPfi.Value.DiskCategory == DiskCategory.Nintendo && nintendoPfi.Value.PartVersion == 15) { dumpLog.WriteLine("Dumping Nintendo GameCube or Wii discs is not yet implemented."); throw new NotImplementedException("Dumping Nintendo GameCube or Wii discs is not yet implemented."); } } } break; case MediaType.DVDDownload: case MediaType.DVDPR: case MediaType.DVDPRDL: case MediaType.DVDPRW: case MediaType.DVDPRWDL: case MediaType.DVDR: case MediaType.DVDRAM: case MediaType.DVDRDL: case MediaType.DVDROM: case MediaType.DVDRW: case MediaType.DVDRWDL: case MediaType.HDDVDR: case MediaType.HDDVDRAM: case MediaType.HDDVDRDL: case MediaType.HDDVDROM: case MediaType.HDDVDRW: case MediaType.HDDVDRWDL: dumpLog.WriteLine("Reading Physical Format Information"); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, dev.Timeout, out _); if (!sense) { if (PFI.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_PFI, tmpBuf); PFI.PhysicalFormatInformation decPfi = PFI.Decode(cmdBuf).Value; DicConsole.WriteLine("PFI:\n{0}", PFI.Prettify(decPfi)); // False book types if (dskType == MediaType.DVDROM) { switch (decPfi.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 = decPfi.PartVersion == 6 ? MediaType.DVDRDL : MediaType.DVDR; break; case DiskCategory.DVDRAM: dskType = MediaType.DVDRAM; break; default: dskType = MediaType.DVDROM; break; case DiskCategory.DVDRW: dskType = decPfi.PartVersion == 3 ? MediaType.DVDRWDL : 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 = decPfi.DiscSize == DVDSize.Eighty ? MediaType.GOD : MediaType.WOD; break; case DiskCategory.UMD: dskType = MediaType.UMD; break; } } } } dumpLog.WriteLine("Reading Disc Manufacturing Information"); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, dev.Timeout, out _); if (!sense) { if (DMI.IsXbox(cmdBuf) || DMI.IsXbox360(cmdBuf)) { if (DMI.IsXbox(cmdBuf)) { dskType = MediaType.XGD; } else if (DMI.IsXbox360(cmdBuf)) { dskType = MediaType.XGD2; // All XGD3 all have the same number of blocks if (blocks == 25063 || // Locked (or non compatible drive) blocks == 4229664 || // Xtreme unlock blocks == 4246304) // Wxripper unlock { dskType = MediaType.XGD3; } } sense = dev.ScsiInquiry(out byte[] inqBuf, out _); if (sense || !Inquiry.Decode(inqBuf).HasValue || Inquiry.Decode(inqBuf).HasValue&& !Inquiry.Decode(inqBuf).Value.KreonPresent) { dumpLog.WriteLine("Dumping Xbox Game Discs requires a drive with Kreon firmware."); throw new NotImplementedException("Dumping Xbox Game Discs requires a drive with Kreon firmware."); } if (dumpRaw && !force) { DicConsole .ErrorWriteLine("Not continuing. If you want to continue reading cooked data when raw is not available use the force option."); // TODO: Exit more gracefully return; } isXbox = true; } if (cmdBuf.Length == 2052) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_DMI, tmpBuf); } } break; } #endregion Nintendo #region All DVD and HD DVD types #endregion All DVD and HD DVD types #region DVD-ROM if (dskType == MediaType.DVDDownload || dskType == MediaType.DVDROM) { dumpLog.WriteLine("Reading Lead-in Copyright Information."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, dev.Timeout, out _); if (!sense) { if (CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_CMI, tmpBuf); } } } #endregion DVD-ROM switch (dskType) { #region DVD-ROM and HD DVD-ROM case MediaType.DVDDownload: case MediaType.DVDROM: case MediaType.HDDVDROM: dumpLog.WriteLine("Reading Burst Cutting Area."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_BCA, tmpBuf); } break; #endregion DVD-ROM and HD DVD-ROM #region DVD-RAM and HD DVD-RAM case MediaType.DVDRAM: case MediaType.HDDVDRAM: dumpLog.WriteLine("Reading Disc Description Structure."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DvdramDds, 0, dev.Timeout, out _); if (!sense) { if (DDS.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDRAM_DDS, tmpBuf); } } dumpLog.WriteLine("Reading Spare Area Information."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DvdramSpareAreaInformation, 0, dev.Timeout, out _); if (!sense) { if (Spare.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDRAM_SpareArea, tmpBuf); } } break; #endregion DVD-RAM and HD DVD-RAM #region DVD-R and DVD-RW case MediaType.DVDR: case MediaType.DVDRW: dumpLog.WriteLine("Reading Pre-Recorded Information."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.PreRecordedInfo, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDR_PreRecordedInfo, tmpBuf); } break; #endregion DVD-R and DVD-RW } switch (dskType) { #region DVD-R, DVD-RW and HD DVD-R case MediaType.DVDR: case MediaType.DVDRW: case MediaType.HDDVDR: dumpLog.WriteLine("Reading Media Identifier."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DvdrMediaIdentifier, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDR_MediaIdentifier, tmpBuf); } dumpLog.WriteLine("Reading Recordable Physical Information."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DvdrPhysicalInformation, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVDR_PFI, tmpBuf); } break; #endregion DVD-R, DVD-RW and HD DVD-R #region All DVD+ case MediaType.DVDPR: case MediaType.DVDPRDL: case MediaType.DVDPRW: case MediaType.DVDPRWDL: dumpLog.WriteLine("Reading ADdress In Pregroove."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.Adip, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_ADIP, tmpBuf); } dumpLog.WriteLine("Reading Disc Control Blocks."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.Dcb, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DCB, tmpBuf); } break; #endregion All DVD+ #region HD DVD-ROM case MediaType.HDDVDROM: dumpLog.WriteLine("Reading Lead-in Copyright Information."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.HddvdCopyrightInformation, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.HDDVD_CPI, tmpBuf); } break; #endregion HD DVD-ROM #region All Blu-ray case MediaType.BDR: case MediaType.BDRE: case MediaType.BDROM: case MediaType.BDRXL: case MediaType.BDREXL: dumpLog.WriteLine("Reading Disc Information."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, MmcDiscStructureFormat.DiscInformation, 0, dev.Timeout, out _); if (!sense) { if (DI.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.BD_DI, tmpBuf); } } // TODO: PAC /* * dumpLog.WriteLine("Reading PAC."); * sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, * MmcDiscStructureFormat.Pac, 0, dev.Timeout, out _); * if(!sense) * { * tmpBuf = new byte[cmdBuf.Length - 4]; * Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); * mediaTags.Add(MediaTagType.PAC, tmpBuf); * }*/ break; #endregion All Blu-ray } switch (dskType) { #region BD-ROM only case MediaType.BDROM: dumpLog.WriteLine("Reading Burst Cutting Area."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, MmcDiscStructureFormat.BdBurstCuttingArea, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.BD_BCA, tmpBuf); } break; #endregion BD-ROM only #region Writable Blu-ray only case MediaType.BDR: case MediaType.BDRE: case MediaType.BDRXL: case MediaType.BDREXL: dumpLog.WriteLine("Reading Disc Definition Structure."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, MmcDiscStructureFormat.BdDds, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.BD_DDS, tmpBuf); } dumpLog.WriteLine("Reading Spare Area Information."); sense = dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Bd, 0, 0, MmcDiscStructureFormat.BdSpareAreaInformation, 0, dev.Timeout, out _); if (!sense) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.BD_SpareArea, tmpBuf); } break; #endregion Writable Blu-ray only } if (isXbox) { Xgd.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags, ref dskType, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions, preSidecar, skip, nometadata, notrim); return; } Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags, ref dskType, true, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions, preSidecar, skip, nometadata, notrim); }
public ImageInfoViewModel(string imagePath, IFilter filter, IMediaImage imageFormat, Window view) { _imagePath = imagePath; _filter = filter; _imageFormat = imageFormat; _view = view; IAssetLoader assets = AvaloniaLocator.Current.GetService <IAssetLoader>(); MediaTagsList = new ObservableCollection <string>(); SectorTagsList = new ObservableCollection <string>(); Sessions = new ObservableCollection <Session>(); Tracks = new ObservableCollection <Track>(); DumpHardwareList = new ObservableCollection <DumpHardwareModel>(); EntropyCommand = ReactiveCommand.Create(ExecuteEntropyCommand); VerifyCommand = ReactiveCommand.Create(ExecuteVerifyCommand); ChecksumCommand = ReactiveCommand.Create(ExecuteChecksumCommand); ConvertCommand = ReactiveCommand.Create(ExecuteConvertCommand); CreateSidecarCommand = ReactiveCommand.Create(ExecuteCreateSidecarCommand); ViewSectorsCommand = ReactiveCommand.Create(ExecuteViewSectorsCommand); DecodeMediaTagCommand = ReactiveCommand.Create(ExecuteDecodeMediaTagCommand); var genericHddIcon = new Bitmap(assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-harddisk.png"))); var genericOpticalIcon = new Bitmap(assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-optical.png"))); var genericFolderIcon = new Bitmap(assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/inode-directory.png"))); var mediaResource = new Uri($"avares://Aaru.Gui/Assets/Logos/Media/{imageFormat.Info.MediaType}.png"); MediaLogo = assets.Exists(mediaResource) ? new Bitmap(assets.Open(mediaResource)) : imageFormat.Info.XmlMediaType == XmlMediaType.BlockMedia ? genericHddIcon : imageFormat.Info.XmlMediaType == XmlMediaType.OpticalDisc ? genericOpticalIcon : genericFolderIcon; ImagePathText = $"Path: {imagePath}"; FilterText = $"Filter: {filter.Name}"; ImageIdentifiedText = $"Image format identified by {imageFormat.Name} ({imageFormat.Id})."; ImageFormatText = !string.IsNullOrWhiteSpace(imageFormat.Info.Version) ? $"Format: {imageFormat.Format} version {imageFormat.Info.Version}" : $"Format: {imageFormat.Format}"; ImageSizeText = $"Image without headers is {imageFormat.Info.ImageSize} bytes long"; SectorsText = $"Contains a media of {imageFormat.Info.Sectors} sectors with a maximum sector size of {imageFormat.Info.SectorSize} bytes (if all sectors are of the same size this would be {imageFormat.Info.Sectors * imageFormat.Info.SectorSize} bytes)"; MediaTypeText = $"Contains a media of type {imageFormat.Info.MediaType} and XML type {imageFormat.Info.XmlMediaType}"; HasPartitionsText = $"{(imageFormat.Info.HasPartitions ? "Has" : "Doesn't have")} partitions"; HasSessionsText = $"{(imageFormat.Info.HasSessions ? "Has" : "Doesn't have")} sessions"; if (!string.IsNullOrWhiteSpace(imageFormat.Info.Application)) { ApplicationText = !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion) ? $"Was created with {imageFormat.Info.Application} version {imageFormat.Info.ApplicationVersion}" : $"Was created with {imageFormat.Info.Application}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.Creator)) { CreatorText = $"Created by: {imageFormat.Info.Creator}"; } if (imageFormat.Info.CreationTime != DateTime.MinValue) { CreationTimeText = $"Created on {imageFormat.Info.CreationTime}"; } if (imageFormat.Info.LastModificationTime != DateTime.MinValue) { LastModificationTimeText = $"Last modified on {imageFormat.Info.LastModificationTime}"; } if (imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0) { MediaSequenceText = $"Media is number {imageFormat.Info.MediaSequence} on a set of {imageFormat.Info.LastMediaSequence} medias"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle)) { MediaTitleText = $"Media title: {imageFormat.Info.MediaTitle}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer)) { MediaManufacturerText = $"Media manufacturer: {imageFormat.Info.MediaManufacturer}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel)) { MediaModelText = $"Media model: {imageFormat.Info.MediaModel}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber)) { MediaSerialNumberText = $"Media serial number: {imageFormat.Info.MediaSerialNumber}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode)) { MediaBarcodeText = $"Media barcode: {imageFormat.Info.MediaBarcode}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber)) { MediaPartNumberText = $"Media part number: {imageFormat.Info.MediaPartNumber}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer)) { DriveManufacturerText = $"Drive manufacturer: {imageFormat.Info.DriveManufacturer}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel)) { DriveModelText = $"Drive model: {imageFormat.Info.DriveModel}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber)) { DriveSerialNumberText = $"Drive serial number: {imageFormat.Info.DriveSerialNumber}"; } if (!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision)) { DriveFirmwareRevisionText = $"Drive firmware info: {imageFormat.Info.DriveFirmwareRevision}"; } if (imageFormat.Info.Cylinders > 0 && imageFormat.Info.Heads > 0 && imageFormat.Info.SectorsPerTrack > 0 && imageFormat.Info.XmlMediaType != XmlMediaType.OpticalDisc && (!(imageFormat is ITapeImage tapeImage) || !tapeImage.IsTape)) { MediaGeometryText = $"Media geometry: {imageFormat.Info.Cylinders} cylinders, {imageFormat.Info.Heads} heads, {imageFormat.Info.SectorsPerTrack} sectors per track"; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Count > 0) { foreach (MediaTagType tag in imageFormat.Info.ReadableMediaTags.OrderBy(t => t)) { MediaTagsList.Add(tag.ToString()); } } if (imageFormat.Info.ReadableSectorTags != null && imageFormat.Info.ReadableSectorTags.Count > 0) { foreach (SectorTagType tag in imageFormat.Info.ReadableSectorTags.OrderBy(t => t)) { SectorTagsList.Add(tag.ToString()); } } PeripheralDeviceTypes scsiDeviceType = PeripheralDeviceTypes.DirectAccess; byte[] scsiInquiryData = null; Inquiry?scsiInquiry = null; Modes.DecodedMode?scsiMode = null; byte[] scsiModeSense6 = null; byte[] scsiModeSense10 = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_INQUIRY)) { scsiInquiryData = imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY); scsiDeviceType = (PeripheralDeviceTypes)(scsiInquiryData[0] & 0x1F); scsiInquiry = Inquiry.Decode(scsiInquiryData); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6)) { scsiModeSense6 = imageFormat.ReadDiskTag(MediaTagType.SCSI_MODESENSE_6); scsiMode = Modes.DecodeMode6(scsiModeSense6, scsiDeviceType); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10)) { scsiModeSense10 = imageFormat.ReadDiskTag(MediaTagType.SCSI_MODESENSE_10); scsiMode = Modes.DecodeMode10(scsiModeSense10, scsiDeviceType); } ScsiInfo = new ScsiInfo { DataContext = new ScsiInfoViewModel(scsiInquiryData, scsiInquiry, null, scsiMode, scsiDeviceType, scsiModeSense6, scsiModeSense10, null, _view) }; byte[] ataIdentify = null; byte[] atapiIdentify = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) { ataIdentify = imageFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY)) { atapiIdentify = imageFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY); } AtaInfo = new AtaInfo { DataContext = new AtaInfoViewModel(ataIdentify, atapiIdentify, null, _view) }; byte[] toc = null; TOC.CDTOC? decodedToc = null; byte[] fullToc = null; FullTOC.CDFullTOC? decodedFullToc = null; byte[] pma = null; byte[] atip = null; ATIP.CDATIP? decodedAtip = null; byte[] cdtext = null; CDTextOnLeadIn.CDText?decodedCdText = null; string mediaCatalogueNumber = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_TOC)) { toc = imageFormat.ReadDiskTag(MediaTagType.CD_TOC); if (toc.Length > 0) { ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(toc, 0)); if (dataLen + 2 != toc.Length) { byte[] tmp = new byte[toc.Length + 2]; Array.Copy(toc, 0, tmp, 2, toc.Length); tmp[0] = (byte)((toc.Length & 0xFF00) >> 8); tmp[1] = (byte)(toc.Length & 0xFF); toc = tmp; } decodedToc = TOC.Decode(toc); } } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_FullTOC)) { fullToc = imageFormat.ReadDiskTag(MediaTagType.CD_FullTOC); if (fullToc.Length > 0) { ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(fullToc, 0)); if (dataLen + 2 != fullToc.Length) { byte[] tmp = new byte[fullToc.Length + 2]; Array.Copy(fullToc, 0, tmp, 2, fullToc.Length); tmp[0] = (byte)((fullToc.Length & 0xFF00) >> 8); tmp[1] = (byte)(fullToc.Length & 0xFF); fullToc = tmp; } decodedFullToc = FullTOC.Decode(fullToc); } } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_PMA)) { pma = imageFormat.ReadDiskTag(MediaTagType.CD_PMA); if (pma.Length > 0) { ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(pma, 0)); if (dataLen + 2 != pma.Length) { byte[] tmp = new byte[pma.Length + 2]; Array.Copy(pma, 0, tmp, 2, pma.Length); tmp[0] = (byte)((pma.Length & 0xFF00) >> 8); tmp[1] = (byte)(pma.Length & 0xFF); pma = tmp; } } } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_ATIP)) { atip = imageFormat.ReadDiskTag(MediaTagType.CD_ATIP); uint dataLen = Swapping.Swap(BitConverter.ToUInt32(atip, 0)); if (dataLen + 4 != atip.Length) { byte[] tmp = new byte[atip.Length + 4]; Array.Copy(atip, 0, tmp, 4, atip.Length); tmp[0] = (byte)((atip.Length & 0xFF000000) >> 24); tmp[1] = (byte)((atip.Length & 0xFF0000) >> 16); tmp[2] = (byte)((atip.Length & 0xFF00) >> 8); tmp[3] = (byte)(atip.Length & 0xFF); atip = tmp; } decodedAtip = ATIP.Decode(atip); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_TEXT)) { cdtext = imageFormat.ReadDiskTag(MediaTagType.CD_TEXT); uint dataLen = Swapping.Swap(BitConverter.ToUInt32(cdtext, 0)); if (dataLen + 4 != cdtext.Length) { byte[] tmp = new byte[cdtext.Length + 4]; Array.Copy(cdtext, 0, tmp, 4, cdtext.Length); tmp[0] = (byte)((cdtext.Length & 0xFF000000) >> 24); tmp[1] = (byte)((cdtext.Length & 0xFF0000) >> 16); tmp[2] = (byte)((cdtext.Length & 0xFF00) >> 8); tmp[3] = (byte)(cdtext.Length & 0xFF); cdtext = tmp; } decodedCdText = CDTextOnLeadIn.Decode(cdtext); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.CD_MCN)) { byte[] mcn = imageFormat.ReadDiskTag(MediaTagType.CD_MCN); mediaCatalogueNumber = Encoding.UTF8.GetString(mcn); } CompactDiscInfo = new CompactDiscInfo { DataContext = new CompactDiscInfoViewModel(toc, atip, null, null, fullToc, pma, cdtext, decodedToc, decodedAtip, null, decodedFullToc, decodedCdText, null, mediaCatalogueNumber, null, _view) }; byte[] dvdPfi = null; byte[] dvdDmi = null; byte[] dvdCmi = null; byte[] hddvdCopyrightInformation = null; byte[] dvdBca = null; PFI.PhysicalFormatInformation?decodedPfi = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_PFI)) { dvdPfi = imageFormat.ReadDiskTag(MediaTagType.DVD_PFI); decodedPfi = PFI.Decode(dvdPfi); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_DMI)) { dvdDmi = imageFormat.ReadDiskTag(MediaTagType.DVD_DMI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_CMI)) { dvdCmi = imageFormat.ReadDiskTag(MediaTagType.DVD_CMI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.HDDVD_CPI)) { hddvdCopyrightInformation = imageFormat.ReadDiskTag(MediaTagType.HDDVD_CPI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_BCA)) { dvdBca = imageFormat.ReadDiskTag(MediaTagType.DVD_BCA); } DvdInfo = new DvdInfo { DataContext = new DvdInfoViewModel(imageFormat.Info.MediaType, dvdPfi, dvdDmi, dvdCmi, hddvdCopyrightInformation, dvdBca, null, decodedPfi, _view) }; byte[] dvdRamDds = null; byte[] dvdRamCartridgeStatus = null; byte[] dvdRamSpareArea = null; byte[] lastBorderOutRmd = null; byte[] dvdPreRecordedInfo = null; byte[] dvdrMediaIdentifier = null; byte[] dvdrPhysicalInformation = null; byte[] hddvdrMediumStatus = null; byte[] dvdrLayerCapacity = null; byte[] dvdrDlMiddleZoneStart = null; byte[] dvdrDlJumpIntervalSize = null; byte[] dvdrDlManualLayerJumpStartLba = null; byte[] dvdPlusAdip = null; byte[] dvdPlusDcb = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_DDS)) { dvdRamDds = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_DDS); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_MediumStatus)) { dvdRamCartridgeStatus = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_MediumStatus); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDRAM_SpareArea)) { dvdRamSpareArea = imageFormat.ReadDiskTag(MediaTagType.DVDRAM_SpareArea); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_RMD)) { lastBorderOutRmd = imageFormat.ReadDiskTag(MediaTagType.DVDR_RMD); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_PreRecordedInfo)) { dvdPreRecordedInfo = imageFormat.ReadDiskTag(MediaTagType.DVDR_PreRecordedInfo); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_MediaIdentifier)) { dvdrMediaIdentifier = imageFormat.ReadDiskTag(MediaTagType.DVDR_MediaIdentifier); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDR_PFI)) { dvdrPhysicalInformation = imageFormat.ReadDiskTag(MediaTagType.DVDR_PFI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.HDDVD_MediumStatus)) { hddvdrMediumStatus = imageFormat.ReadDiskTag(MediaTagType.HDDVD_MediumStatus); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_LayerCapacity)) { dvdrLayerCapacity = imageFormat.ReadDiskTag(MediaTagType.DVDDL_LayerCapacity); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_MiddleZoneAddress)) { dvdrDlMiddleZoneStart = imageFormat.ReadDiskTag(MediaTagType.DVDDL_MiddleZoneAddress); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_JumpIntervalSize)) { dvdrDlJumpIntervalSize = imageFormat.ReadDiskTag(MediaTagType.DVDDL_JumpIntervalSize); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVDDL_ManualLayerJumpLBA)) { dvdrDlManualLayerJumpStartLba = imageFormat.ReadDiskTag(MediaTagType.DVDDL_ManualLayerJumpLBA); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DVD_ADIP)) { dvdPlusAdip = imageFormat.ReadDiskTag(MediaTagType.DVD_ADIP); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.DCB)) { dvdPlusDcb = imageFormat.ReadDiskTag(MediaTagType.DCB); } DvdWritableInfo = new DvdWritableInfo { DataContext = new DvdWritableInfoViewModel(imageFormat.Info.MediaType, dvdRamDds, dvdRamCartridgeStatus, dvdRamSpareArea, lastBorderOutRmd, dvdPreRecordedInfo, dvdrMediaIdentifier, dvdrPhysicalInformation, hddvdrMediumStatus, null, dvdrLayerCapacity, dvdrDlMiddleZoneStart, dvdrDlJumpIntervalSize, dvdrDlManualLayerJumpStartLba, null, dvdPlusAdip, dvdPlusDcb, _view) }; byte[] blurayBurstCuttingArea = null; byte[] blurayCartridgeStatus = null; byte[] blurayDds = null; byte[] blurayDiscInformation = null; byte[] blurayPowResources = null; byte[] bluraySpareAreaInformation = null; byte[] blurayTrackResources = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_BCA)) { blurayBurstCuttingArea = imageFormat.ReadDiskTag(MediaTagType.BD_BCA); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_CartridgeStatus)) { blurayCartridgeStatus = imageFormat.ReadDiskTag(MediaTagType.BD_CartridgeStatus); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_DDS)) { blurayDds = imageFormat.ReadDiskTag(MediaTagType.BD_DDS); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_DI)) { blurayDiscInformation = imageFormat.ReadDiskTag(MediaTagType.BD_DI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_POWResourcesInformation)) { blurayPowResources = imageFormat.ReadDiskTag(MediaTagType.MMC_POWResourcesInformation); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.BD_SpareArea)) { bluraySpareAreaInformation = imageFormat.ReadDiskTag(MediaTagType.BD_SpareArea); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_TrackResourcesInformation)) { bluraySpareAreaInformation = imageFormat.ReadDiskTag(MediaTagType.MMC_TrackResourcesInformation); } BlurayInfo = new BlurayInfo { DataContext = new BlurayInfoViewModel(blurayDiscInformation, blurayBurstCuttingArea, blurayDds, blurayCartridgeStatus, bluraySpareAreaInformation, blurayPowResources, blurayTrackResources, null, null, _view) }; byte[] xboxDmi = null; byte[] xboxSecuritySector = null; SS.SecuritySector?decodedXboxSecuritySector = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.Xbox_DMI)) { xboxDmi = imageFormat.ReadDiskTag(MediaTagType.Xbox_DMI); } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.Xbox_SecuritySector)) { xboxSecuritySector = imageFormat.ReadDiskTag(MediaTagType.Xbox_SecuritySector); decodedXboxSecuritySector = SS.Decode(xboxSecuritySector); } XboxInfo = new XboxInfo { DataContext = new XboxInfoViewModel(null, xboxDmi, xboxSecuritySector, decodedXboxSecuritySector, _view) }; byte[] pcmciaCis = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.PCMCIA_CIS)) { pcmciaCis = imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS); } PcmciaInfo = new PcmciaInfo { DataContext = new PcmciaInfoViewModel(pcmciaCis, _view) }; DeviceType deviceType = DeviceType.Unknown; byte[] cid = null; byte[] csd = null; byte[] ocr = null; byte[] extendedCsd = null; byte[] scr = null; if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_CID)) { cid = imageFormat.ReadDiskTag(MediaTagType.SD_CID); deviceType = DeviceType.SecureDigital; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_CSD)) { csd = imageFormat.ReadDiskTag(MediaTagType.SD_CSD); deviceType = DeviceType.SecureDigital; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_OCR)) { ocr = imageFormat.ReadDiskTag(MediaTagType.SD_OCR); deviceType = DeviceType.SecureDigital; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.SD_SCR)) { scr = imageFormat.ReadDiskTag(MediaTagType.SD_SCR); deviceType = DeviceType.SecureDigital; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_CID)) { cid = imageFormat.ReadDiskTag(MediaTagType.MMC_CID); deviceType = DeviceType.MMC; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_CSD)) { csd = imageFormat.ReadDiskTag(MediaTagType.MMC_CSD); deviceType = DeviceType.MMC; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_OCR)) { ocr = imageFormat.ReadDiskTag(MediaTagType.MMC_OCR); deviceType = DeviceType.MMC; } if (imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Contains(MediaTagType.MMC_ExtendedCSD)) { extendedCsd = imageFormat.ReadDiskTag(MediaTagType.MMC_ExtendedCSD); deviceType = DeviceType.MMC; } SdMmcInfo = new SdMmcInfo { DataContext = new SdMmcInfoViewModel(deviceType, cid, csd, ocr, extendedCsd, scr) }; if (imageFormat is IOpticalMediaImage opticalMediaImage) { try { if (opticalMediaImage.Sessions != null && opticalMediaImage.Sessions.Count > 0) { foreach (Session session in opticalMediaImage.Sessions) { Sessions.Add(session); } } } catch { // ignored } try { if (opticalMediaImage.Tracks != null && opticalMediaImage.Tracks.Count > 0) { foreach (Track track in opticalMediaImage.Tracks) { Tracks.Add(track); } } } catch { // ignored } } if (imageFormat.DumpHardware is null) { return; } foreach (DumpHardwareType dump in imageFormat.DumpHardware) { foreach (ExtentType extent in dump.Extents) { DumpHardwareList.Add(new DumpHardwareModel { Manufacturer = dump.Manufacturer, Model = dump.Model, Serial = dump.Serial, SoftwareName = dump.Software.Name, SoftwareVersion = dump.Software.Version, OperatingSystem = dump.Software.OperatingSystem, Start = extent.Start, End = extent.End }); } } }
/// <summary>Dumps an optical disc</summary> void Mmc() { MediaType dskType = MediaType.Unknown; bool sense; byte[] tmpBuf; bool compactDisc = true; bool gotConfiguration = false; bool isXbox = false; DVDDecryption dvdDecrypt = null; _speedMultiplier = 1; // TODO: Log not only what is it reading, but if it was read correctly or not. sense = _dev.GetConfiguration(out byte[] cmdBuf, out _, 0, MmcGetConfigurationRt.Current, _dev.Timeout, out _); if (!sense) { gotConfiguration = true; Features.SeparatedFeatures ftr = Features.Separate(cmdBuf); _dumpLog.WriteLine("Device reports current profile is 0x{0:X4}", ftr.CurrentProfile); switch (ftr.CurrentProfile) { case 0x0001: dskType = MediaType.GENERIC_HDD; _speedMultiplier = -1; goto default; case 0x0002: dskType = MediaType.PD650; _speedMultiplier = -1; goto default; case 0x0005: dskType = MediaType.CDMO; break; case 0x0008: dskType = MediaType.CD; break; case 0x0009: dskType = MediaType.CDR; break; case 0x000A: dskType = MediaType.CDRW; break; case 0x0010: dskType = MediaType.DVDROM; _speedMultiplier = 9; goto default; case 0x0011: dskType = MediaType.DVDR; _speedMultiplier = 9; goto default; case 0x0012: dskType = MediaType.DVDRAM; _speedMultiplier = 9; goto default; case 0x0013: case 0x0014: dskType = MediaType.DVDRW; _speedMultiplier = 9; goto default; case 0x0015: case 0x0016: dskType = MediaType.DVDRDL; _speedMultiplier = 9; goto default; case 0x0017: dskType = MediaType.DVDRWDL; _speedMultiplier = 9; goto default; case 0x0018: dskType = MediaType.DVDDownload; _speedMultiplier = 9; goto default; case 0x001A: dskType = MediaType.DVDPRW; _speedMultiplier = 9; goto default; case 0x001B: dskType = MediaType.DVDPR; _speedMultiplier = 9; goto default; case 0x0020: dskType = MediaType.DDCD; goto default; case 0x0021: dskType = MediaType.DDCDR; goto default; case 0x0022: dskType = MediaType.DDCDRW; goto default; case 0x002A: dskType = MediaType.DVDPRWDL; _speedMultiplier = 9; goto default; case 0x002B: dskType = MediaType.DVDPRDL; _speedMultiplier = 9; goto default; case 0x0040: dskType = MediaType.BDROM; _speedMultiplier = 30; goto default; case 0x0041: case 0x0042: dskType = MediaType.BDR; _speedMultiplier = 30; goto default; case 0x0043: dskType = MediaType.BDRE; _speedMultiplier = 30; goto default; case 0x0050: dskType = MediaType.HDDVDROM; _speedMultiplier = 30; goto default; case 0x0051: dskType = MediaType.HDDVDR; _speedMultiplier = 30; goto default; case 0x0052: dskType = MediaType.HDDVDRAM; _speedMultiplier = 30; goto default; case 0x0053: dskType = MediaType.HDDVDRW; _speedMultiplier = 30; goto default; case 0x0058: dskType = MediaType.HDDVDRDL; _speedMultiplier = 30; goto default; case 0x005A: dskType = MediaType.HDDVDRWDL; _speedMultiplier = 30; goto default; default: compactDisc = false; break; } } Modes.DecodedMode?decMode = null; sense = _dev.ModeSense6(out cmdBuf, out _, true, ScsiModeSensePageControl.Current, 0x00, _dev.Timeout, out _); if (sense || _dev.Error) { sense = _dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x00, _dev.Timeout, out _); if (!sense && !_dev.Error) { decMode = Modes.DecodeMode6(cmdBuf, PeripheralDeviceTypes.MultiMediaDevice); } } else { decMode = Modes.DecodeMode6(cmdBuf, PeripheralDeviceTypes.MultiMediaDevice); } if (decMode is null) { sense = _dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, _dev.Timeout, out _); if (sense || _dev.Error) { sense = _dev.ModeSense10(out cmdBuf, out _, false, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, _dev.Timeout, out _); if (sense || _dev.Error) { sense = _dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current, 0x00, 0x00, _dev.Timeout, out _); if (sense || _dev.Error) { sense = _dev.ModeSense10(out cmdBuf, out _, false, false, ScsiModeSensePageControl.Current, 0x00, 0x00, _dev.Timeout, out _); if (!sense && !_dev.Error) { decMode = Modes.DecodeMode10(cmdBuf, PeripheralDeviceTypes.MultiMediaDevice); } } else { decMode = Modes.DecodeMode10(cmdBuf, PeripheralDeviceTypes.MultiMediaDevice); } } else { decMode = Modes.DecodeMode10(cmdBuf, PeripheralDeviceTypes.MultiMediaDevice); } } else { decMode = Modes.DecodeMode10(cmdBuf, PeripheralDeviceTypes.MultiMediaDevice); } } if (decMode.HasValue && _dev.IsUsb && !gotConfiguration && (decMode.Value.Header.MediumType == MediumTypes.UnknownBlockDevice || decMode.Value.Header.MediumType == MediumTypes.ReadOnlyBlockDevice || decMode.Value.Header.MediumType == MediumTypes.ReadWriteBlockDevice)) { _speedMultiplier = -1; Sbc(null, MediaType.Unknown, false); return; } if (compactDisc) { _speedMultiplier *= 177; CompactDisc(); return; } _speedMultiplier *= 150; var scsiReader = new Reader(_dev, _dev.Timeout, null, _errorLog, _dumpRaw); ulong blocks = scsiReader.GetDeviceBlocks(); _dumpLog.WriteLine("Device reports disc has {0} blocks", blocks); Dictionary <MediaTagType, byte[]> mediaTags = new Dictionary <MediaTagType, byte[]>(); if (dskType == MediaType.PD650) { switch (blocks + 1) { case 1281856: dskType = MediaType.PD650_WORM; break; case 58620544: dskType = MediaType.REV120; break; case 17090880: dskType = MediaType.REV35; break; case 34185728: dskType = MediaType.REV70; break; } } #region Nintendo switch (dskType) { case MediaType.Unknown when blocks > 0: _dumpLog.WriteLine("Reading Physical Format Information"); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _); if (!sense) { PFI.PhysicalFormatInformation?nintendoPfi = PFI.Decode(cmdBuf); if (nintendoPfi?.DiskCategory == DiskCategory.Nintendo && nintendoPfi.Value.PartVersion == 15) { _dumpLog.WriteLine("Dumping Nintendo GameCube or Wii discs is not yet implemented."); StoppingErrorMessage?. Invoke("Dumping Nintendo GameCube or Wii discs is not yet implemented."); return; } } break; case MediaType.DVDDownload: case MediaType.DVDPR: case MediaType.DVDPRDL: case MediaType.DVDPRW: case MediaType.DVDPRWDL: case MediaType.DVDR: case MediaType.DVDRAM: case MediaType.DVDRDL: case MediaType.DVDROM: case MediaType.DVDRW: case MediaType.DVDRWDL: case MediaType.HDDVDR: case MediaType.HDDVDRAM: case MediaType.HDDVDRDL: case MediaType.HDDVDROM: case MediaType.HDDVDRW: case MediaType.HDDVDRWDL: _dumpLog.WriteLine("Reading Physical Format Information"); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, _dev.Timeout, out _); if (!sense) { if (PFI.Decode(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_PFI, tmpBuf); PFI.PhysicalFormatInformation decPfi = PFI.Decode(cmdBuf).Value; UpdateStatus?.Invoke($"PFI:\n{PFI.Prettify(decPfi)}"); // False book types switch (decPfi.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 = decPfi.PartVersion >= 6 ? MediaType.DVDRDL : MediaType.DVDR; break; case DiskCategory.DVDRAM: dskType = MediaType.DVDRAM; break; default: dskType = MediaType.DVDROM; break; case DiskCategory.DVDRW: dskType = decPfi.PartVersion >= 15 ? MediaType.DVDRWDL : 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 = decPfi.DiscSize == DVDSize.Eighty ? MediaType.GOD : MediaType.WOD; break; case DiskCategory.UMD: dskType = MediaType.UMD; break; } } } _dumpLog.WriteLine("Reading Disc Manufacturing Information"); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, _dev.Timeout, out _); if (!sense) { if (DMI.IsXbox(cmdBuf) || DMI.IsXbox360(cmdBuf)) { if (DMI.IsXbox(cmdBuf)) { dskType = MediaType.XGD; } else if (DMI.IsXbox360(cmdBuf)) { dskType = MediaType.XGD2; // All XGD3 all have the same number of blocks if (blocks + 1 == 25063 || // Locked (or non compatible drive) blocks + 1 == 4229664 || // Xtreme unlock blocks + 1 == 4246304) // Wxripper unlock { dskType = MediaType.XGD3; } } isXbox = true; sense = _dev.ScsiInquiry(out byte[] inqBuf, out _); if (sense || !Inquiry.Decode(inqBuf).HasValue || (Inquiry.Decode(inqBuf).HasValue&& !Inquiry.Decode(inqBuf).Value.KreonPresent)) { _dumpLog.WriteLine("Dumping Xbox Game Discs requires a drive with Kreon firmware."); StoppingErrorMessage?. Invoke("Dumping Xbox Game Discs requires a drive with Kreon firmware."); if (!_force) { return; } isXbox = false; } if (_dumpRaw && !_force) { StoppingErrorMessage?. Invoke("Not continuing. If you want to continue reading cooked data when raw is not available use the force option."); // TODO: Exit more gracefully return; } } if (cmdBuf.Length == 2052) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_DMI, tmpBuf); } } break; } #endregion Nintendo #region All DVD and HD DVD types #endregion All DVD and HD DVD types #region DVD-ROM if (dskType == MediaType.DVDDownload || dskType == MediaType.DVDROM) { _dumpLog.WriteLine("Reading Lead-in Copyright Information."); sense = _dev.ReadDiscStructure(out cmdBuf, out _, MmcDiscStructureMediaType.Dvd, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, _dev.Timeout, out _); if (!sense) { if (CSS_CPRM.DecodeLeadInCopyright(cmdBuf).HasValue) { tmpBuf = new byte[cmdBuf.Length - 4]; Array.Copy(cmdBuf, 4, tmpBuf, 0, cmdBuf.Length - 4); mediaTags.Add(MediaTagType.DVD_CMI, tmpBuf); CSS_CPRM.LeadInCopyright?cmi = CSS_CPRM.DecodeLeadInCopyright(cmdBuf); if (cmi !.Value.CopyrightType == CopyrightType.NoProtection) { UpdateStatus?.Invoke("Drive reports no copy protection on disc."); } else { if (!Settings.Settings.Current.EnableDecryption) { UpdateStatus?.Invoke("Drive reports the disc uses copy protection. " + "The dump will be incorrect unless decryption is enabled."); } else { if (cmi !.Value.CopyrightType == CopyrightType.CSS) { UpdateStatus?.Invoke("Drive reports disc uses CSS copy protection."); dvdDecrypt = new DVDDecryption(_dev); sense = dvdDecrypt.ReadBusKey(out cmdBuf, out _, CSS_CPRM.DecodeLeadInCopyright(cmdBuf) !.Value. CopyrightType, _dev.Timeout, out _); if (!sense) { byte[] busKey = cmdBuf; UpdateStatus?.Invoke("Reading disc key."); sense = dvdDecrypt.ReadDiscKey(out cmdBuf, out _, _dev.Timeout, out _); if (!sense) { CSS_CPRM.DiscKey?decodedDiscKey = CSS.DecodeDiscKey(cmdBuf, busKey); sense = dvdDecrypt.ReadAsf(out cmdBuf, out _, DvdCssKeyClass.DvdCssCppmOrCprm, _dev.Timeout, out _); if (!sense) { if (cmdBuf[7] == 1) { UpdateStatus?.Invoke("Disc and drive authentication succeeded."); sense = dvdDecrypt.ReadRpc(out cmdBuf, out _, DvdCssKeyClass.DvdCssCppmOrCprm, _dev.Timeout, out _); if (!sense) { CSS_CPRM.RegionalPlaybackControlState?rpc = CSS_CPRM.DecodeRegionalPlaybackControlState(cmdBuf); if (rpc.HasValue) { UpdateStatus?.Invoke(CSS.CheckRegion(rpc.Value, cmi.Value) ? "Disc and drive regions match." : "Disc and drive regions do not match. The dump will be incorrect"); } } if (decodedDiscKey.HasValue) { mediaTags.Add(MediaTagType.DVD_DiscKey, decodedDiscKey.Value.Key); UpdateStatus?.Invoke("Decrypting disc key."); CSS.DecryptDiscKey(decodedDiscKey.Value.Key, out byte[] discKey); if (discKey != null) { UpdateStatus?.Invoke("Decryption of disc key succeeded."); mediaTags.Add(MediaTagType.DVD_DiscKey_Decrypted, discKey); } else { UpdateStatus?.Invoke("Decryption of disc key failed."); } } } } } } } else { UpdateStatus?. Invoke($"Drive reports disc uses {CSS_CPRM.DecodeLeadInCopyright(cmdBuf)!.Value.CopyrightType.ToString()} copy protection. " + "This is not yet supported and the dump will be incorrect."); } } }