public static PreRecordedInformation?Decode(byte[] response) { if (response == null) { return(null); } if (response.Length < 67) { return(null); } var pri = new PreRecordedInformation(); byte[] tmp; pri.DataLength = (ushort)((response[0] << 8) + response[1]); pri.Reserved1 = response[2]; pri.Reserved2 = response[3]; pri.FieldId1 = response[4]; pri.FieldId2 = response[12]; pri.FieldId3 = response[20]; pri.FieldId4 = response[28]; pri.FieldId5 = response[36]; if (pri.FieldId1 != 1 || pri.FieldId2 != 2 || pri.FieldId3 != 3 || pri.FieldId4 != 4 || pri.FieldId5 != 5) { return(null); } pri.DiscApplicationCode = response[5]; pri.DiscPhysicalCode = response[6]; pri.LastAddressOfDataRecordableArea = (uint)((response[7] << 16) + (response[8] << 8) + response[9]); pri.PartVersion = (byte)(response[10] >> 4); pri.ExtensionCode = (byte)(response[10] & 0xF); pri.Reserved3 = response[11]; pri.OPCSuggestedCode = response[13]; pri.WaveLengthCode = response[14]; pri.WriteStrategyCode = (uint)((response[15] << 24) + (response[16] << 16) + (response[17] << 8) + response[18]); pri.Reserved4 = response[19]; pri.ManufacturerId1 = new byte[6]; pri.Reserved5 = response[27]; pri.ManufacturerId2 = new byte[6]; pri.Reserved6 = response[35]; pri.ManufacturerId3 = new byte[6]; pri.Reserved7 = response[43]; pri.Reserved8 = new byte[response.Length - 44]; Array.Copy(response, 21, pri.ManufacturerId1, 0, 6); Array.Copy(response, 29, pri.ManufacturerId2, 0, 6); Array.Copy(response, 37, pri.ManufacturerId3, 0, 6); Array.Copy(response, 44, pri.Reserved8, 0, pri.Reserved8.Length); tmp = new byte[18]; Array.Copy(response, 21, tmp, 0, 6); Array.Copy(response, 29, tmp, 6, 6); // If RW or has part version or has extension code, 3rd manufacturer ID is a write strategy code if ((pri.DiscPhysicalCode & 0x2) > 0 || pri.PartVersion > 0 || pri.ExtensionCode > 0) { pri.WriteStrategyCode2 = (uint)((response[37] << 24) + (response[38] << 16) + (response[39] << 8) + response[40]); } else { Array.Copy(response, 37, tmp, 12, 6); } pri.ManufacturerId = StringHandlers.CToString(tmp, Encoding.ASCII).Trim(); return(pri); }
public static string Prettify(PreRecordedInformation?pri) { if (pri == null) { return(null); } PreRecordedInformation decoded = pri.Value; var sb = new StringBuilder(); if ((decoded.DiscApplicationCode & 0x40) > 0) { sb.AppendLine("Disc for unrestricted use."); if ((decoded.DiscApplicationCode & 0x3F) > 0) { sb.AppendFormat("Invalid purpose field with value {0}", decoded.DiscApplicationCode & 0x3F). AppendLine(); } else { sb.AppendLine("Consumer purpose disc for use in consumer purpose drives"); } } else { sb.AppendLine("Disc for restricted use."); if ((decoded.DiscApplicationCode & 0x3F) > 0) { sb.AppendFormat("Disc for use in special drives according with purpose value {0}", decoded.DiscApplicationCode & 0x3F).AppendLine(); } else { sb.AppendLine("General purpose disc for use in general purpose drives"); } } sb.AppendLine((decoded.DiscPhysicalCode & 0x80) > 0 ? "Disc track pitch is 0,74 μm" : "Unknown track pitch"); sb.AppendLine((decoded.DiscPhysicalCode & 0x40) > 0 ? "Reference velocity is 3,49 m/s" : "Unknown reference velocity"); sb.AppendLine((decoded.DiscPhysicalCode & 0x20) > 0 ? "Disc has 80mm diameter" : "Disc has 120mm diameter"); sb.AppendLine((decoded.DiscPhysicalCode & 0x10) > 0 ? "Disc reflectivity is between 18% and 30%" : "Disc reflectivity is between 45% and 85%"); sb.AppendLine((decoded.DiscPhysicalCode & 0x04) > 0 ? "Dye is organic" : "Dye is phase change"); sb.AppendLine((decoded.DiscPhysicalCode & 0x02) > 0 ? "Disc is RW (rewritable)" : "Disc is R (recordable)"); sb.AppendLine((decoded.DiscPhysicalCode & 0x01) > 0 ? "Wavelength is 650nm" : "Unknown wavelength"); sb.AppendFormat("Last writable ECC block address: 0x{0:X6}", decoded.LastAddressOfDataRecordableArea). AppendLine(); if (decoded.PartVersion > 0) { sb.AppendFormat("Part version {0}", decoded.PartVersion).AppendLine(); } bool rw = (decoded.DiscPhysicalCode & 0x02) > 0; if (rw) { if ((decoded.OPCSuggestedCode & 0xF) > 0) { double recordingPower = 0; switch (decoded.OPCSuggestedCode & 0xF) { case 1: recordingPower = 7.0; break; case 2: recordingPower = 7.5; break; case 3: recordingPower = 8.0; break; case 4: recordingPower = 8.5; break; case 5: recordingPower = 9.0; break; case 6: recordingPower = 9.5; break; case 7: recordingPower = 10.0; break; case 8: recordingPower = 10.5; break; case 9: recordingPower = 11.0; break; case 10: recordingPower = 11.5; break; case 11: recordingPower = 12.0; break; case 12: recordingPower = 12.5; break; case 13: recordingPower = 13.0; break; case 14: recordingPower = 13.5; break; case 15: recordingPower = 14.0; break; } sb.AppendFormat("Recommended recording power is {0} mW", recordingPower).AppendLine(); } else { sb.AppendLine("Recording power is not specified"); } if ((decoded.WaveLengthCode & 0xF) > 0) { double erasingPower = 0; switch (decoded.WaveLengthCode & 0xF) { case 1: erasingPower = 0.38; break; case 2: erasingPower = 0.40; break; case 3: erasingPower = 0.42; break; case 4: erasingPower = 0.44; break; case 5: erasingPower = 0.46; break; case 6: erasingPower = 0.48; break; case 7: erasingPower = 0.50; break; case 8: erasingPower = 0.52; break; case 9: erasingPower = 0.54; break; case 10: erasingPower = 0.56; break; case 11: erasingPower = 0.58; break; case 12: erasingPower = 0.60; break; case 13: erasingPower = 0.62; break; case 14: erasingPower = 0.64; break; case 15: erasingPower = 0.66; break; } sb.AppendFormat("Recommended erasing power ratio is {0} ε", erasingPower).AppendLine(); } else { sb.AppendLine("Erasing power ratio is not specified"); } } else { if ((decoded.OPCSuggestedCode & 0xF) > 0) { double recordingPower = 0; switch (decoded.OPCSuggestedCode & 0xF) { case 1: recordingPower = 6.0; break; case 2: recordingPower = 6.5; break; case 3: recordingPower = 7.0; break; case 4: recordingPower = 7.5; break; case 5: recordingPower = 8.0; break; case 6: recordingPower = 8.5; break; case 7: recordingPower = 9.0; break; case 8: recordingPower = 9.5; break; case 9: recordingPower = 10.0; break; case 10: recordingPower = 10.5; break; case 11: recordingPower = 11.0; break; case 12: recordingPower = 11.5; break; case 13: recordingPower = 12.0; break; } sb.AppendFormat("Recommended recording power is {0} mW", recordingPower).AppendLine(); } if (decoded.WaveLengthCode > 0) { int wavelength = 0; switch (decoded.WaveLengthCode) { case 1: wavelength = 645; break; case 2: wavelength = 646; break; case 3: wavelength = 647; break; case 4: wavelength = 648; break; case 5: wavelength = 649; break; case 6: wavelength = 650; break; case 7: wavelength = 651; break; case 8: wavelength = 652; break; case 9: wavelength = 653; break; case 10: wavelength = 654; break; case 11: wavelength = 655; break; case 12: wavelength = 656; break; case 13: wavelength = 657; break; case 14: wavelength = 658; break; case 15: wavelength = 659; break; case 16: wavelength = 660; break; } sb.AppendFormat("Recommended recording power is {0} mW", wavelength).AppendLine(); } } sb.AppendFormat("Disc manufacturer is {0}", ManufacturerFromPrePit(decoded.ManufacturerId)).AppendLine(); return(sb.ToString()); }