// /*************************************************************************** // The Disc Image Chef // ---------------------------------------------------------------------------- // // Filename : MMC.cs // Version : 1.0 // Author(s) : Natalia Portillo // // Component : Component // // Revision : $Revision$ // Last change by : $Author$ // Date : $Date$ // // --[ Description ] ---------------------------------------------------------- // // Description // // --[ License ] -------------------------------------------------------------- // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // ---------------------------------------------------------------------------- // Copyright (C) 2011-2015 Claunia.com // ****************************************************************************/ // //$Id$ using System; using System.Collections.Generic; using System.IO; using DiscImageChef.Console; using DiscImageChef.Devices; using DiscImageChef.Metadata; namespace DiscImageChef.Core.Devices.Report.SCSI { internal static class MMC { internal static void Report(Device dev, ref DeviceReport report, bool debug, ref Decoders.SCSI.Modes.ModePage_2A? cdromMode, ref List mediaTypes) { if(report == null) return; byte[] senseBuffer; byte[] buffer; double duration; bool sense; uint timeout = 5; ConsoleKeyInfo pressedKey; Decoders.SCSI.Modes.DecodedMode? decMode = null; report.SCSI.MultiMediaDevice = new mmcType(); if(cdromMode.HasValue) { report.SCSI.MultiMediaDevice.ModeSense2A = new mmcModeType(); if(cdromMode.Value.BufferSize != 0) { report.SCSI.MultiMediaDevice.ModeSense2A.BufferSize = cdromMode.Value.BufferSize; report.SCSI.MultiMediaDevice.ModeSense2A.BufferSizeSpecified = true; } if(cdromMode.Value.CurrentSpeed != 0) { report.SCSI.MultiMediaDevice.ModeSense2A.CurrentSpeed = cdromMode.Value.CurrentSpeed; report.SCSI.MultiMediaDevice.ModeSense2A.CurrentSpeedSpecified = true; } if(cdromMode.Value.CurrentWriteSpeed != 0) { report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeed = cdromMode.Value.CurrentWriteSpeed; report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSpecified = true; } if(cdromMode.Value.CurrentWriteSpeedSelected != 0) { report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSelected = cdromMode.Value.CurrentWriteSpeedSelected; report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSelectedSpecified = true; } if(cdromMode.Value.MaximumSpeed != 0) { report.SCSI.MultiMediaDevice.ModeSense2A.MaximumSpeed = cdromMode.Value.MaximumSpeed; report.SCSI.MultiMediaDevice.ModeSense2A.MaximumSpeedSpecified = true; } if(cdromMode.Value.MaxWriteSpeed != 0) { report.SCSI.MultiMediaDevice.ModeSense2A.MaximumWriteSpeed = cdromMode.Value.MaxWriteSpeed; report.SCSI.MultiMediaDevice.ModeSense2A.MaximumWriteSpeedSpecified = true; } if(cdromMode.Value.RotationControlSelected != 0) { report.SCSI.MultiMediaDevice.ModeSense2A.RotationControlSelected = cdromMode.Value.RotationControlSelected; report.SCSI.MultiMediaDevice.ModeSense2A.RotationControlSelectedSpecified = true; } if(cdromMode.Value.SupportedVolumeLevels != 0) { report.SCSI.MultiMediaDevice.ModeSense2A.SupportedVolumeLevels = cdromMode.Value.SupportedVolumeLevels; report.SCSI.MultiMediaDevice.ModeSense2A.SupportedVolumeLevelsSpecified = true; } report.SCSI.MultiMediaDevice.ModeSense2A.AccurateCDDA = cdromMode.Value.AccurateCDDA; report.SCSI.MultiMediaDevice.ModeSense2A.BCK = cdromMode.Value.BCK; report.SCSI.MultiMediaDevice.ModeSense2A.BufferUnderRunProtection = cdromMode.Value.BUF; report.SCSI.MultiMediaDevice.ModeSense2A.CanEject = cdromMode.Value.Eject; report.SCSI.MultiMediaDevice.ModeSense2A.CanLockMedia = cdromMode.Value.Lock; report.SCSI.MultiMediaDevice.ModeSense2A.CDDACommand = cdromMode.Value.CDDACommand; report.SCSI.MultiMediaDevice.ModeSense2A.CompositeAudioVideo = cdromMode.Value.Composite; report.SCSI.MultiMediaDevice.ModeSense2A.CSSandCPPMSupported = cdromMode.Value.CMRSupported == 1; report.SCSI.MultiMediaDevice.ModeSense2A.DeterministicSlotChanger = cdromMode.Value.SDP; report.SCSI.MultiMediaDevice.ModeSense2A.DigitalPort1 = cdromMode.Value.DigitalPort1; report.SCSI.MultiMediaDevice.ModeSense2A.DigitalPort2 = cdromMode.Value.DigitalPort2; report.SCSI.MultiMediaDevice.ModeSense2A.LeadInPW = cdromMode.Value.LeadInPW; report.SCSI.MultiMediaDevice.ModeSense2A.LoadingMechanismType = cdromMode.Value.LoadingMechanism; report.SCSI.MultiMediaDevice.ModeSense2A.LockStatus = cdromMode.Value.LockState; report.SCSI.MultiMediaDevice.ModeSense2A.LSBF = cdromMode.Value.LSBF; report.SCSI.MultiMediaDevice.ModeSense2A.PlaysAudio = cdromMode.Value.AudioPlay; report.SCSI.MultiMediaDevice.ModeSense2A.PreventJumperStatus = cdromMode.Value.PreventJumper; report.SCSI.MultiMediaDevice.ModeSense2A.RCK = cdromMode.Value.RCK; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsBarcode = cdromMode.Value.ReadBarcode; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsBothSides = cdromMode.Value.SCC; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsCDR = cdromMode.Value.ReadCDR; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsCDRW = cdromMode.Value.ReadCDRW; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDeinterlavedSubchannel = cdromMode.Value.DeinterlaveSubchannel; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDR = cdromMode.Value.ReadDVDR; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDRAM = cdromMode.Value.ReadDVDRAM; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDROM = cdromMode.Value.ReadDVDROM; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsISRC = cdromMode.Value.ISRC; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsMode2Form2 = cdromMode.Value.Mode2Form2; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsMode2Form1 = cdromMode.Value.Mode2Form1; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsPacketCDR = cdromMode.Value.Method2; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsSubchannel = cdromMode.Value.Subchannel; report.SCSI.MultiMediaDevice.ModeSense2A.ReadsUPC = cdromMode.Value.UPC; report.SCSI.MultiMediaDevice.ModeSense2A.ReturnsC2Pointers = cdromMode.Value.C2Pointer; report.SCSI.MultiMediaDevice.ModeSense2A.SeparateChannelMute = cdromMode.Value.SeparateChannelMute; report.SCSI.MultiMediaDevice.ModeSense2A.SeparateChannelVolume = cdromMode.Value.SeparateChannelVolume; report.SCSI.MultiMediaDevice.ModeSense2A.SSS = cdromMode.Value.SSS; report.SCSI.MultiMediaDevice.ModeSense2A.SupportsMultiSession = cdromMode.Value.MultiSession; report.SCSI.MultiMediaDevice.ModeSense2A.TestWrite = cdromMode.Value.TestWrite; report.SCSI.MultiMediaDevice.ModeSense2A.WritesCDR = cdromMode.Value.WriteCDR; report.SCSI.MultiMediaDevice.ModeSense2A.WritesCDRW = cdromMode.Value.WriteCDRW; report.SCSI.MultiMediaDevice.ModeSense2A.WritesDVDR = cdromMode.Value.WriteDVDR; report.SCSI.MultiMediaDevice.ModeSense2A.WritesDVDRAM = cdromMode.Value.WriteDVDRAM; report.SCSI.MultiMediaDevice.ModeSense2A.WriteSpeedPerformanceDescriptors = cdromMode.Value.WriteSpeedPerformanceDescriptors; mediaTypes.Add("CD-ROM"); mediaTypes.Add("Audio CD"); if(cdromMode.Value.ReadCDR) mediaTypes.Add("CD-R"); if(cdromMode.Value.ReadCDRW) mediaTypes.Add("CD-RW"); if(cdromMode.Value.ReadDVDROM) mediaTypes.Add("DVD-ROM"); if(cdromMode.Value.ReadDVDRAM) mediaTypes.Add("DVD-RAM"); if(cdromMode.Value.ReadDVDR) mediaTypes.Add("DVD-R"); } DicConsole.WriteLine("Querying MMC GET CONFIGURATION..."); sense = dev.GetConfiguration(out buffer, out senseBuffer, timeout, out duration); if(!sense) { Decoders.SCSI.MMC.Features.SeparatedFeatures ftr = Decoders.SCSI.MMC.Features.Separate(buffer); if(ftr.Descriptors != null && ftr.Descriptors.Length > 0) { report.SCSI.MultiMediaDevice.Features = new mmcFeaturesType(); foreach(Decoders.SCSI.MMC.Features.FeatureDescriptor desc in ftr.Descriptors) { switch(desc.Code) { case 0x0001: { Decoders.SCSI.MMC.Feature_0001? ftr0001 = Decoders.SCSI.MMC.Features.Decode_0001(desc.Data); if(ftr0001.HasValue) { report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandard = ftr0001.Value.PhysicalInterfaceStandard; report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandardSpecified = true; if((uint)ftr0001.Value.PhysicalInterfaceStandard > 0x8) { report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandardNumber = (uint)ftr0001.Value.PhysicalInterfaceStandard; report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandardNumberSpecified = true; report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandard = Decoders.SCSI.MMC.PhysicalInterfaces.Unspecified; } report.SCSI.MultiMediaDevice.Features.SupportsDeviceBusyEvent = ftr0001.Value.DBE; } } break; case 0x0003: { Decoders.SCSI.MMC.Feature_0003? ftr0003 = Decoders.SCSI.MMC.Features.Decode_0003(desc.Data); if(ftr0003.HasValue) { report.SCSI.MultiMediaDevice.Features.LoadingMechanismType = ftr0003.Value.LoadingMechanismType; report.SCSI.MultiMediaDevice.Features.LoadingMechanismTypeSpecified = true; report.SCSI.MultiMediaDevice.Features.CanLoad = ftr0003.Value.Load; report.SCSI.MultiMediaDevice.Features.CanEject = ftr0003.Value.Eject; report.SCSI.MultiMediaDevice.Features.PreventJumper = ftr0003.Value.PreventJumper; report.SCSI.MultiMediaDevice.Features.DBML = ftr0003.Value.DBML; report.SCSI.MultiMediaDevice.Features.Locked = ftr0003.Value.Lock; } } break; case 0x0004: { Decoders.SCSI.MMC.Feature_0004? ftr0004 = Decoders.SCSI.MMC.Features.Decode_0004(desc.Data); if(ftr0004.HasValue) { report.SCSI.MultiMediaDevice.Features.SupportsWriteProtectPAC = ftr0004.Value.DWP; report.SCSI.MultiMediaDevice.Features.SupportsWriteInhibitDCB = ftr0004.Value.WDCB; report.SCSI.MultiMediaDevice.Features.SupportsPWP = ftr0004.Value.SPWP; report.SCSI.MultiMediaDevice.Features.SupportsSWPP = ftr0004.Value.SSWPP; } } break; case 0x0010: { Decoders.SCSI.MMC.Feature_0010? ftr0010 = Decoders.SCSI.MMC.Features.Decode_0010(desc.Data); if(ftr0010.HasValue) { if(ftr0010.Value.LogicalBlockSize > 0) { report.SCSI.MultiMediaDevice.Features.LogicalBlockSize = ftr0010.Value.LogicalBlockSize; report.SCSI.MultiMediaDevice.Features.LogicalBlockSizeSpecified = true; } if(ftr0010.Value.Blocking > 0) { report.SCSI.MultiMediaDevice.Features.BlocksPerReadableUnit = ftr0010.Value.Blocking; report.SCSI.MultiMediaDevice.Features.BlocksPerReadableUnitSpecified = true; } report.SCSI.MultiMediaDevice.Features.ErrorRecoveryPage = ftr0010.Value.PP; } } break; case 0x001D: report.SCSI.MultiMediaDevice.Features.MultiRead = true; break; case 0x001E: { report.SCSI.MultiMediaDevice.Features.CanReadCD = true; Decoders.SCSI.MMC.Feature_001E? ftr001E = Decoders.SCSI.MMC.Features.Decode_001E(desc.Data); if(ftr001E.HasValue) { report.SCSI.MultiMediaDevice.Features.SupportsDAP = ftr001E.Value.DAP; report.SCSI.MultiMediaDevice.Features.SupportsC2 = ftr001E.Value.C2; report.SCSI.MultiMediaDevice.Features.CanReadLeadInCDText = ftr001E.Value.CDText; } } break; case 0x001F: { report.SCSI.MultiMediaDevice.Features.CanReadDVD = true; Decoders.SCSI.MMC.Feature_001F? ftr001F = Decoders.SCSI.MMC.Features.Decode_001F(desc.Data); if(ftr001F.HasValue) { report.SCSI.MultiMediaDevice.Features.DVDMultiRead = ftr001F.Value.MULTI110; report.SCSI.MultiMediaDevice.Features.CanReadAllDualRW = ftr001F.Value.DualRW; report.SCSI.MultiMediaDevice.Features.CanReadAllDualR = ftr001F.Value.DualRW; } } break; case 0x0022: report.SCSI.MultiMediaDevice.Features.CanEraseSector = true; break; case 0x0023: { report.SCSI.MultiMediaDevice.Features.CanFormat = true; Decoders.SCSI.MMC.Feature_0023? ftr0023 = Decoders.SCSI.MMC.Features.Decode_0023(desc.Data); if(ftr0023.HasValue) { report.SCSI.MultiMediaDevice.Features.CanFormatBDREWithoutSpare = ftr0023.Value.RENoSA; report.SCSI.MultiMediaDevice.Features.CanExpandBDRESpareArea = ftr0023.Value.Expand; report.SCSI.MultiMediaDevice.Features.CanFormatQCert = ftr0023.Value.QCert; report.SCSI.MultiMediaDevice.Features.CanFormatCert = ftr0023.Value.Cert; report.SCSI.MultiMediaDevice.Features.CanFormatFRF = ftr0023.Value.FRF; report.SCSI.MultiMediaDevice.Features.CanFormatRRM = ftr0023.Value.RRM; } } break; case 0x0024: report.SCSI.MultiMediaDevice.Features.CanReadSpareAreaInformation = true; break; case 0x0027: report.SCSI.MultiMediaDevice.Features.CanWriteCDRWCAV = true; break; case 0x0028: { report.SCSI.MultiMediaDevice.Features.CanReadCDMRW = true; Decoders.SCSI.MMC.Feature_0028? ftr0028 = Decoders.SCSI.MMC.Features.Decode_0028(desc.Data); if(ftr0028.HasValue) { report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW = ftr0028.Value.DVDPRead; report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusMRW = ftr0028.Value.DVDPWrite; report.SCSI.MultiMediaDevice.Features.CanWriteCDMRW = ftr0028.Value.Write; } } break; case 0x002A: { report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW = true; Decoders.SCSI.MMC.Feature_002A? ftr002A = Decoders.SCSI.MMC.Features.Decode_002A(desc.Data); if(ftr002A.HasValue) { report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRW = ftr002A.Value.Write; } } break; case 0x002B: { report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR = true; Decoders.SCSI.MMC.Feature_002B? ftr002B = Decoders.SCSI.MMC.Features.Decode_002B(desc.Data); if(ftr002B.HasValue) { report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusR = ftr002B.Value.Write; } } break; case 0x002D: { report.SCSI.MultiMediaDevice.Features.CanWriteCDTAO = true; Decoders.SCSI.MMC.Feature_002D? ftr002D = Decoders.SCSI.MMC.Features.Decode_002D(desc.Data); if(ftr002D.HasValue) { report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInTAO = ftr002D.Value.BUF; report.SCSI.MultiMediaDevice.Features.CanWriteRawSubchannelInTAO = ftr002D.Value.RWRaw; report.SCSI.MultiMediaDevice.Features.CanWritePackedSubchannelInTAO = ftr002D.Value.RWPack; report.SCSI.MultiMediaDevice.Features.CanTestWriteInTAO = ftr002D.Value.TestWrite; report.SCSI.MultiMediaDevice.Features.CanOverwriteTAOTrack = ftr002D.Value.CDRW; report.SCSI.MultiMediaDevice.Features.CanWriteRWSubchannelInTAO = ftr002D.Value.RWSubchannel; } } break; case 0x002E: { report.SCSI.MultiMediaDevice.Features.CanWriteCDSAO = true; Decoders.SCSI.MMC.Feature_002E? ftr002E = Decoders.SCSI.MMC.Features.Decode_002E(desc.Data); if(ftr002E.HasValue) { report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInSAO = ftr002E.Value.BUF; report.SCSI.MultiMediaDevice.Features.CanWriteRawMultiSession = ftr002E.Value.RAWMS; report.SCSI.MultiMediaDevice.Features.CanWriteRaw = ftr002E.Value.RAW; report.SCSI.MultiMediaDevice.Features.CanTestWriteInSAO = ftr002E.Value.TestWrite; report.SCSI.MultiMediaDevice.Features.CanOverwriteSAOTrack = ftr002E.Value.CDRW; report.SCSI.MultiMediaDevice.Features.CanWriteRWSubchannelInSAO = ftr002E.Value.RW; } } break; case 0x002F: { report.SCSI.MultiMediaDevice.Features.CanWriteDVDR = true; Decoders.SCSI.MMC.Feature_002F? ftr002F = Decoders.SCSI.MMC.Features.Decode_002F(desc.Data); if(ftr002F.HasValue) { report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInDVD = ftr002F.Value.BUF; report.SCSI.MultiMediaDevice.Features.CanWriteDVDRDL = ftr002F.Value.RDL; report.SCSI.MultiMediaDevice.Features.CanTestWriteDVD = ftr002F.Value.TestWrite; report.SCSI.MultiMediaDevice.Features.CanWriteDVDRW = ftr002F.Value.DVDRW; } } break; case 0x0030: report.SCSI.MultiMediaDevice.Features.CanReadDDCD = true; break; case 0x0031: { report.SCSI.MultiMediaDevice.Features.CanWriteDDCDR = true; Decoders.SCSI.MMC.Feature_0031? ftr0031 = Decoders.SCSI.MMC.Features.Decode_0031(desc.Data); if(ftr0031.HasValue) report.SCSI.MultiMediaDevice.Features.CanTestWriteDDCDR = ftr0031.Value.TestWrite; } break; case 0x0032: report.SCSI.MultiMediaDevice.Features.CanWriteDDCDRW = true; break; case 0x0037: report.SCSI.MultiMediaDevice.Features.CanWriteCDRW = true; break; case 0x0038: report.SCSI.MultiMediaDevice.Features.CanPseudoOverwriteBDR = true; break; case 0x003A: { report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL = true; Decoders.SCSI.MMC.Feature_003A? ftr003A = Decoders.SCSI.MMC.Features.Decode_003A(desc.Data); if(ftr003A.HasValue) report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRWDL = ftr003A.Value.Write; } break; case 0x003B: { report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL = true; Decoders.SCSI.MMC.Feature_003B? ftr003B = Decoders.SCSI.MMC.Features.Decode_003B(desc.Data); if(ftr003B.HasValue) report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRDL = ftr003B.Value.Write; } break; case 0x0040: { report.SCSI.MultiMediaDevice.Features.CanReadBD = true; Decoders.SCSI.MMC.Feature_0040? ftr0040 = Decoders.SCSI.MMC.Features.Decode_0040(desc.Data); if(ftr0040.HasValue) { report.SCSI.MultiMediaDevice.Features.CanReadBluBCA = ftr0040.Value.BCA; report.SCSI.MultiMediaDevice.Features.CanReadBDRE2 = ftr0040.Value.RE2; report.SCSI.MultiMediaDevice.Features.CanReadBDRE1 = ftr0040.Value.RE1; report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE = ftr0040.Value.OldRE; report.SCSI.MultiMediaDevice.Features.CanReadBDR = ftr0040.Value.R; report.SCSI.MultiMediaDevice.Features.CanReadOldBDR = ftr0040.Value.OldR; report.SCSI.MultiMediaDevice.Features.CanReadBDROM = ftr0040.Value.ROM; report.SCSI.MultiMediaDevice.Features.CanReadOldBDROM = ftr0040.Value.OldROM; } } break; case 0x0041: { report.SCSI.MultiMediaDevice.Features.CanWriteBD = true; Decoders.SCSI.MMC.Feature_0041? ftr0041 = Decoders.SCSI.MMC.Features.Decode_0041(desc.Data); if(ftr0041.HasValue) { report.SCSI.MultiMediaDevice.Features.CanWriteBDRE2 = ftr0041.Value.RE2; report.SCSI.MultiMediaDevice.Features.CanWriteBDRE1 = ftr0041.Value.RE1; report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE = ftr0041.Value.OldRE; report.SCSI.MultiMediaDevice.Features.CanReadBDR = ftr0041.Value.R; report.SCSI.MultiMediaDevice.Features.CanReadOldBDR = ftr0041.Value.OldR; } } break; case 0x0050: { report.SCSI.MultiMediaDevice.Features.CanReadHDDVD = true; Decoders.SCSI.MMC.Feature_0050? ftr0050 = Decoders.SCSI.MMC.Features.Decode_0050(desc.Data); if(ftr0050.HasValue) { report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR = ftr0050.Value.HDDVDR; report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM = ftr0050.Value.HDDVDRAM; } } break; case 0x0051: { // TODO: Write HD DVD-RW Decoders.SCSI.MMC.Feature_0051? ftr0051 = Decoders.SCSI.MMC.Features.Decode_0051(desc.Data); if(ftr0051.HasValue) { report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDR = ftr0051.Value.HDDVDR; report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDRAM = ftr0051.Value.HDDVDRAM; } } break; case 0x0080: report.SCSI.MultiMediaDevice.Features.SupportsHybridDiscs = true; break; case 0x0101: report.SCSI.MultiMediaDevice.Features.SupportsModePage1Ch = true; break; case 0x0102: { report.SCSI.MultiMediaDevice.Features.EmbeddedChanger = true; Decoders.SCSI.MMC.Feature_0102? ftr0102 = Decoders.SCSI.MMC.Features.Decode_0102(desc.Data); if(ftr0102.HasValue) { report.SCSI.MultiMediaDevice.Features.ChangerIsSideChangeCapable = ftr0102.Value.SCC; report.SCSI.MultiMediaDevice.Features.ChangerSupportsDiscPresent = ftr0102.Value.SDP; report.SCSI.MultiMediaDevice.Features.ChangerSlots = (byte)(ftr0102.Value.HighestSlotNumber + 1); } } break; case 0x0103: { report.SCSI.MultiMediaDevice.Features.CanPlayCDAudio = true; Decoders.SCSI.MMC.Feature_0103? ftr0103 = Decoders.SCSI.MMC.Features.Decode_0103(desc.Data); if(ftr0103.HasValue) { report.SCSI.MultiMediaDevice.Features.CanAudioScan = ftr0103.Value.Scan; report.SCSI.MultiMediaDevice.Features.CanMuteSeparateChannels = ftr0103.Value.SCM; report.SCSI.MultiMediaDevice.Features.SupportsSeparateVolume = ftr0103.Value.SV; if(ftr0103.Value.VolumeLevels > 0) { report.SCSI.MultiMediaDevice.Features.VolumeLevelsSpecified = true; report.SCSI.MultiMediaDevice.Features.VolumeLevels = ftr0103.Value.VolumeLevels; } } } break; case 0x0104: report.SCSI.MultiMediaDevice.Features.CanUpgradeFirmware = true; break; case 0x0106: { report.SCSI.MultiMediaDevice.Features.SupportsCSS = true; Decoders.SCSI.MMC.Feature_0106? ftr0106 = Decoders.SCSI.MMC.Features.Decode_0106(desc.Data); if(ftr0106.HasValue) { if(ftr0106.Value.CSSVersion > 0) { report.SCSI.MultiMediaDevice.Features.CSSVersionSpecified = true; report.SCSI.MultiMediaDevice.Features.CSSVersion = ftr0106.Value.CSSVersion; } } } break; case 0x0108: report.SCSI.MultiMediaDevice.Features.CanReportDriveSerial = true; break; case 0x0109: report.SCSI.MultiMediaDevice.Features.CanReportMediaSerial = true; break; case 0x010B: { report.SCSI.MultiMediaDevice.Features.SupportsCPRM = true; Decoders.SCSI.MMC.Feature_010B? ftr010B = Decoders.SCSI.MMC.Features.Decode_010B(desc.Data); if(ftr010B.HasValue) { if(ftr010B.Value.CPRMVersion > 0) { report.SCSI.MultiMediaDevice.Features.CPRMVersionSpecified = true; report.SCSI.MultiMediaDevice.Features.CPRMVersion = ftr010B.Value.CPRMVersion; } } } break; case 0x010C: { Decoders.SCSI.MMC.Feature_010C? ftr010C = Decoders.SCSI.MMC.Features.Decode_010C(desc.Data); if(ftr010C.HasValue) { string syear, smonth, sday, shour, sminute, ssecond; byte[] temp; temp = new byte[4]; temp[0] = (byte)((ftr010C.Value.Century & 0xFF00) >> 8); temp[1] = (byte)(ftr010C.Value.Century & 0xFF); temp[2] = (byte)((ftr010C.Value.Year & 0xFF00) >> 8); temp[3] = (byte)(ftr010C.Value.Year & 0xFF); syear = System.Text.Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr010C.Value.Month & 0xFF00) >> 8); temp[1] = (byte)(ftr010C.Value.Month & 0xFF); smonth = System.Text.Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr010C.Value.Day & 0xFF00) >> 8); temp[1] = (byte)(ftr010C.Value.Day & 0xFF); sday = System.Text.Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr010C.Value.Hour & 0xFF00) >> 8); temp[1] = (byte)(ftr010C.Value.Hour & 0xFF); shour = System.Text.Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr010C.Value.Minute & 0xFF00) >> 8); temp[1] = (byte)(ftr010C.Value.Minute & 0xFF); sminute = System.Text.Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr010C.Value.Second & 0xFF00) >> 8); temp[1] = (byte)(ftr010C.Value.Second & 0xFF); ssecond = System.Text.Encoding.ASCII.GetString(temp); try { report.SCSI.MultiMediaDevice.Features.FirmwareDate = new DateTime(int.Parse(syear), int.Parse(smonth), int.Parse(sday), int.Parse(shour), int.Parse(sminute), int.Parse(ssecond), DateTimeKind.Utc); report.SCSI.MultiMediaDevice.Features.FirmwareDateSpecified = true; } #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body { } } } break; case 0x010D: { report.SCSI.MultiMediaDevice.Features.SupportsAACS = true; Decoders.SCSI.MMC.Feature_010D? ftr010D = Decoders.SCSI.MMC.Features.Decode_010D(desc.Data); if(ftr010D.HasValue) { report.SCSI.MultiMediaDevice.Features.CanReadDriveAACSCertificate = ftr010D.Value.RDC; report.SCSI.MultiMediaDevice.Features.CanReadCPRM_MKB = ftr010D.Value.RMC; report.SCSI.MultiMediaDevice.Features.CanWriteBusEncryptedBlocks = ftr010D.Value.WBE; report.SCSI.MultiMediaDevice.Features.SupportsBusEncryption = ftr010D.Value.BEC; report.SCSI.MultiMediaDevice.Features.CanGenerateBindingNonce = ftr010D.Value.BNG; if(ftr010D.Value.BindNonceBlocks > 0) { report.SCSI.MultiMediaDevice.Features.BindingNonceBlocksSpecified = true; report.SCSI.MultiMediaDevice.Features.BindingNonceBlocks = ftr010D.Value.BindNonceBlocks; } if(ftr010D.Value.AGIDs > 0) { report.SCSI.MultiMediaDevice.Features.AGIDsSpecified = true; report.SCSI.MultiMediaDevice.Features.AGIDs = ftr010D.Value.AGIDs; } if(ftr010D.Value.AACSVersion > 0) { report.SCSI.MultiMediaDevice.Features.AACSVersionSpecified = true; report.SCSI.MultiMediaDevice.Features.AACSVersion = ftr010D.Value.AACSVersion; } } } break; case 0x010E: report.SCSI.MultiMediaDevice.Features.CanWriteCSSManagedDVD = true; break; case 0x0113: report.SCSI.MultiMediaDevice.Features.SupportsSecurDisc = true; break; case 0x0142: report.SCSI.MultiMediaDevice.Features.SupportsOSSC = true; break; case 0x0110: report.SCSI.MultiMediaDevice.Features.SupportsVCPS = true; break; } } } if(report.SCSI.MultiMediaDevice.Features.CanReadBD || report.SCSI.MultiMediaDevice.Features.CanReadBDR || report.SCSI.MultiMediaDevice.Features.CanReadBDRE1 || report.SCSI.MultiMediaDevice.Features.CanReadBDRE2 || report.SCSI.MultiMediaDevice.Features.CanReadBDROM || report.SCSI.MultiMediaDevice.Features.CanReadOldBDR || report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE || report.SCSI.MultiMediaDevice.Features.CanReadOldBDROM) { if(!mediaTypes.Contains("BD-ROM")) mediaTypes.Add("BD-ROM"); if(!mediaTypes.Contains("BD-R")) mediaTypes.Add("BD-R"); if(!mediaTypes.Contains("BD-RE")) mediaTypes.Add("BD-RE"); if(!mediaTypes.Contains("BD-R LTH")) mediaTypes.Add("BD-R LTH"); if(!mediaTypes.Contains("BD-R XL")) mediaTypes.Add("BD-R XL"); } if(report.SCSI.MultiMediaDevice.Features.CanReadCD || report.SCSI.MultiMediaDevice.Features.MultiRead) { if(!mediaTypes.Contains("CD-ROM")) mediaTypes.Add("CD-ROM"); if(!mediaTypes.Contains("Audio CD")) mediaTypes.Add("Audio CD"); if(!mediaTypes.Contains("CD-R")) mediaTypes.Add("CD-R"); if(!mediaTypes.Contains("CD-RW")) mediaTypes.Add("CD-RW"); } if(report.SCSI.MultiMediaDevice.Features.CanReadCDMRW) { if(!mediaTypes.Contains("CD-MRW")) mediaTypes.Add("CD-MRW"); } if(report.SCSI.MultiMediaDevice.Features.CanReadDDCD) { if(!mediaTypes.Contains("DDCD-ROM")) mediaTypes.Add("DDCD-ROM"); if(!mediaTypes.Contains("DDCD-R")) mediaTypes.Add("DDCD-R"); if(!mediaTypes.Contains("DDCD-RW")) mediaTypes.Add("DDCD-RW"); } if(report.SCSI.MultiMediaDevice.Features.CanReadDVD || report.SCSI.MultiMediaDevice.Features.DVDMultiRead || report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR || report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL || report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW || report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL) { if(!mediaTypes.Contains("DVD-ROM")) mediaTypes.Add("DVD-ROM"); if(!mediaTypes.Contains("DVD-R")) mediaTypes.Add("DVD-R"); if(!mediaTypes.Contains("DVD-RW")) mediaTypes.Add("DVD-RW"); if(!mediaTypes.Contains("DVD+R")) mediaTypes.Add("DVD+R"); if(!mediaTypes.Contains("DVD+RW")) mediaTypes.Add("DVD+RW"); if(!mediaTypes.Contains("DVD-R DL")) mediaTypes.Add("DVD-R DL"); if(!mediaTypes.Contains("DVD+R DL")) mediaTypes.Add("DVD+R DL"); } if(report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW) { if(!mediaTypes.Contains("DVD+MRW")) mediaTypes.Add("DVD+MRW"); } if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVD || report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR) { if(!mediaTypes.Contains("HD DVD-ROM")) mediaTypes.Add("HD DVD-ROM"); if(!mediaTypes.Contains("HD DVD-R")) mediaTypes.Add("HD DVD-R"); if(!mediaTypes.Contains("HD DVD-RW")) mediaTypes.Add("HD DVD-RW"); } if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM) { if(!mediaTypes.Contains("HD DVD-RAM")) mediaTypes.Add("HD DVD-RAM"); } } bool tryPlextor = false, tryHLDTST = false, tryPioneer = false, tryNEC = false; tryPlextor |= dev.Manufacturer.ToLowerInvariant() == "plextor"; tryHLDTST |= dev.Manufacturer.ToLowerInvariant() == "hl-dt-st"; tryPioneer |= dev.Manufacturer.ToLowerInvariant() == "pioneer"; tryNEC |= dev.Manufacturer.ToLowerInvariant() == "nec"; // Very old CD drives do not contain mode page 2Ah neither GET CONFIGURATION, so just try all CDs on them // Also don't get confident, some drives didn't know CD-RW but are able to read them if(mediaTypes.Count == 0 || mediaTypes.Contains("CD-ROM")) { if(!mediaTypes.Contains("CD-ROM")) mediaTypes.Add("CD-ROM"); if(!mediaTypes.Contains("Audio CD")) mediaTypes.Add("Audio CD"); if(!mediaTypes.Contains("CD-R")) mediaTypes.Add("CD-R"); if(!mediaTypes.Contains("CD-RW")) mediaTypes.Add("CD-RW"); } mediaTypes.Sort(); List mediaTests = new List(); foreach(string mediaType in mediaTypes) { pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { DicConsole.Write("Do you have a {0} disc that you can insert in the drive? (Y/N): ", mediaType); pressedKey = System.Console.ReadKey(); DicConsole.WriteLine(); } if(pressedKey.Key == ConsoleKey.Y) { dev.AllowMediumRemoval(out senseBuffer, timeout, out duration); dev.EjectTray(out senseBuffer, timeout, out duration); DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); System.Console.ReadKey(true); testedMediaType mediaTest = new testedMediaType(); mediaTest.MediumTypeName = mediaType; mediaTest.MediaIsRecognized = true; sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); if(sense) { Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); if(decSense.HasValue) { if(decSense.Value.ASC == 0x3A) { int leftRetries = 20; while(leftRetries > 0) { DicConsole.Write("\rWaiting for drive to become ready"); System.Threading.Thread.Sleep(2000); sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); if(!sense) break; leftRetries--; } mediaTest.MediaIsRecognized &= !sense; } else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) { int leftRetries = 20; while(leftRetries > 0) { DicConsole.Write("\rWaiting for drive to become ready"); System.Threading.Thread.Sleep(2000); sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); if(!sense) break; leftRetries--; } mediaTest.MediaIsRecognized &= !sense; } else mediaTest.MediaIsRecognized = false; } else mediaTest.MediaIsRecognized = false; } if(mediaTest.MediaIsRecognized) { mediaTest.SupportsReadCapacitySpecified = true; mediaTest.SupportsReadCapacity16Specified = true; DicConsole.WriteLine("Querying SCSI READ CAPACITY..."); sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration); if(!sense && !dev.Error) { mediaTest.SupportsReadCapacity = true; mediaTest.Blocks = (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3])) + 1; mediaTest.BlockSize = (uint)((buffer[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); mediaTest.BlocksSpecified = true; mediaTest.BlockSizeSpecified = true; } DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)..."); sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration); if(!sense && !dev.Error) { mediaTest.SupportsReadCapacity16 = true; byte[] temp = new byte[8]; Array.Copy(buffer, 0, temp, 0, 8); Array.Reverse(temp); mediaTest.Blocks = BitConverter.ToUInt64(temp, 0) + 1; mediaTest.BlockSize = (uint)((buffer[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); mediaTest.BlocksSpecified = true; mediaTest.BlockSizeSpecified = true; } decMode = null; DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); if(!sense && !dev.Error) { report.SCSI.SupportsModeSense10 = true; decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); if(debug) mediaTest.ModeSense10Data = buffer; } DicConsole.WriteLine("Querying SCSI MODE SENSE..."); sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); if(!sense && !dev.Error) { report.SCSI.SupportsModeSense6 = true; if(!decMode.HasValue) decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); if(debug) mediaTest.ModeSense6Data = buffer; } if(decMode.HasValue) { mediaTest.MediumType = (byte)decMode.Value.Header.MediumType; mediaTest.MediumTypeSpecified = true; if(decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0) { mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; mediaTest.DensitySpecified = true; } } if(mediaType.StartsWith("CD-", StringComparison.Ordinal) || mediaType == "Audio CD") { mediaTest.CanReadTOCSpecified = true; mediaTest.CanReadFullTOCSpecified = true; DicConsole.WriteLine("Querying CD TOC..."); mediaTest.CanReadTOC = !dev.ReadTocPmaAtip(out buffer, out senseBuffer, false, 0, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadTOC); if(debug) DataFile.WriteTo("SCSI Report", "readtoc", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Querying CD Full TOC..."); mediaTest.CanReadFullTOC = !dev.ReadRawToc(out buffer, out senseBuffer, 1, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadFullTOC); if(debug) DataFile.WriteTo("SCSI Report", "readfulltoc", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType.StartsWith("CD-R", StringComparison.Ordinal)) { mediaTest.CanReadATIPSpecified = true; mediaTest.CanReadPMASpecified = true; DicConsole.WriteLine("Querying CD ATIP..."); mediaTest.CanReadATIP = !dev.ReadAtip(out buffer, out senseBuffer, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadATIP); if(debug) DataFile.WriteTo("SCSI Report", "atip", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Querying CD PMA..."); mediaTest.CanReadPMA = !dev.ReadPma(out buffer, out senseBuffer, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPMA); if(debug) DataFile.WriteTo("SCSI Report", "pma", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType.StartsWith("DVD-", StringComparison.Ordinal) || mediaType.StartsWith("HD DVD-", StringComparison.Ordinal)) { mediaTest.CanReadPFISpecified = true; mediaTest.CanReadDMISpecified = true; DicConsole.WriteLine("Querying DVD PFI..."); mediaTest.CanReadPFI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPFI); if(debug) DataFile.WriteTo("SCSI Report", "pfi", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Querying DVD DMI..."); mediaTest.CanReadDMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDMI); if(debug) DataFile.WriteTo("SCSI Report", "dmi", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType == "DVD-ROM") { mediaTest.CanReadCMISpecified = true; DicConsole.WriteLine("Querying DVD CMI..."); mediaTest.CanReadCMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCMI); if(debug) DataFile.WriteTo("SCSI Report", "cmi", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType == "DVD-ROM" || mediaType == "HD DVD-ROM") { mediaTest.CanReadBCASpecified = true; DicConsole.WriteLine("Querying DVD BCA..."); mediaTest.CanReadBCA = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadBCA); if(debug) DataFile.WriteTo("SCSI Report", "bca", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadAACSSpecified = true; DicConsole.WriteLine("Querying DVD AACS..."); mediaTest.CanReadAACS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVD_AACS, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadAACS); if(debug) DataFile.WriteTo("SCSI Report", "aacs", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType == "BD-ROM") { mediaTest.CanReadBCASpecified = true; DicConsole.WriteLine("Querying BD BCA..."); mediaTest.CanReadBCA = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_BurstCuttingArea, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadBCA); if(debug) DataFile.WriteTo("SCSI Report", "bdbca", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType == "DVD-RAM" || mediaType == "HD DVD-RAM") { mediaTest.CanReadDDSSpecified = true; mediaTest.CanReadSpareAreaInformationSpecified = true; mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_DDS, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDDS); if(debug) DataFile.WriteTo("SCSI Report", "dds", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadSpareAreaInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_SpareAreaInformation, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadSpareAreaInformation); if(debug) DataFile.WriteTo("SCSI Report", "sai", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType.StartsWith("BD-R", StringComparison.Ordinal) && mediaType != "BD-ROM") { mediaTest.CanReadDDSSpecified = true; mediaTest.CanReadSpareAreaInformationSpecified = true; DicConsole.WriteLine("Querying BD DDS..."); mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_DDS, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDDS); if(debug) DataFile.WriteTo("SCSI Report", "bddds", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Querying BD SAI..."); mediaTest.CanReadSpareAreaInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_SpareAreaInformation, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadSpareAreaInformation); if(debug) DataFile.WriteTo("SCSI Report", "bdsai", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType == "DVD-R" || mediaType == "DVD-RW") { mediaTest.CanReadPRISpecified = true; DicConsole.WriteLine("Querying DVD PRI..."); mediaTest.CanReadPRI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PreRecordedInfo, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPRI); if(debug) DataFile.WriteTo("SCSI Report", "pri", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType == "DVD-R" || mediaType == "DVD-RW" || mediaType == "HD DVD-R") { mediaTest.CanReadMediaIDSpecified = true; mediaTest.CanReadRecordablePFISpecified = true; DicConsole.WriteLine("Querying DVD Media ID..."); mediaTest.CanReadMediaID = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_MediaIdentifier, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadMediaID); if(debug) DataFile.WriteTo("SCSI Report", "mediaid", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Querying DVD Embossed PFI..."); mediaTest.CanReadRecordablePFI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_PhysicalInformation, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRecordablePFI); if(debug) DataFile.WriteTo("SCSI Report", "epfi", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType.StartsWith("DVD+R", StringComparison.Ordinal)) { mediaTest.CanReadADIPSpecified = true; mediaTest.CanReadDCBSpecified = true; DicConsole.WriteLine("Querying DVD ADIP..."); mediaTest.CanReadADIP = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.ADIP, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadADIP); if(debug) DataFile.WriteTo("SCSI Report", "adip", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Querying DVD DCB..."); mediaTest.CanReadDCB = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DCB, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDCB); if(debug) DataFile.WriteTo("SCSI Report", "dcb", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType == "HD DVD-ROM") { mediaTest.CanReadHDCMISpecified = true; DicConsole.WriteLine("Querying HD DVD CMI..."); mediaTest.CanReadHDCMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.HDDVD_CopyrightInformation, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadHDCMI); if(debug) DataFile.WriteTo("SCSI Report", "hdcmi", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType.EndsWith(" DL", StringComparison.Ordinal)) { mediaTest.CanReadLayerCapacitySpecified = true; DicConsole.WriteLine("Querying DVD Layer Capacity..."); mediaTest.CanReadLayerCapacity = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_LayerCapacity, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadLayerCapacity); if(debug) DataFile.WriteTo("SCSI Report", "layer", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType.StartsWith("BD-R", StringComparison.Ordinal)) { mediaTest.CanReadDiscInformationSpecified = true; mediaTest.CanReadPACSpecified = true; DicConsole.WriteLine("Querying BD Disc Information..."); mediaTest.CanReadDiscInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.DiscInformation, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadDiscInformation); if(debug) DataFile.WriteTo("SCSI Report", "di", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Querying BD PAC..."); mediaTest.CanReadPAC = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.PAC, 0, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPAC); if(debug) DataFile.WriteTo("SCSI Report", "pac", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } mediaTest.SupportsReadSpecified = true; mediaTest.SupportsRead10Specified = true; mediaTest.SupportsRead12Specified = true; mediaTest.SupportsRead16Specified = true; DicConsole.WriteLine("Trying SCSI READ (6)..."); mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, 2048, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead); if(debug) DataFile.WriteTo("SCSI Report", "read6", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying SCSI READ (10)..."); mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, 2048, 0, 1, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead10); if(debug) DataFile.WriteTo("SCSI Report", "read10", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying SCSI READ (12)..."); mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, 2048, 0, 1, false, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead12); if(debug) DataFile.WriteTo("SCSI Report", "read12", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying SCSI READ (16)..."); mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, 2048, 0, 1, false, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead16); if(debug) DataFile.WriteTo("SCSI Report", "read16", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); if(debug) { if(!tryPlextor) { pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { DicConsole.Write("Do you have want to try Plextor vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); pressedKey = System.Console.ReadKey(); DicConsole.WriteLine(); } tryPlextor |= pressedKey.Key == ConsoleKey.Y; } } if(mediaType.StartsWith("CD-", StringComparison.Ordinal) || mediaType == "Audio CD") { mediaTest.CanReadC2PointersSpecified = true; mediaTest.CanReadCorrectedSubchannelSpecified = true; mediaTest.CanReadCorrectedSubchannelWithC2Specified = true; mediaTest.CanReadLeadInSpecified = true; mediaTest.CanReadLeadOutSpecified = true; mediaTest.CanReadPQSubchannelSpecified = true; mediaTest.CanReadPQSubchannelWithC2Specified = true; mediaTest.CanReadRWSubchannelSpecified = true; mediaTest.CanReadRWSubchannelWithC2Specified = true; mediaTest.SupportsReadCdMsfSpecified = true; mediaTest.SupportsReadCdSpecified = true; mediaTest.SupportsReadCdMsfRawSpecified = true; mediaTest.SupportsReadCdRawSpecified = true; if(mediaType == "Audio CD") { DicConsole.WriteLine("Trying SCSI READ CD..."); mediaTest.SupportsReadCd = !dev.ReadCd(out buffer, out senseBuffer, 0, 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsReadCd); if(debug) DataFile.WriteTo("SCSI Report", "readcd", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying SCSI READ CD MSF..."); mediaTest.SupportsReadCdMsf = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, MmcSectorTypes.CDDA, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsReadCdMsf); if(debug) DataFile.WriteTo("SCSI Report", "readcdmsf", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } else { DicConsole.WriteLine("Trying SCSI READ CD..."); mediaTest.SupportsReadCd = !dev.ReadCd(out buffer, out senseBuffer, 0, 2048, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsReadCd); if(debug) DataFile.WriteTo("SCSI Report", "readcd", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying SCSI READ CD MSF..."); mediaTest.SupportsReadCdMsf = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2048, MmcSectorTypes.AllTypes, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsReadCdMsf); if(debug) DataFile.WriteTo("SCSI Report", "readcdmsf", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying SCSI READ CD full sector..."); mediaTest.SupportsReadCdRaw = !dev.ReadCd(out buffer, out senseBuffer, 0, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsReadCdRaw); if(debug) DataFile.WriteTo("SCSI Report", "readcdraw", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying SCSI READ CD MSF full sector..."); mediaTest.SupportsReadCdMsfRaw = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, MmcSectorTypes.AllTypes, false, false, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsReadCdMsfRaw); if(debug) DataFile.WriteTo("SCSI Report", "readcdmsfraw", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaTest.SupportsReadCdRaw || mediaType == "Audio CD") { DicConsole.WriteLine("Trying to read CD Lead-In..."); for(int i = -150; i < 0; i++) { if(mediaType == "Audio CD") sense = dev.ReadCd(out buffer, out senseBuffer, (uint)i, 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); else sense = dev.ReadCd(out buffer, out senseBuffer, (uint)i, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", sense); if(debug) DataFile.WriteTo("SCSI Report", "leadin", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); if(!sense) { mediaTest.CanReadLeadIn = true; break; } } DicConsole.WriteLine("Trying to read CD Lead-Out..."); if(mediaType == "Audio CD") mediaTest.CanReadLeadOut = dev.ReadCd(out buffer, out senseBuffer, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); else mediaTest.CanReadLeadOut = !dev.ReadCd(out buffer, out senseBuffer, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadLeadOut); if(debug) DataFile.WriteTo("SCSI Report", "leadout", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaType == "Audio CD" && mediaTest.SupportsReadCd) { DicConsole.WriteLine("Trying to read C2 Pointers..."); mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); if(!mediaTest.CanReadC2Pointers) mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2648, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers); if(debug) DataFile.WriteTo("SCSI Report", "readcdc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying to read subchannels..."); mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPQSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdpq", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRWSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdrw", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCorrectedSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdsub", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2662, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); if(!mediaTest.CanReadPQSubchannelWithC2) mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2664, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPQSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdpqc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); if(!mediaTest.CanReadRWSubchannelWithC2) mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRWSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdrwc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); if(!mediaTest.CanReadCorrectedSubchannelWithC2) mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCorrectedSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdsubc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } else if(mediaTest.SupportsReadCdRaw) { DicConsole.WriteLine("Trying to read C2 Pointers..."); mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); if(!mediaTest.CanReadC2Pointers) mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2648, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers); if(debug) DataFile.WriteTo("SCSI Report", "readcdc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying to read subchannels..."); mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPQSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdpq", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRWSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdrw", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCorrectedSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdsub", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2662, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); if(!mediaTest.CanReadPQSubchannelWithC2) mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2664, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPQSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdpqc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); if(!mediaTest.CanReadRWSubchannelWithC2) mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRWSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdrwc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); if(!mediaTest.CanReadCorrectedSubchannelWithC2) mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCorrectedSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdsubc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } else { DicConsole.WriteLine("Trying to read C2 Pointers..."); mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2342, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); if(!mediaTest.CanReadC2Pointers) mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2344, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadC2Pointers); if(debug) DataFile.WriteTo("SCSI Report", "readcdc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying to read subchannels..."); mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2064, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPQSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdpq", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2144, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRWSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdrw", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2144, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCorrectedSubchannel); if(debug) DataFile.WriteTo("SCSI Report", "readcdsub", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2358, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); if(!mediaTest.CanReadPQSubchannelWithC2) mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2360, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadPQSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdpqc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); if(!mediaTest.CanReadRWSubchannelWithC2) mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadRWSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdrwc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); if(!mediaTest.CanReadCorrectedSubchannelWithC2) mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.CanReadCorrectedSubchannelWithC2); if(debug) DataFile.WriteTo("SCSI Report", "readcdsubc2", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(debug) { if(!tryNEC) { pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { DicConsole.Write("Do you have want to try NEC vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); pressedKey = System.Console.ReadKey(); DicConsole.WriteLine(); } tryNEC |= pressedKey.Key == ConsoleKey.Y; } if(!tryPioneer) { pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { DicConsole.Write("Do you have want to try Pioneer vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); pressedKey = System.Console.ReadKey(); DicConsole.WriteLine(); } tryPioneer |= pressedKey.Key == ConsoleKey.Y; } } if(tryPlextor) { mediaTest.SupportsPlextorReadCDDASpecified = true; DicConsole.WriteLine("Trying Plextor READ CD-DA..."); mediaTest.SupportsPlextorReadCDDA = !dev.PlextorReadCdDa(out buffer, out senseBuffer, 0, 2352, 1, PlextorSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsPlextorReadCDDA); if(debug) DataFile.WriteTo("SCSI Report", "plextorreadcdda", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(tryPioneer) { mediaTest.SupportsPioneerReadCDDASpecified = true; mediaTest.SupportsPioneerReadCDDAMSFSpecified = true; DicConsole.WriteLine("Trying Pioneer READ CD-DA..."); mediaTest.SupportsPioneerReadCDDA = !dev.PioneerReadCdDa(out buffer, out senseBuffer, 0, 2352, 1, PioneerSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsPioneerReadCDDA); if(debug) DataFile.WriteTo("SCSI Report", "pioneerreadcdda", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); DicConsole.WriteLine("Trying Pioneer READ CD-DA MSF..."); mediaTest.SupportsPioneerReadCDDAMSF = !dev.PioneerReadCdDaMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, PioneerSubchannel.None, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsPioneerReadCDDAMSF); if(debug) DataFile.WriteTo("SCSI Report", "pioneerreadcddamsf", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(tryNEC) { mediaTest.SupportsNECReadCDDASpecified = true; DicConsole.WriteLine("Trying NEC READ CD-DA..."); mediaTest.SupportsNECReadCDDA = !dev.NecReadCdDa(out buffer, out senseBuffer, 0, 1, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsNECReadCDDA); if(debug) DataFile.WriteTo("SCSI Report", "necreadcdda", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } } mediaTest.LongBlockSize = mediaTest.BlockSize; DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration); if(sense && !dev.Error) { Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); if(decSense.HasValue) { if(decSense.Value.SenseKey == Decoders.SCSI.SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00) { mediaTest.SupportsReadLong = true; if(decSense.Value.InformationValid && decSense.Value.ILI) { mediaTest.LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); mediaTest.LongBlockSizeSpecified = true; } } } } if(debug) { if(!tryHLDTST) { pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { DicConsole.Write("Do you have want to try HL-DT-ST (aka LG) vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); pressedKey = System.Console.ReadKey(); DicConsole.WriteLine(); } tryHLDTST |= pressedKey.Key == ConsoleKey.Y; } } if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize) { if(mediaTest.BlockSize == 512) { // Long sector sizes for 512-byte magneto-opticals foreach(ushort testSize in new[] { 600, 610, 630 }) { sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration); if(!sense && !dev.Error) { mediaTest.SupportsReadLong = true; mediaTest.LongBlockSize = testSize; mediaTest.LongBlockSizeSpecified = true; break; } } } else if(mediaTest.BlockSize == 1024) { sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration); if(!sense && !dev.Error) { mediaTest.SupportsReadLong = true; mediaTest.LongBlockSize = 1200; mediaTest.LongBlockSizeSpecified = true; } } else if(mediaTest.BlockSize == 2048) { if(mediaType.StartsWith("DVD", StringComparison.Ordinal)) { sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 37856, timeout, out duration); if(!sense && !dev.Error) { mediaTest.SupportsReadLong = true; mediaTest.LongBlockSize = 37856; mediaTest.LongBlockSizeSpecified = true; } } else { sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration); if(!sense && !dev.Error) { mediaTest.SupportsReadLong = true; mediaTest.LongBlockSize = 2380; mediaTest.LongBlockSizeSpecified = true; } } } else if(mediaTest.BlockSize == 4096) { sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration); if(!sense && !dev.Error) { mediaTest.SupportsReadLong = true; mediaTest.LongBlockSize = 4760; mediaTest.LongBlockSizeSpecified = true; } } else if(mediaTest.BlockSize == 8192) { sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration); if(!sense && !dev.Error) { mediaTest.SupportsReadLong = true; mediaTest.LongBlockSize = 9424; mediaTest.LongBlockSizeSpecified = true; } } } if(tryPlextor) { mediaTest.SupportsPlextorReadRawDVDSpecified = true; DicConsole.WriteLine("Trying Plextor trick to raw read DVDs..."); mediaTest.SupportsPlextorReadRawDVD = !dev.PlextorReadRawDvd(out buffer, out senseBuffer, 0, 1, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsPlextorReadRawDVD); if(debug) DataFile.WriteTo("SCSI Report", "plextorrawdvd", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); if(mediaTest.SupportsPlextorReadRawDVD) mediaTest.SupportsPlextorReadRawDVD = !ArrayHelpers.ArrayIsNullOrEmpty(buffer); } if(tryHLDTST) { mediaTest.SupportsHLDTSTReadRawDVDSpecified = true; DicConsole.WriteLine("Trying HL-DT-ST (aka LG) trick to raw read DVDs..."); mediaTest.SupportsHLDTSTReadRawDVD = !dev.HlDtStReadRawDvd(out buffer, out senseBuffer, 0, 1, timeout, out duration); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsHLDTSTReadRawDVD); if(debug) DataFile.WriteTo("SCSI Report", "hldtstrawdvd", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize) { pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { DicConsole.Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): "); pressedKey = System.Console.ReadKey(); DicConsole.WriteLine(); } if(pressedKey.Key == ConsoleKey.Y) { for(ushort i = (ushort)mediaTest.BlockSize; i <= ushort.MaxValue; i++) { DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration); if(!sense) { if(debug) { FileStream bingo = new FileStream(string.Format("{0}_readlong.bin", mediaType), FileMode.Create); bingo.Write(buffer, 0, buffer.Length); bingo.Close(); } mediaTest.LongBlockSize = i; mediaTest.LongBlockSizeSpecified = true; break; } if(i == ushort.MaxValue) break; } DicConsole.WriteLine(); } } if(debug && mediaTest.SupportsReadLong && mediaTest.LongBlockSizeSpecified && mediaTest.LongBlockSize != mediaTest.BlockSize) { sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, (ushort)mediaTest.LongBlockSize, timeout, out duration); if(!sense) DataFile.WriteTo("SCSI Report", "readlong10", "_debug_" + report.SCSI.Inquiry.ProductIdentification + "_" + mediaType + ".bin", "read results", buffer); } } mediaTests.Add(mediaTest); } report.SCSI.MultiMediaDevice.TestedMedia = mediaTests.ToArray(); } } } }