Files
Aaru/DiscImageChef.Decoders/DVD/PFI.cs
Natalia Portillo b2ab03407f * LICENSE.MIT:
* LICENSE.LGPL:
	  Added LICENSE files for LGPL and MIT licenses.

	* DiscImageChef.Devices/Enums.cs:
	* DiscImageChef.Partitions/MBR.cs:
	* DiscImageChef.Partitions/RDB.cs:
	* DiscImageChef.DiscImages/GDI.cs:
	* DiscImageChef.Partitions/Sun.cs:
	* DiscImageChef.DiscImages/VHD.cs:
	* DiscImageChef.Partitions/GPT.cs:
	* DiscImageChef.Filesystems/FFS.cs:
	* DiscImageChef.Filesystems/FAT.cs:
	* DiscImageChef.Partitions/NeXT.cs:
	* DiscImageChef.Devices/Command.cs:
	* DiscImageChef.DiscImages/Nero.cs:
	* DiscImageChef.Decoders/CD/PMA.cs:
	* DiscImageChef.Decoders/CD/TOC.cs:
	* DiscImageChef.Filesystems/BFS.cs:
	* DiscImageChef.Filesystems/ODS.cs:
	* DiscImageChef.Helpers/PrintHex.cs:
	* DiscImageChef.Helpers/Swapping.cs:
	* DiscImageChef.Decoders/DVD/PRI.cs:
	* DiscImageChef.Decoders/DVD/DMI.cs:
	* DiscImageChef.Decoders/DVD/DDS.cs:
	* DiscImageChef.Decoders/DVD/RMD.cs:
	* DiscImageChef.Decoders/DVD/UDI.cs:
	* DiscImageChef.Partitions/Atari.cs:
	* DiscImageChef.Decoders/DVD/BCA.cs:
	* DiscImageChef.Filesystems/SysV.cs:
	* DiscImageChef.Filesystems/HPFS.cs:
	* DiscImageChef.Filesystems/NTFS.cs:
	* DiscImageChef.Filesystems/APFS.cs:
	* DiscImageChef.Decoders/DVD/PFI.cs:
	* DiscImageChef.Decoders/CD/ATIP.cs:
	* DiscImageChef.Filesystems/Acorn.cs:
	* DiscImageChef.DiscImages/CDRWin.cs:
	* DiscImageChef.DiscImages/CDRDAO.cs:
	* DiscImageChef.Filesystems/BTRFS.cs:
	* DiscImageChef.Decoders/Xbox/DMI.cs:
	* DiscImageChef.Helpers/ArrayFill.cs:
	* DiscImageChef.Settings/Settings.cs:
	* DiscImageChef.Filesystems/Opera.cs:
	* DiscImageChef.Filesystems/extFS.cs:
	* DiscImageChef.Decoders/DVD/CPRM.cs:
	* DiscImageChef.Decoders/DVD/ADIP.cs:
	* DiscImageChef.Decoders/CD/Enums.cs:
	* DiscImageChef.Decoders/DVD/AACS.cs:
	* DiscImageChef.Decoders/SCSI/EVPD.cs:
	* DiscImageChef.Filesystems/ProDOS.cs:
	* DiscImageChef.Metadata/MediaType.cs:
	* DiscImageChef.Console/DicConsole.cs:
	* DiscImageChef.Decoders/DVD/Spare.cs:
	* DiscImageChef.Filesystems/ext2FS.cs:
	* DiscImageChef.Decoders/DVD/Enums.cs:
	* DiscImageChef.Filesystems/Symbian.cs:
	* DiscImageChef.Decoders/SCSI/Types.cs:
	* DiscImageChef.Filesystems/UNIXBFS.cs:
	* DiscImageChef.DiscImages/TeleDisk.cs:
	* DiscImageChef.Decoders/SCSI/Sense.cs:
	* DiscImageChef.Decoders/CD/FullTOC.cs:
	* DiscImageChef.Decoders/Blu-ray/DI.cs:
	* DiscImageChef.Decoders/ATA/Errors.cs:
	* DiscImageChef.Filesystems/ISO9660.cs:
	* DiscImageChef.Filesystems/MinixFS.cs:
	* DiscImageChef.Devices/Linux/Enums.cs:
	* DiscImageChef.Filesystems/SolarFS.cs:
	* DiscImageChef.Filesystems/Structs.cs:
	* DiscImageChef.DiscImages/Apple2MG.cs:
	* DiscImageChef.Decoders/SCSI/Modes.cs:
	* DiscImageChef.Metadata/Dimensions.cs:
	* DiscImageChef.Partitions/AppleMap.cs:
	* DiscImageChef.Decoders/Floppy/ISO.cs:
	* DiscImageChef.Decoders/DVD/Layers.cs:
	* DiscImageChef.Decoders/CD/Session.cs:
	* DiscImageChef.Decoders/SCSI/Enums.cs:
	* DiscImageChef.Filesystems/Nintendo.cs:
	* DiscImageChef.Helpers/DateHandlers.cs:
	* DiscImageChef.Filesystems/AmigaDOS.cs:
	* DiscImageChef.DiscImages/ImageInfo.cs:
	* DiscImageChef.Checksums/MD5Context.cs:
	* DiscImageChef.Devices/Linux/Extern.cs:
	* DiscImageChef.Filesystems/AppleHFS.cs:
	* DiscImageChef.Filesystems/AppleMFS.cs:
	* DiscImageChef.Helpers/ArrayIsEmpty.cs:
	* DiscImageChef.Decoders/Blu-ray/BCA.cs:
	* DiscImageChef.Decoders/Blu-ray/DDS.cs:
	* DiscImageChef.Filesystems/PCEngine.cs:
	* DiscImageChef.Decoders/ATA/Identify.cs:
	* DiscImageChef.Devices/Linux/Command.cs:
	* DiscImageChef.Devices/FreeBSD/Enums.cs:
	* DiscImageChef.Decoders/SCSI/Inquiry.cs:
	* DiscImageChef.Metadata/DeviceReport.cs:
	* DiscImageChef.Decoders/Floppy/Amiga.cs:
	* DiscImageChef.Devices/Linux/Structs.cs:
	* DiscImageChef.Devices/Windows/Enums.cs:
	* DiscImageChef.Decoders/DVD/CSS&CPRM.cs:
	* DiscImageChef.Checksums/SHA1Context.cs:
	* DiscImageChef.DiscImages/DiskCopy42.cs:
	* DiscImageChef.Partitions/PartPlugin.cs:
	* DiscImageChef.CommonTypes/Partition.cs:
	* DiscImageChef.Decoders/Floppy/Enums.cs:
	* DiscImageChef.CommonTypes/MediaType.cs:
	* DiscImageChef.Decoders/Floppy/Apple2.cs:
	* DiscImageChef.Devices/Windows/Extern.cs:
	* DiscImageChef.Decoders/SCSI/MMC/CPRM.cs:
	* DiscImageChef.Helpers/StringHandlers.cs:
	* DiscImageChef.DiscImages/ImagePlugin.cs:
	* DiscImageChef.Checksums/CRC64Context.cs:
	* DiscImageChef.Checksums/CRC32Context.cs:
	* DiscImageChef.DiscImages/ZZZRawImage.cs:
	* DiscImageChef.Checksums/CRC16Context.cs:
	* DiscImageChef.Filesystems/LisaFS/Dir.cs:
	* DiscImageChef.Decoders/DVD/Cartridge.cs:
	* DiscImageChef.Decoders/Blu-ray/Spare.cs:
	* DiscImageChef.Filesystems/Filesystem.cs:
	* DiscImageChef.Decoders/SCSI/MMC/AACS.cs:
	* DiscImageChef.Devices/FreeBSD/Extern.cs:
	* DiscImageChef.Devices/Device/Commands.cs:
	* DiscImageChef.Checksums/SHA384Context.cs:
	* DiscImageChef.Devices/FreeBSD/Command.cs:
	* DiscImageChef.Checksums/SHA512Context.cs:
	* DiscImageChef.Decoders/SCSI/MMC/Enums.cs:
	* DiscImageChef.Devices/Windows/Command.cs:
	* DiscImageChef.Devices/FreeBSD/Structs.cs:
	* DiscImageChef.Devices/Windows/Structs.cs:
	* DiscImageChef.Filesystems/LisaFS/Info.cs:
	* DiscImageChef.Checksums/SHA256Context.cs:
	* DiscImageChef.Filesystems/LisaFS/File.cs:
	* DiscImageChef.Filesystems/AppleHFSPlus.cs:
	* DiscImageChef.Filesystems/LisaFS/Super.cs:
	* DiscImageChef.Filesystems/LisaFS/Xattr.cs:
	* DiscImageChef.Checksums/Adler32Context.cs:
	* DiscImageChef.Decoders/Floppy/System34.cs:
	* DiscImageChef.Checksums/SpamSumContext.cs:
	* DiscImageChef.Decoders/SCSI/MMC/Hybrid.cs:
	* DiscImageChef.Devices/Device/Variables.cs:
	* DiscImageChef.Filesystems/LisaFS/Consts.cs:
	* DiscImageChef.Filesystems/LisaFS/LisaFS.cs:
	* DiscImageChef.Decoders/Floppy/Commodore.cs:
	* DiscImageChef.Checksums/FletcherContext.cs:
	* DiscImageChef.Filesystems/LisaFS/Extent.cs:
	* DiscImageChef.Devices/Device/Destructor.cs:
	* DiscImageChef.Decoders/Floppy/AppleSony.cs:
	* DiscImageChef.Filesystems/LisaFS/Structs.cs:
	* DiscImageChef.Decoders/SCSI/VendorString.cs:
	* DiscImageChef.Decoders/SCSI/MMC/Features.cs:
	* DiscImageChef.Devices/Device/Constructor.cs:
	* DiscImageChef.Checksums/RIPEMD160Context.cs:
	* DiscImageChef.Decoders/CD/CDTextOnLeadIn.cs:
	* DiscImageChef.Decoders/Blu-ray/Cartridge.cs:
	* DiscImageChef.Decoders/Floppy/System3740.cs:
	* DiscImageChef.Filesystems/LisaFS/Encoding.cs:
	* DiscImageChef.Decoders/SCSI/ModesEncoders.cs:
	* DiscImageChef.CommonTypes/MediaTypeFromSCSI.cs:
	* DiscImageChef.Helpers/BigEndianBitConverter.cs:
	* DiscImageChef.Decoders/Floppy/Perpendicular.cs:
	* DiscImageChef.Decoders/SCSI/SSC/BlockLimits.cs:
	* DiscImageChef.Decoders/SCSI/MMC/WriteProtect.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/HP.cs:
	* DiscImageChef.Devices/Device/AtaCommands/Cfa.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/NEC.cs:
	* DiscImageChef.Helpers/EndianAwareBinaryReader.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/MMC.cs:
	* DiscImageChef.Devices/Device/AtaCommands/MCPT.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/SSC.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/SPC.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/SMC.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/SBC.cs:
	* DiscImageChef.Metadata/Properties/AssemblyInfo.cs:
	* DiscImageChef.Devices/Device/AtaCommands/Atapi.cs:
	* DiscImageChef.Devices/Device/AtaCommands/Ata28.cs:
	* DiscImageChef.Devices/Device/AtaCommands/Smart.cs:
	* DiscImageChef.Decoders/SCSI/SSC/DensitySupport.cs:
	* DiscImageChef.Devices/Device/AtaCommands/Ata48.cs:
	* DiscImageChef.Decoders/SCSI/MMC/DiscInformation.cs:
	* DiscImageChef.Devices/Device/AtaCommands/AtaCHS.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/SyQuest.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/Plextor.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/Plasmon.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/Pioneer.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/Adaptec.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/Fujitsu.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/HL-DT-ST.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/Certance.cs:
	* DiscImageChef.Decoders/SCSI/DiscStructureCapabilities.cs:
	* DiscImageChef.Devices/Device/ScsiCommands/ArchiveCorp.cs:
	  Relicensed as LGPL.
	Updated standard header.

	* DiscImageChef/Main.cs:
	* DiscImageChef/Plugins.cs:
	* DiscImageChef/Options.cs:
	* DiscImageChef/Commands/Ls.cs:
	* DiscImageChef/Core/IBGLog.cs:
	* DiscImageChef/Core/MHDDLog.cs:
	* DiscImageChef/AssemblyInfo.cs:
	* DiscImageChef/Core/Checksum.cs:
	* DiscImageChef/Commands/Decode.cs:
	* DiscImageChef/Core/Statistics.cs:
	* DiscImageChef/Commands/Verify.cs:
	* DiscImageChef/Commands/Formats.cs:
	* DiscImageChef/Commands/Entropy.cs:
	* DiscImageChef/Commands/Compare.cs:
	* DiscImageChef.Interop/DetectOS.cs:
	* DiscImageChef/Commands/Analyze.cs:
	* DiscImageChef/Commands/Commands.cs:
	* DiscImageChef/Commands/PrintHex.cs:
	* DiscImageChef/Commands/Checksum.cs:
	* DiscImageChef/DetectImageFormat.cs:
	* DiscImageChef/Commands/DumpMedia.cs:
	* DiscImageChef/Commands/Benchmark.cs:
	* DiscImageChef/Commands/Configure.cs:
	* DiscImageChef/Commands/MediaInfo.cs:
	* DiscImageChef.Interop/PlatformID.cs:
	* DiscImageChef/Commands/MediaScan.cs:
	* DiscImageChef/Commands/Statistics.cs:
	* DiscImageChef/Commands/DeviceInfo.cs:
	* DiscImageChef.Checksums/ReedSolomon.cs:
	* DiscImageChef/Commands/DeviceReport.cs:
	* DiscImageChef/Commands/ExtractFiles.cs:
	* DiscImageChef.Checksums/CDChecksums.cs:
	* DiscImageChef/Commands/CreateSidecar.cs:
	  Updated standard header.

	* DiscImageChef.Checksums/DiscImageChef.Checksums.csproj:
	  Relicensed project as LGPL.
	Updated standard header.
	Embed license as resource.

	* DiscImageChef.Console/DiscImageChef.Console.csproj:
	* DiscImageChef.Devices/DiscImageChef.Devices.csproj:
	* DiscImageChef.Helpers/DiscImageChef.Helpers.csproj:
	* DiscImageChef.Settings/DiscImageChef.Settings.csproj:
	* DiscImageChef.Decoders/DiscImageChef.Decoders.csproj:
	* DiscImageChef.Metadata/DiscImageChef.Metadata.csproj:
	* DiscImageChef.Partitions/DiscImageChef.Partitions.csproj:
	* DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj:
	* DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj:
	* DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj:
	  Relicensed as LGPL.
	Updated standard header.
	Embed license as resource.

	* DiscImageChef/DiscImageChef.csproj:
	* DiscImageChef.Interop/DiscImageChef.Interop.csproj:
	  Updated standard header.
	Embed license as resource.
2016-07-28 18:13:49 +01:00

1669 lines
69 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : PFI.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Device structures decoders.
//
// --[ Description ] ----------------------------------------------------------
//
// Records DVD Physical Format Information.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2016 Natalia Portillo
// ****************************************************************************/
using System;
using System.Text;
namespace DiscImageChef.Decoders.DVD
{
/// <summary>
/// Information from the following standards:
/// ANSI X3.304-1997
/// T10/1048-D revision 9.0
/// T10/1048-D revision 10a
/// T10/1228-D revision 7.0c
/// T10/1228-D revision 11a
/// T10/1363-D revision 10g
/// T10/1545-D revision 1d
/// T10/1545-D revision 5
/// T10/1545-D revision 5a
/// T10/1675-D revision 2c
/// T10/1675-D revision 4
/// T10/1836-D revision 2g
/// ECMA 267: 120 mm DVD - Read-Only Disk
/// ECMA 268: 80 mm DVD - Read-Only Disk
/// ECMA 272: 120 mm DVD Rewritable Disk (DVD-RAM)
/// ECMA 274: Data Interchange on 120 mm Optical Disk using +RW Format - Capacity: 3,0 Gbytes and 6,0 Gbytes
/// ECMA 279: 80 mm (1,23 Gbytes per side) and 120 mm (3,95 Gbytes per side) DVD-Recordable Disk (DVD-R)
/// ECMA 330: 120 mm (4,7 Gbytes per side) and 80 mm (1,46 Gbytes per side) DVD Rewritable Disk (DVD-RAM)
/// ECMA 337: Data Interchange on 120 mm and 80 mm Optical Disk using +RW Format - Capacity: 4,7 and 1,46 Gbytes per Side
/// ECMA 338: 80 mm (1,46 Gbytes per side) and 120 mm (4,70 Gbytes per side) DVD Re-recordable Disk (DVD-RW)
/// ECMA 349: Data Interchange on 120 mm and 80 mm Optical Disk using +R Format - Capacity: 4,7 and 1,46 Gbytes per Side
/// ECMA 359: 80 mm (1,46 Gbytes per side) and 120 mm (4,70 Gbytes per side) DVD Recordable Disk (DVD-R)
/// ECMA 364: Data Interchange on 120 mm and 80 mm Optical Disk using +R DL Format - Capacity 8,55 and 2,66 Gbytes per Side
/// ECMA 365: Data Interchange on 60 mm Read-Only ODC - Capacity: 1,8 Gbytes (UMD™)
/// ECMA 371: Data Interchange on 120 mm and 80 mm Optical Disk using +RW HS Format - Capacity 4,7 and 1,46 Gbytes per side
/// ECMA 374: Data Interchange on 120 mm and 80 mm Optical Disk using +RW DL Format - Capacity 8,55 and 2,66 Gbytes per side
/// ECMA 382: 120 mm (8,54 Gbytes per side) and 80 mm (2,66 Gbytes per side) DVD Recordable Disk for Dual Layer (DVD-R for DL)
/// ECMA 384: 120 mm (8,54 Gbytes per side) and 80 mm (2,66 Gbytes per side) DVD Re-recordable Disk for Dual Layer (DVD-RW for DL)
/// </summary>
public static class PFI
{
public struct PhysicalFormatInformation
{
/// <summary>
/// Bytes 0 to 1
/// Data length
/// </summary>
public UInt16 DataLength;
/// <summary>
/// Byte 2
/// Reserved
/// </summary>
public byte Reserved1;
/// <summary>
/// Byte 3
/// Reserved
/// </summary>
public byte Reserved2;
#region PFI common to all
/// <summary>
/// Byte 4, bits 7 to 4
/// Disk category field
/// </summary>
public DiskCategory DiskCategory;
/// <summary>
/// Byte 4, bits 3 to 0
/// Media version
/// </summary>
public byte PartVersion;
/// <summary>
/// Byte 5, bits 7 to 4
/// 120mm if 0, 80mm if 1. If UMD (60mm) 0 also. Reserved rest of values
/// </summary>
public DVDSize DiscSize;
/// <summary>
/// Byte 5, bits 3 to 0
/// Maximum data rate
/// </summary>
public MaximumRateField MaximumRate;
/// <summary>
/// Byte 6, bit 7
/// Reserved
/// </summary>
public bool Reserved3;
/// <summary>
/// Byte 6, bits 6 to 5
/// Number of layers
/// </summary>
public byte Layers;
/// <summary>
/// Byte 6, bit 4
/// Track path
/// </summary>
public bool TrackPath;
/// <summary>
/// Byte 6, bits 3 to 0
/// Layer type
/// </summary>
public LayerTypeFieldMask LayerType;
/// <summary>
/// Byte 7, bits 7 to 4
/// Linear density field
/// </summary>
public LinearDensityField LinearDensity;
/// <summary>
/// Byte 7, bits 3 to 0
/// Track density field
/// </summary>
public TrackDensityField TrackDensity;
/// <summary>
/// Bytes 8 to 11
/// PSN where Data Area starts
/// </summary>
public UInt32 DataAreaStartPSN;
/// <summary>
/// Bytes 12 to 15
/// PSN where Data Area ends
/// </summary>
public UInt32 DataAreaEndPSN;
/// <summary>
/// Bytes 16 to 19
/// PSN where Data Area ends in Layer 0
/// </summary>
public UInt32 Layer0EndPSN;
/// <summary>
/// Byte 20, bit 7
/// True if BCA exists. GC/Wii discs do not have this bit set, but there is a BCA, making it unreadable in normal DVD drives
/// </summary>
public bool BCA;
/// <summary>
/// Byte 20, bits 6 to 0
/// Reserved
/// </summary>
public byte Reserved4;
#endregion PFI common to all
#region UMD PFI
/// <summary>
/// Bytes 21 to 22
/// UMD only, media attribute, application-defined, part of media specific in rest of discs
/// </summary>
public UInt16 MediaAttribute;
#endregion UMD PFI
#region DVD-RAM PFI
/// <summary>
/// Byte 36
/// Disc type, respecting case recordability
/// </summary>
public DVDRAMDiscType DiscType;
#endregion DVD-RAM PFI
#region DVD-RAM PFI, Version 0001b
/// <summary>
/// Byte 52
/// Byte 504 in Version 0110b
/// Linear velocity, in tenths of m/s
/// </summary>
public byte Velocity;
/// <summary>
/// Byte 53
/// Byte 505 in Version 0110b
/// Read power on disk surface, tenths of mW
/// </summary>
public byte ReadPower;
/// <summary>
/// Byte 54
/// Byte 507 in Version 0110b
/// Peak power on disk surface for recording land tracks
/// </summary>
public byte PeakPower;
/// <summary>
/// Byte 55
/// Bias power on disk surface for recording land tracks
/// </summary>
public byte BiasPower;
/// <summary>
/// Byte 56
/// First pulse starting time for recording on land tracks, ns
/// </summary>
public byte FirstPulseStart;
/// <summary>
/// Byte 57
/// Byte 515 in Version 0110b
/// First pulse ending time for recording on land tracks
/// </summary>
public byte FirstPulseEnd;
/// <summary>
/// Byte 58
/// Byte 518 in Version 0110b
/// Multiple-pulse duration time for recording on land tracks
/// </summary>
public byte MultiplePulseDuration;
/// <summary>
/// Byte 59
/// Byte 519 in Version 0110b
/// Last pulse starting time for recording on land tracks
/// </summary>
public byte LastPulseStart;
/// <summary>
/// Byte 60
/// Las pulse ending time for recording on land tracks
/// </summary>
public byte LastPulseEnd;
/// <summary>
/// Byte 61
/// Bias power duration for recording on land tracks
/// </summary>
public byte BiasPowerDuration;
/// <summary>
/// Byte 62
/// Byte 511 on Version 0110b
/// Peak power for recording on groove tracks
/// </summary>
public byte PeakPowerGroove;
/// <summary>
/// Byte 63
/// Bias power for recording on groove tracks
/// </summary>
public byte BiasPowerGroove;
/// <summary>
/// Byte 64
/// First pulse starting time on groove tracks
/// </summary>
public byte FirstPulseStartGroove;
/// <summary>
/// Byte 65
/// First pulse ending time on groove tracks
/// </summary>
public byte FirstPulseEndGroove;
/// <summary>
/// Byte 66
/// Multiple-pulse duration time on groove tracks
/// </summary>
public byte MultiplePulseDurationGroove;
/// <summary>
/// Byte 67
/// Last pulse starting time on groove tracks
/// </summary>
public byte LastPulseStartGroove;
/// <summary>
/// Byte 68
/// Last pulse ending time on groove tracks
/// </summary>
public byte LastPulseEndGroove;
/// <summary>
/// Byte 69
/// Bias power duration for recording on groove tracks
/// </summary>
public byte BiasPowerDurationGroove;
#endregion DVD-RAM PFI, Version 0001b
#region DVD-R PFI, DVD-RW PFI
/// <summary>
/// Bytes 36 to 39
/// Sector number of the first sector of the current Border Out
/// </summary>
public UInt32 CurrentBorderOutSector;
/// <summary>
/// Bytes 40 to 43
/// Sector number of the first sector of the next Border In
/// </summary>
public UInt32 NextBorderInSector;
#endregion DVD-R PFI, DVD-RW PFI
#region DVD+RW PFI
/// <summary>
/// Byte 36
/// Linear velocities
/// 0 = CLV from 4,90 m/s to 6,25 m/s
/// 1 = CAV from 3,02 m/s to 7,35 m/s
/// </summary>
public byte RecordingVelocity;
/// <summary>
/// Byte 37
/// Maximum read power in milliwatts at maximum velocity
/// mW = 20 * (value - 1)
/// </summary>
public byte ReadPowerMaxVelocity;
/// <summary>
/// Byte 38
/// Indicative value of Ptarget in mW at maximum velocity
/// </summary>
public byte PIndMaxVelocity;
/// <summary>
/// Byte 39
/// Peak power multiplication factor at maximum velocity
/// </summary>
public byte PMaxVelocity;
/// <summary>
/// Byte 40
/// Bias1/write power ration at maximum velocity
/// </summary>
public byte E1MaxVelocity;
/// <summary>
/// Byte 41
/// Bias2/write power ration at maximum velocity
/// </summary>
public byte E2MaxVelocity;
/// <summary>
/// Byte 42
/// Target value for γ, γtarget at the maximum velocity
/// </summary>
public byte YTargetMaxVelocity;
/// <summary>
/// Byte 43
/// Maximum read power in milliwatts at reference velocity (4,90 m/s)
/// mW = 20 * (value - 1)
/// </summary>
public byte ReadPowerRefVelocity;
/// <summary>
/// Byte 44
/// Indicative value of Ptarget in mW at reference velocity (4,90 m/s)
/// </summary>
public byte PIndRefVelocity;
/// <summary>
/// Byte 45
/// Peak power multiplication factor at reference velocity (4,90 m/s)
/// </summary>
public byte PRefVelocity;
/// <summary>
/// Byte 46
/// Bias1/write power ration at reference velocity (4,90 m/s)
/// </summary>
public byte E1RefVelocity;
/// <summary>
/// Byte 47
/// Bias2/write power ration at reference velocity (4,90 m/s)
/// </summary>
public byte E2RefVelocity;
/// <summary>
/// Byte 48
/// Target value for γ, γtarget at the reference velocity (4,90 m/s)
/// </summary>
public byte YTargetRefVelocity;
/// <summary>
/// Byte 49
/// Maximum read power in milliwatts at minimum velocity
/// mW = 20 * (value - 1)
/// </summary>
public byte ReadPowerMinVelocity;
/// <summary>
/// Byte 50
/// Indicative value of Ptarget in mW at minimum velocity
/// </summary>
public byte PIndMinVelocity;
/// <summary>
/// Byte 51
/// Peak power multiplication factor at minimum velocity
/// </summary>
public byte PMinVelocity;
/// <summary>
/// Byte 52
/// Bias1/write power ration at minimum velocity
/// </summary>
public byte E1MinVelocity;
/// <summary>
/// Byte 53
/// Bias2/write power ration at minimum velocity
/// </summary>
public byte E2MinVelocity;
/// <summary>
/// Byte 54
/// Target value for γ, γtarget at the minimum velocity
/// </summary>
public byte YTargetMinVelocity;
#endregion DVD+RW PFI
#region DVD-RAM PFI, version 0110b
/// <summary>
/// Byte 506, bit 7
/// Mode of adaptative write pulse control
/// </summary>
public bool AdaptativeWritePulseControlFlag;
/// <summary>
/// Byte 508
/// Bias power 1 on disk surface for recording land tracks
/// </summary>
public byte BiasPower1;
/// <summary>
/// Byte 509
/// Bias power 2 on disk surface for recording land tracks
/// </summary>
public byte BiasPower2;
/// <summary>
/// Byte 510
/// Bias power 3 on disk surface for recording land tracks
/// </summary>
public byte BiasPower3;
/// <summary>
/// Byte 512
/// Bias power 1 on disk surface for recording groove tracks
/// </summary>
public byte BiasPower1Groove;
/// <summary>
/// Byte 513
/// Bias power 2 on disk surface for recording groove tracks
/// </summary>
public byte BiasPower2Groove;
/// <summary>
/// Byte 514
/// Bias power 3 on disk surface for recording groove tracks
/// </summary>
public byte BiasPower3Groove;
/// <summary>
/// Byte 516
/// First pulse duration
/// </summary>
public byte FirstPulseDuration;
/// <summary>
/// Byte 520
/// Bias power 2 duration on land tracks at Velocity 1
/// </summary>
public byte BiasPower2Duration;
/// <summary>
/// Byte 521
/// First pulse start time, at Mark 3T and Leading Space 3T
/// </summary>
public byte FirstPulseStart3TSpace3T;
/// <summary>
/// Byte 522
/// First pulse start time, at Mark 4T and Leading Space 3T
/// </summary>
public byte FirstPulseStart4TSpace3T;
/// <summary>
/// Byte 523
/// First pulse start time, at Mark 5T and Leading Space 3T
/// </summary>
public byte FirstPulseStart5TSpace3T;
/// <summary>
/// Byte 524
/// First pulse start time, at Mark >5T and Leading Space 3T
/// </summary>
public byte FirstPulseStartSpace3T;
/// <summary>
/// Byte 525
/// First pulse start time, at Mark 3T and Leading Space 4T
/// </summary>
public byte FirstPulseStart3TSpace4T;
/// <summary>
/// Byte 526
/// First pulse start time, at Mark 4T and Leading Space 4T
/// </summary>
public byte FirstPulseStart4TSpace4T;
/// <summary>
/// Byte 527
/// First pulse start time, at Mark 5T and Leading Space 4T
/// </summary>
public byte FirstPulseStart5TSpace4T;
/// <summary>
/// Byte 528
/// First pulse start time, at Mark >5T and Leading Space 4T
/// </summary>
public byte FirstPulseStartSpace4T;
/// <summary>
/// Byte 529
/// First pulse start time, at Mark 3T and Leading Space 5T
/// </summary>
public byte FirstPulseStart3TSpace5T;
/// <summary>
/// Byte 530
/// First pulse start time, at Mark 4T and Leading Space 5T
/// </summary>
public byte FirstPulseStart4TSpace5T;
/// <summary>
/// Byte 531
/// First pulse start time, at Mark 5T and Leading Space 5T
/// </summary>
public byte FirstPulseStart5TSpace5T;
/// <summary>
/// Byte 532
/// First pulse start time, at Mark >5T and Leading Space 5T
/// </summary>
public byte FirstPulseStartSpace5T;
/// <summary>
/// Byte 533
/// First pulse start time, at Mark 3T and Leading Space >5T
/// </summary>
public byte FirstPulseStart3TSpace;
/// <summary>
/// Byte 534
/// First pulse start time, at Mark 4T and Leading Space >5T
/// </summary>
public byte FirstPulseStart4TSpace;
/// <summary>
/// Byte 535
/// First pulse start time, at Mark 5T and Leading Space >5T
/// </summary>
public byte FirstPulseStart5TSpace;
/// <summary>
/// Byte 536
/// First pulse start time, at Mark >5T and Leading Space >5T
/// </summary>
public byte FirstPulseStartSpace;
/// <summary>
/// Byte 537
/// First pulse start time, at Mark 3T and Trailing Space 3T
/// </summary>
public byte FirstPulse3TStartTSpace3T;
/// <summary>
/// Byte 538
/// First pulse start time, at Mark 4T and Trailing Space 3T
/// </summary>
public byte FirstPulse4TStartTSpace3T;
/// <summary>
/// Byte 539
/// First pulse start time, at Mark 5T and Trailing Space 3T
/// </summary>
public byte FirstPulse5TStartTSpace3T;
/// <summary>
/// Byte 540
/// First pulse start time, at Mark >5T and Trailing Space 3T
/// </summary>
public byte FirstPulseStartTSpace3T;
/// <summary>
/// Byte 541
/// First pulse start time, at Mark 3T and Trailing Space 4T
/// </summary>
public byte FirstPulse3TStartTSpace4T;
/// <summary>
/// Byte 542
/// First pulse start time, at Mark 4T and Trailing Space 4T
/// </summary>
public byte FirstPulse4TStartTSpace4T;
/// <summary>
/// Byte 543
/// First pulse start time, at Mark 5T and Trailing Space 4T
/// </summary>
public byte FirstPulse5TStartTSpace4T;
/// <summary>
/// Byte 544
/// First pulse start time, at Mark >5T and Trailing Space 4T
/// </summary>
public byte FirstPulseStartTSpace4T;
/// <summary>
/// Byte 545
/// First pulse start time, at Mark 3T and Trailing Space 5T
/// </summary>
public byte FirstPulse3TStartTSpace5T;
/// <summary>
/// Byte 546
/// First pulse start time, at Mark 4T and Trailing Space 5T
/// </summary>
public byte FirstPulse4TStartTSpace5T;
/// <summary>
/// Byte 547
/// First pulse start time, at Mark 5T and Trailing Space 5T
/// </summary>
public byte FirstPulse5TStartTSpace5T;
/// <summary>
/// Byte 548
/// First pulse start time, at Mark >5T and Trailing Space 5T
/// </summary>
public byte FirstPulseStartTSpace5T;
/// <summary>
/// Byte 549
/// First pulse start time, at Mark 3T and Trailing Space >5T
/// </summary>
public byte FirstPulse3TStartTSpace;
/// <summary>
/// Byte 550
/// First pulse start time, at Mark 4T and Trailing Space >5T
/// </summary>
public byte FirstPulse4TStartTSpace;
/// <summary>
/// Byte 551
/// First pulse start time, at Mark 5T and Trailing Space >5T
/// </summary>
public byte FirstPulse5TStartTSpace;
/// <summary>
/// Byte 552
/// First pulse start time, at Mark >5T and Trailing Space >5T
/// </summary>
public byte FirstPulseStartTSpace;
/// <summary>
/// Bytes 553 to 600
/// Disk manufacturer's name, space-padded
/// </summary>
public string DiskManufacturer;
/// <summary>
/// Bytes 601 to 616
/// Disk manufacturer's supplementary information
/// </summary>
public string DiskManufacturerSupplementary;
/// <summary>
/// Bytes 617 to 627
/// Write power control parameters
/// </summary>
public byte[] WritePowerControlParams;
/// <summary>
/// Byte 619
/// Ratio of peak power for land tracks to threshold peak power for land tracks
/// </summary>
public byte PowerRatioLandThreshold;
/// <summary>
/// Byte 620
/// Target asymmetry
/// </summary>
public byte TargetAsymmetry;
/// <summary>
/// Byte 621
/// Temporary peak power
/// </summary>
public byte TemporaryPeakPower;
/// <summary>
/// Byte 622
/// Temporary bias power 1
/// </summary>
public byte TemporaryBiasPower1;
/// <summary>
/// Byte 623
/// Temporary bias power 2
/// </summary>
public byte TemporaryBiasPower2;
/// <summary>
/// Byte 624
/// Temporary bias power 3
/// </summary>
public byte TemporaryBiasPower3;
/// <summary>
/// Byte 625
/// Ratio of peak power for groove tracks to threshold peak power for groove tracks
/// </summary>
public byte PowerRatioGrooveThreshold;
/// <summary>
/// Byte 626
/// Ratio of peak power for land tracks to threshold 6T peak power for land tracks
/// </summary>
public byte PowerRatioLandThreshold6T;
/// <summary>
/// Byte 627
/// Ratio of peak power for groove tracks to threshold 6T peak power for groove tracks
/// </summary>
public byte PowerRatioGrooveThreshold6T;
#endregion DVD-RAM PFI, version 0110b
#region DVD+RW PFI, DVD+R PFI, DVD+R DL PFI and DVD+RW DL PFI
/// <summary>
/// Byte 20, bit 6
/// If set indicates data zone contains extended information for VCPS
/// </summary>
public bool VCPS;
/// <summary>
/// Byte 21
/// Indicates restricted usage disk
/// </summary>
public byte ApplicationCode;
/// <summary>
/// Byte 22
/// Bitmap of extended information block presence
/// </summary>
public byte ExtendedInformation;
/// <summary>
/// Bytes 23 to 30
/// Disk manufacturer ID, null-padded
/// </summary>
public string DiskManufacturerID;
/// <summary>
/// Bytes 31 to 33
/// Media type ID, null-padded
/// </summary>
public string MediaTypeID;
/// <summary>
/// Byte 34
/// Product revision number
/// </summary>
public byte ProductRevision;
/// <summary>
/// Byte 35
/// Indicates how many bytes, up to 63, are used in ADIP's PFI
/// </summary>
public byte PFIUsedInADIP;
#endregion DVD+RW PFI, DVD+R PFI, DVD+R DL PFI and DVD+RW DL PFI
#region DVD+RW PFI, version 0010b
/// <summary>
/// Byte 55
/// Ttop first pulse duration
/// </summary>
public byte TopFirstPulseDuration;
/// <summary>
/// Byte 56
/// Tmp multi pulse duration
/// </summary>
public byte MultiPulseDuration;
/// <summary>
/// Byte 57
/// dTtop first pulse lead time
/// </summary>
public byte FirstPulseLeadTime;
/// <summary>
/// Byte 58
/// dTera erase lead time at reference velocity
/// </summary>
public byte EraseLeadTimeRefVelocity;
/// <summary>
/// Byte 59
/// dTera erase lead time at upper velocity
/// </summary>
public byte EraseLeadTimeUppVelocity;
#endregion DVD+RW PFI, version 0010b
#region DVD+R PFI version 0001b and DVD+R DL PFI version 0001b
/// <summary>
/// Byte 36
/// Primary recording velocity for the basic write strategy
/// </summary>
public byte PrimaryVelocity;
/// <summary>
/// Byte 37
/// Upper recording velocity for the basic write strategy
/// </summary>
public byte UpperVelocity;
/// <summary>
/// Byte 38
/// Wavelength λIND
/// </summary>
public byte Wavelength;
/// <summary>
/// Byte 39
/// Normalized write power dependency on wavelength (dP/dλ)/(PIND/λIND)
/// </summary>
public byte NormalizedPowerDependency;
/// <summary>
/// Byte 40
/// Maximum read power at primary velocity
/// </summary>
public byte MaximumPowerAtPrimaryVelocity;
/// <summary>
/// Byte 41
/// Pind at primary velocity
/// </summary>
public byte PindAtPrimaryVelocity;
/// <summary>
/// Byte 42
/// βtarget at primary velocity
/// </summary>
public byte BtargetAtPrimaryVelocity;
/// <summary>
/// Byte 43
/// Maximum read power at upper velocity
/// </summary>
public byte MaximumPowerAtUpperVelocity;
/// <summary>
/// Byte 44
/// Pind at primary velocity
/// </summary>
public byte PindAtUpperVelocity;
/// <summary>
/// Byte 45
/// βtarget at upper velocity
/// </summary>
public byte BtargetAtUpperVelocity;
/// <summary>
/// Byte 46
/// Ttop (≥4T) first pulse duration for cm ≥4T at Primary velocity
/// </summary>
public byte FirstPulseDuration4TPrimaryVelocity;
/// <summary>
/// Byte 47
/// Ttop (=3T) first pulse duration for cm =3T at Primary velocity
/// </summary>
public byte FirstPulseDuration3TPrimaryVelocity;
/// <summary>
/// Byte 48
/// Tmp multi pulse duration at Primary velocity
/// </summary>
public byte MultiPulseDurationPrimaryVelocity;
/// <summary>
/// Byte 49
/// Tlp last pulse duration at Primary velocity
/// </summary>
public byte LastPulseDurationPrimaryVelocity;
/// <summary>
/// Byte 50
/// dTtop (≥4T) first pulse lead time for cm ≥4T at Primary velocity
/// </summary>
public byte FirstPulseLeadTime4TPrimaryVelocity;
/// <summary>
/// Byte 51
/// dTtop (=3T) first pulse lead time for cm =3T at Primary velocity
/// </summary>
public byte FirstPulseLeadTime3TPrimaryVelocity;
/// <summary>
/// Byte 52
/// dTle first pulse leading edge shift for ps =3T at Primary velocity
/// </summary>
public byte FirstPulseLeadingEdgePrimaryVelocity;
/// <summary>
/// Byte 53
/// Ttop (≥4T) first pulse duration for cm ≥4T at Upper velocity
/// </summary>
public byte FirstPulseDuration4TUpperVelocity;
/// <summary>
/// Byte 54
/// Ttop (=3T) first pulse duration for cm =3T at Upper velocity
/// </summary>
public byte FirstPulseDuration3TUpperVelocity;
/// <summary>
/// Byte 55
/// Tmp multi pulse duration at Upper velocity
/// </summary>
public byte MultiPulseDurationUpperVelocity;
/// <summary>
/// Byte 56
/// Tlp last pulse duration at Upper velocity
/// </summary>
public byte LastPulseDurationUpperVelocity;
/// <summary>
/// Byte 57
/// dTtop (≥4T) first pulse lead time for cm ≥4T at Upper velocity
/// </summary>
public byte FirstPulseLeadTime4TUpperVelocity;
/// <summary>
/// Byte 58
/// dTtop (=3T) first pulse lead time for cm =3T at Upper velocity
/// </summary>
public byte FirstPulseLeadTime3TUpperVelocity;
/// <summary>
/// Byte 59
/// dTle first pulse leading edge shift for ps =3T at Upper velocity
/// </summary>
public byte FirstPulseLeadingEdgeUpperVelocity;
#endregion DVD+R PFI version 0001b and DVD+R DL PFI version 0001b
#region DVD+R DL PFI version 0001b
/// <summary>
/// Byte 34, bits 7 to 6
/// </summary>
public DVDLayerStructure LayerStructure;
#endregion DVD+R DL PFI version 0001b
#region DVD+RW DL PFI
/// <summary>
/// Byte 36
/// Primary recording velocity for the basic write strategy
/// </summary>
public byte BasicPrimaryVelocity;
/// <summary>
/// Byte 37
/// Maximum read power at Primary velocity
/// </summary>
public byte MaxReadPowerPrimaryVelocity;
/// <summary>
/// Byte 38
/// PIND at Primary velocity
/// </summary>
public byte PindPrimaryVelocity;
/// <summary>
/// Byte 39
/// ρ at Primary velocity
/// </summary>
public byte PPrimaryVelocity;
/// <summary>
/// Byte 40
/// ε1 at Primary velocity
/// </summary>
public byte E1PrimaryVelocity;
/// <summary>
/// Byte 41
/// ε2 at Primary velocity
/// </summary>
public byte E2PrimaryVelocity;
/// <summary>
/// Byte 42
/// γtarget at Primary velocity
/// </summary>
public byte YtargetPrimaryVelocity;
/// <summary>
/// Byte 43
/// β optimum at Primary velocity
/// </summary>
public byte BOptimumPrimaryVelocity;
/// <summary>
/// Byte 46
/// Ttop first pulse duration
/// </summary>
public byte TFirstPulseDuration;
/// <summary>
/// Byte 47
/// Tmp multi pulse duration
/// </summary>
public byte TMultiPulseDuration;
/// <summary>
/// Byte 48
/// dTtop first pulse lead/lag time for any runlength ≥ 4T
/// </summary>
public byte FirstPulseLeadTimeAnyRun;
/// <summary>
/// Byte 49
/// dTtop,3 first pulse lead/lag time for runlengths = 3T
/// </summary>
public byte FirstPulseLeadTimeRun3T;
/// <summary>
/// Byte 50
/// dTlp last pulse lead/lag time for any runlength ≥ 5T
/// </summary>
public byte LastPulseLeadTimeAnyRun;
/// <summary>
/// Byte 51
/// dTlp,3 last pulse lead/lag time for runlengths = 3T
/// </summary>
public byte LastPulseLeadTime3T;
/// <summary>
/// Byte 52
/// dTlp,4 last pulse lead/lag time for runlengths = 4T
/// </summary>
public byte LastPulseLeadTime4T;
/// <summary>
/// Byte 53
/// dTera erase lead/lag time when preceding mark length ≥ 5T
/// </summary>
public byte ErasePulseLeadTimeAny;
/// <summary>
/// Byte 54
/// dTera,3 erase lead/lag time when preceding mark length = 3T
/// </summary>
public byte ErasePulseLeadTime3T;
/// <summary>
/// Byte 55
/// dTera,4 erase lead/lag time when preceding mark length = 4T
/// </summary>
public byte ErasePulseLeadTime4T;
#endregion DVD+RW DL PFI
#region DVD-R DL PFI and DVD-RW DL PFI
/// <summary>
/// Byte 21
/// Maximum recording speed
/// </summary>
public DVDRecordingSpeed MaxRecordingSpeed;
/// <summary>
/// Byte 22
/// Minimum recording speed
/// </summary>
public DVDRecordingSpeed MinRecordingSpeed;
/// <summary>
/// Byte 23
/// Another recording speed
/// </summary>
public DVDRecordingSpeed RecordingSpeed1;
/// <summary>
/// Byte 24
/// Another recording speed
/// </summary>
public DVDRecordingSpeed RecordingSpeed2;
/// <summary>
/// Byte 25
/// Another recording speed
/// </summary>
public DVDRecordingSpeed RecordingSpeed3;
/// <summary>
/// Byte 26
/// Another recording speed
/// </summary>
public DVDRecordingSpeed RecordingSpeed4;
/// <summary>
/// Byte 27
/// Another recording speed
/// </summary>
public DVDRecordingSpeed RecordingSpeed5;
/// <summary>
/// Byte 28
/// Another recording speed
/// </summary>
public DVDRecordingSpeed RecordingSpeed6;
/// <summary>
/// Byte 29
/// Another recording speed
/// </summary>
public DVDRecordingSpeed RecordingSpeed7;
/// <summary>
/// Byte 30
/// Class
/// </summary>
public byte Class;
/// <summary>
/// Byte 31
/// Extended version. 0x30 = ECMA-382, 0x20 = ECMA-384
/// </summary>
public byte ExtendedVersion;
/// <summary>
/// Byte 36
/// Start sector number of current RMD in Extra Border Zone
/// </summary>
public UInt32 CurrentRMDExtraBorderPSN;
/// <summary>
/// Byte 40
/// Start sector number of Physical Format Information blocks in Extra Border Zone
/// </summary>
public UInt32 PFIExtraBorderPSN;
/// <summary>
/// Byte 44, bit 0
/// If NOT set, Control Data Zone is pre-recorded
/// </summary>
public bool PreRecordedControlDataInv;
/// <summary>
/// Byte 44 bit 1
/// Lead-in Zone is pre-recorded
/// </summary>
public bool PreRecordedLeadIn;
/// <summary>
/// Byte 44 bit 3
/// Lead-out Zone is pre-recorded
/// </summary>
public bool PreRecordedLeadOut;
/// <summary>
/// Byte 45 bits 0 to 3
/// AR characteristic of LPP on Layer 1
/// </summary>
public byte ARCharLayer1;
/// <summary>
/// Byte 45 bits 4 to 7
/// Tracking polarity on Layer 1
/// </summary>
public byte TrackPolarityLayer1;
#endregion DVD-R DL PFI and DVD-RW DL PFI
}
public static PhysicalFormatInformation? Decode(byte[] response)
{
if(response == null)
return null;
if(response.Length < 2052)
return null;
PhysicalFormatInformation pfi = new PhysicalFormatInformation();
byte[] tmp;
pfi.DataLength = (ushort)((response[0] << 8) + response[1]);
pfi.Reserved1 = response[2];
pfi.Reserved2 = response[3];
// Common
pfi.DiskCategory = (DiskCategory)((response[4] & 0xF0) >> 4);
pfi.PartVersion = (byte)(response[4] & 0x0F);
pfi.DiscSize = (DVDSize)((response[5] & 0xF0) >> 4);
pfi.MaximumRate = (MaximumRateField)(response[5] & 0x0F);
pfi.Reserved3 |= (response[6] & 0x80) == 0x80;
pfi.Layers = (byte)((response[6] & 0x60) >> 5);
pfi.TrackPath |= (response[6] & 0x08) == 0x08;
pfi.LayerType = (LayerTypeFieldMask)(response[6] & 0x07);
pfi.LinearDensity = (LinearDensityField)((response[7] & 0xF0) >> 4);
pfi.TrackDensity = (TrackDensityField)(response[7] & 0x0F);
pfi.DataAreaStartPSN = (uint)((response[8] << 24) + (response[9] << 16) + (response[10] << 8) + response[11]);
pfi.DataAreaEndPSN = (uint)((response[12] << 24) + (response[13] << 16) + (response[14] << 8) + response[15]);
pfi.Layer0EndPSN = (uint)((response[16] << 24) + (response[17] << 16) + (response[18] << 8) + response[19]);
pfi.BCA |= (response[20] & 0x80) == 0x80;
// UMD
if(pfi.DiskCategory == DiskCategory.UMD)
{
pfi.MediaAttribute = (ushort)((response[21] << 8) + response[22]);
}
// DVD-RAM
if(pfi.DiskCategory == DiskCategory.DVDRAM)
{
pfi.DiscType = (DVDRAMDiscType)response[36];
if(pfi.PartVersion == 1)
{
pfi.Velocity = response[52];
pfi.ReadPower = response[53];
pfi.PeakPower = response[54];
pfi.BiasPower = response[55];
pfi.FirstPulseStart = response[56];
pfi.FirstPulseEnd = response[57];
pfi.MultiPulseDuration = response[58];
pfi.LastPulseStart = response[59];
pfi.LastPulseEnd = response[60];
pfi.BiasPowerDuration = response[61];
pfi.PeakPowerGroove = response[62];
pfi.BiasPowerGroove = response[63];
pfi.FirstPulseStartGroove = response[64];
pfi.FirstPulseEndGroove = response[65];
pfi.MultiplePulseDurationGroove = response[66];
pfi.LastPulseStartGroove = response[67];
pfi.LastPulseEndGroove = response[68];
pfi.BiasPowerDurationGroove = response[69];
}
else if(pfi.PartVersion == 6)
{
pfi.Velocity = response[504];
pfi.ReadPower = response[505];
pfi.AdaptativeWritePulseControlFlag |= (response[506] & 0x80) == 0x80;
pfi.PeakPower = response[507];
pfi.BiasPower1 = response[508];
pfi.BiasPower2 = response[509];
pfi.BiasPower3 = response[510];
pfi.PeakPowerGroove = response[511];
pfi.BiasPower1Groove = response[512];
pfi.BiasPower2Groove = response[513];
pfi.BiasPower3Groove = response[514];
pfi.FirstPulseEnd = response[515];
pfi.FirstPulseDuration = response[516];
pfi.MultiPulseDuration = response[518];
pfi.LastPulseStart = response[519];
pfi.BiasPower2Duration = response[520];
pfi.FirstPulseStart3TSpace3T = response[521];
pfi.FirstPulseStart4TSpace3T = response[522];
pfi.FirstPulseStart5TSpace3T = response[523];
pfi.FirstPulseStartSpace3T = response[524];
pfi.FirstPulseStart3TSpace4T = response[525];
pfi.FirstPulseStart4TSpace4T = response[526];
pfi.FirstPulseStart5TSpace4T = response[527];
pfi.FirstPulseStartSpace4T = response[528];
pfi.FirstPulseStart3TSpace5T = response[529];
pfi.FirstPulseStart4TSpace5T = response[530];
pfi.FirstPulseStart5TSpace5T = response[531];
pfi.FirstPulseStartSpace5T = response[532];
pfi.FirstPulseStart3TSpace = response[533];
pfi.FirstPulseStart4TSpace = response[534];
pfi.FirstPulseStart5TSpace = response[535];
pfi.FirstPulseStartSpace = response[536];
pfi.FirstPulse3TStartTSpace3T = response[537];
pfi.FirstPulse4TStartTSpace3T = response[538];
pfi.FirstPulse5TStartTSpace3T = response[539];
pfi.FirstPulseStartTSpace3T = response[540];
pfi.FirstPulse3TStartTSpace4T = response[541];
pfi.FirstPulse4TStartTSpace4T = response[542];
pfi.FirstPulse5TStartTSpace4T = response[543];
pfi.FirstPulseStartTSpace4T = response[544];
pfi.FirstPulse3TStartTSpace5T = response[545];
pfi.FirstPulse4TStartTSpace5T = response[546];
pfi.FirstPulse5TStartTSpace5T = response[547];
pfi.FirstPulseStartTSpace5T = response[548];
pfi.FirstPulse3TStartTSpace = response[549];
pfi.FirstPulse4TStartTSpace = response[550];
pfi.FirstPulse5TStartTSpace = response[551];
pfi.FirstPulseStartTSpace = response[552];
tmp = new byte[48];
Array.Copy(response, 553, tmp, 0, 48);
pfi.DiskManufacturer = StringHandlers.SpacePaddedToString(tmp);
tmp = new byte[16];
Array.Copy(response, 601, tmp, 0, 16);
pfi.DiskManufacturerSupplementary = StringHandlers.SpacePaddedToString(tmp);
pfi.WritePowerControlParams = new byte[2];
pfi.WritePowerControlParams[0] = response[617];
pfi.WritePowerControlParams[1] = response[618];
pfi.PowerRatioLandThreshold = response[619];
pfi.TargetAsymmetry = response[620];
pfi.TemporaryPeakPower = response[621];
pfi.TemporaryBiasPower1 = response[622];
pfi.TemporaryBiasPower2 = response[623];
pfi.TemporaryBiasPower3 = response[624];
pfi.PowerRatioGrooveThreshold = response[625];
pfi.PowerRatioLandThreshold6T = response[626];
pfi.PowerRatioGrooveThreshold6T = response[627];
}
}
// DVD-R and DVD-RW
if((pfi.DiskCategory == DiskCategory.DVDR &&
pfi.PartVersion < 6) ||
(pfi.DiskCategory == DiskCategory.DVDRW &&
pfi.PartVersion < 3))
{
pfi.CurrentBorderOutSector = (uint)((response[36] << 24) + (response[37] << 16) + (response[38] << 8) + response[39]);
pfi.NextBorderInSector = (uint)((response[40] << 24) + (response[41] << 16) + (response[42] << 8) + response[43]);
}
// DVD+RW
if(pfi.DiskCategory == DiskCategory.DVDPRW)
{
pfi.RecordingVelocity = response[36];
pfi.ReadPowerMaxVelocity = response[37];
pfi.PIndMaxVelocity = response[38];
pfi.PMaxVelocity = response[39];
pfi.E1MaxVelocity = response[40];
pfi.E2MaxVelocity = response[41];
pfi.YTargetMaxVelocity = response[42];
pfi.ReadPowerRefVelocity = response[43];
pfi.PIndRefVelocity = response[44];
pfi.PRefVelocity = response[45];
pfi.E1RefVelocity = response[46];
pfi.E2RefVelocity = response[47];
pfi.YTargetRefVelocity = response[48];
pfi.ReadPowerMinVelocity = response[49];
pfi.PIndMinVelocity = response[50];
pfi.PMinVelocity = response[51];
pfi.E1MinVelocity = response[52];
pfi.E2MinVelocity = response[53];
pfi.YTargetMinVelocity = response[54];
}
// DVD+R, DVD+RW, DVD+R DL and DVD+RW DL
if(pfi.DiskCategory == DiskCategory.DVDPR ||
pfi.DiskCategory == DiskCategory.DVDPRW ||
pfi.DiskCategory == DiskCategory.DVDPRDL ||
pfi.DiskCategory == DiskCategory.DVDPRWDL)
{
pfi.VCPS |= (response[20] & 0x40) == 0x40;
pfi.ApplicationCode = response[21];
pfi.ExtendedInformation = response[22];
tmp = new byte[8];
Array.Copy(response, 23, tmp, 0, 8);
pfi.DiskManufacturerID = StringHandlers.CToString(tmp);
tmp = new byte[3];
Array.Copy(response, 31, tmp, 0, 3);
pfi.MediaTypeID = StringHandlers.CToString(tmp);
pfi.ProductRevision = pfi.DiskCategory == DiskCategory.DVDPRDL ? (byte)(response[34] & 0x3F) : response[34];
pfi.PFIUsedInADIP = response[35];
}
// DVD+RW
if(pfi.DiskCategory == DiskCategory.DVDPRW &&
pfi.PartVersion == 2)
{
pfi.TopFirstPulseDuration = response[55];
pfi.MultiPulseDuration = response[56];
pfi.FirstPulseLeadTime = response[57];
pfi.EraseLeadTimeRefVelocity = response[58];
pfi.EraseLeadTimeUppVelocity = response[59];
}
// DVD+R and DVD+R DL
if(pfi.DiskCategory == DiskCategory.DVDPR ||
pfi.DiskCategory == DiskCategory.DVDPRDL)
{
pfi.PrimaryVelocity = response[36];
pfi.UpperVelocity = response[37];
pfi.Wavelength = response[38];
pfi.NormalizedPowerDependency = response[39];
pfi.MaximumPowerAtPrimaryVelocity = response[40];
pfi.PindAtPrimaryVelocity = response[41];
pfi.BtargetAtPrimaryVelocity = response[42];
pfi.MaximumPowerAtUpperVelocity = response[43];
pfi.PindAtUpperVelocity = response[44];
pfi.BtargetAtUpperVelocity = response[45];
pfi.FirstPulseDuration4TPrimaryVelocity = response[46];
pfi.FirstPulseDuration3TPrimaryVelocity = response[47];
pfi.MultiPulseDurationPrimaryVelocity = response[48];
pfi.LastPulseDurationPrimaryVelocity = response[49];
pfi.FirstPulseLeadTime4TPrimaryVelocity = response[50];
pfi.FirstPulseLeadTime3TPrimaryVelocity = response[51];
pfi.FirstPulseLeadingEdgePrimaryVelocity = response[52];
pfi.FirstPulseDuration4TUpperVelocity = response[53];
pfi.FirstPulseDuration3TUpperVelocity = response[54];
pfi.MultiPulseDurationUpperVelocity = response[55];
pfi.LastPulseDurationUpperVelocity = response[56];
pfi.FirstPulseLeadTime4TUpperVelocity = response[57];
pfi.FirstPulseLeadTime3TUpperVelocity = response[58];
pfi.FirstPulseLeadingEdgeUpperVelocity = response[59];
}
// DVD+R DL
if(pfi.DiskCategory == DiskCategory.DVDPRDL)
{
pfi.LayerStructure = (DVDLayerStructure)((response[34] & 0xC0) >> 6);
}
// DVD+RW DL
if(pfi.DiskCategory == DiskCategory.DVDPRWDL)
{
pfi.BasicPrimaryVelocity = response[36];
pfi.MaxReadPowerPrimaryVelocity = response[37];
pfi.PindPrimaryVelocity = response[38];
pfi.PPrimaryVelocity = response[39];
pfi.E1PrimaryVelocity = response[40];
pfi.E2PrimaryVelocity = response[41];
pfi.YtargetPrimaryVelocity = response[42];
pfi.BOptimumPrimaryVelocity = response[43];
pfi.TFirstPulseDuration = response[46];
pfi.TMultiPulseDuration = response[47];
pfi.FirstPulseLeadTimeAnyRun = response[48];
pfi.FirstPulseLeadTimeRun3T = response[49];
pfi.LastPulseLeadTimeAnyRun = response[50];
pfi.LastPulseLeadTime3T = response[51];
pfi.LastPulseLeadTime4T = response[52];
pfi.ErasePulseLeadTimeAny = response[53];
pfi.ErasePulseLeadTime3T = response[54];
pfi.ErasePulseLeadTime4T = response[55];
}
// DVD-R DL and DVD-RW DL
if((pfi.DiskCategory == DiskCategory.DVDR &&
pfi.PartVersion == 6) ||
(pfi.DiskCategory == DiskCategory.DVDRW &&
pfi.PartVersion == 3))
{
pfi.MaxRecordingSpeed = (DVDRecordingSpeed)response[21];
pfi.MinRecordingSpeed = (DVDRecordingSpeed)response[22];
pfi.RecordingSpeed1 = (DVDRecordingSpeed)response[23];
pfi.RecordingSpeed2 = (DVDRecordingSpeed)response[24];
pfi.RecordingSpeed3 = (DVDRecordingSpeed)response[25];
pfi.RecordingSpeed4 = (DVDRecordingSpeed)response[26];
pfi.RecordingSpeed5 = (DVDRecordingSpeed)response[27];
pfi.RecordingSpeed6 = (DVDRecordingSpeed)response[28];
pfi.RecordingSpeed7 = (DVDRecordingSpeed)response[29];
pfi.Class = response[30];
pfi.ExtendedVersion = response[31];
pfi.CurrentBorderOutSector = (uint)((response[36] << 24) + (response[37] << 16) + (response[38] << 8) + response[39]);
pfi.NextBorderInSector = (uint)((response[40] << 24) + (response[41] << 16) + (response[42] << 8) + response[43]);
pfi.PreRecordedControlDataInv |= (response[44] & 0x01) == 0x01;
pfi.PreRecordedLeadIn |= (response[44] & 0x02) == 0x02;
pfi.PreRecordedLeadOut |= (response[44] & 0x08) == 0x08;
pfi.ARCharLayer1 = (byte)(response[45] & 0x0F);
pfi.TrackPolarityLayer1 = (byte)((response[45] & 0xF0) >> 4);
}
return pfi;
}
public static string Prettify(PhysicalFormatInformation? pfi)
{
if(pfi == null)
return null;
PhysicalFormatInformation decoded = pfi.Value;
StringBuilder sb = new StringBuilder();
string sizeString;
switch(decoded.DiscSize)
{
case DVDSize.Eighty:
sizeString = "80mm";
break;
case DVDSize.OneTwenty:
sizeString = "120mm";
break;
default:
sizeString = String.Format("unknown size identifier {0}", decoded.DiscSize);
break;
}
string categorySentence = "Disc is a {0} {1} version {2}";
switch(decoded.DiskCategory)
{
case DiskCategory.DVDROM:
sb.AppendFormat(categorySentence, sizeString, "DVD-ROM", decoded.PartVersion).AppendLine();
if(decoded.DiscSize == DVDSize.OneTwenty && decoded.PartVersion == 1)
sb.AppendLine("Disc claims conformation to ECMA-267");
if(decoded.DiscSize == DVDSize.Eighty && decoded.PartVersion == 1)
sb.AppendLine("Disc claims conformation to ECMA-268");
break;
case DiskCategory.DVDRAM:
sb.AppendFormat(categorySentence, sizeString, "DVD-RAM", decoded.PartVersion).AppendLine();
switch(decoded.PartVersion)
{
case 1:
sb.AppendLine("Disc claims conformation to ECMA-272");
break;
case 6:
sb.AppendLine("Disc claims conformation to ECMA-330");
break;
}
break;
case DiskCategory.DVDR:
if(decoded.PartVersion >= 6)
sb.AppendFormat(categorySentence, sizeString, "DVD-R DL", decoded.PartVersion).AppendLine();
else
sb.AppendFormat(categorySentence, sizeString, "DVD-R", decoded.PartVersion).AppendLine();
switch(decoded.PartVersion)
{
case 1:
sb.AppendLine("Disc claims conformation to ECMA-279");
break;
case 5:
sb.AppendLine("Disc claims conformation to ECMA-359");
break;
case 6:
sb.AppendLine("Disc claims conformation to ECMA-382");
break;
}
break;
case DiskCategory.DVDRW:
if(decoded.PartVersion >= 3)
sb.AppendFormat(categorySentence, sizeString, "DVD-RW DL", decoded.PartVersion).AppendLine();
else
sb.AppendFormat(categorySentence, sizeString, "DVD-RW", decoded.PartVersion).AppendLine();
switch(decoded.PartVersion)
{
case 2:
sb.AppendLine("Disc claims conformation to ECMA-338");
break;
case 3:
sb.AppendLine("Disc claims conformation to ECMA-384");
break;
}
break;
case DiskCategory.UMD:
if(decoded.DiscSize == DVDSize.OneTwenty)
sb.AppendFormat(categorySentence, "60mm", "UMD", decoded.PartVersion).AppendLine();
else
sb.AppendFormat(categorySentence, "invalid size", "UMD", decoded.PartVersion).AppendLine();
switch(decoded.PartVersion)
{
case 0:
sb.AppendLine("Disc claims conformation to ECMA-365");
break;
}
break;
case DiskCategory.DVDPRW:
sb.AppendFormat(categorySentence, sizeString, "DVD+RW", decoded.PartVersion).AppendLine();
switch(decoded.PartVersion)
{
case 1:
sb.AppendLine("Disc claims conformation to ECMA-274");
break;
case 2:
sb.AppendLine("Disc claims conformation to ECMA-337");
break;
case 3:
sb.AppendLine("Disc claims conformation to ECMA-371");
break;
}
break;
case DiskCategory.DVDPR:
sb.AppendFormat(categorySentence, sizeString, "DVD+R", decoded.PartVersion).AppendLine();
switch(decoded.PartVersion)
{
case 1:
sb.AppendLine("Disc claims conformation to ECMA-349");
break;
}
break;
case DiskCategory.DVDPRWDL:
sb.AppendFormat(categorySentence, sizeString, "DVD+RW DL", decoded.PartVersion).AppendLine();
switch(decoded.PartVersion)
{
case 1:
sb.AppendLine("Disc claims conformation to ECMA-374");
break;
}
break;
case DiskCategory.DVDPRDL:
sb.AppendFormat(categorySentence, sizeString, "DVD+R DL", decoded.PartVersion).AppendLine();
switch(decoded.PartVersion)
{
case 1:
sb.AppendLine("Disc claims conformation to ECMA-364");
break;
}
break;
case DiskCategory.Nintendo:
if(decoded.PartVersion == 15)
{
if(decoded.DiscSize == DVDSize.Eighty)
sb.AppendLine("Disc is a Nintendo Gamecube Optical Disc (GOD)");
else if(decoded.DiscSize == DVDSize.OneTwenty)
sb.AppendLine("Disc is a Nintendo Wii Optical Disc (WOD)");
else
goto default;
}
else
goto default;
break;
case DiskCategory.HDDVDROM:
sb.AppendFormat(categorySentence, sizeString, "HD DVD-ROM", decoded.PartVersion).AppendLine();
break;
case DiskCategory.HDDVDRAM:
sb.AppendFormat(categorySentence, sizeString, "HD DVD-RAM", decoded.PartVersion).AppendLine();
break;
case DiskCategory.HDDVDR:
sb.AppendFormat(categorySentence, sizeString, "HD DVD-R", decoded.PartVersion).AppendLine();
break;
case DiskCategory.HDDVDRW:
sb.AppendFormat(categorySentence, sizeString, "HD DVD-RW", decoded.PartVersion).AppendLine();
break;
default:
sb.AppendFormat(categorySentence, sizeString, "unknown disc type", decoded.PartVersion).AppendLine();
break;
}
switch(decoded.MaximumRate)
{
case MaximumRateField.TwoMbps:
sb.AppendLine("Disc maximum transfer rate is 2,52 Mbit/sec.");
break;
case MaximumRateField.FiveMbps:
sb.AppendLine("Disc maximum transfer rate is 5,04 Mbit/sec.");
break;
case MaximumRateField.TenMbps:
sb.AppendLine("Disc maximum transfer rate is 10,08 Mbit/sec.");
break;
case MaximumRateField.TwentyMbps:
sb.AppendLine("Disc maximum transfer rate is 20,16 Mbit/sec.");
break;
case MaximumRateField.ThirtyMbps:
sb.AppendLine("Disc maximum transfer rate is 30,24 Mbit/sec.");
break;
case MaximumRateField.Unspecified:
sb.AppendLine("Disc maximum transfer rate is unspecified.");
break;
default:
sb.AppendFormat("Disc maximum transfer rate is specified by unknown key {0}", decoded.MaximumRate).AppendLine();
break;
}
sb.AppendFormat("Disc has {0} layers", decoded.Layers + 1).AppendLine();
if(decoded.TrackPath && decoded.Layers == 1)
sb.AppendLine("Layers are in parallel track path");
else if(!decoded.TrackPath && decoded.Layers == 1)
sb.AppendLine("Layers are in opposite track path");
switch(decoded.LinearDensity)
{
case LinearDensityField.TwoSix:
sb.AppendLine("Pitch size is 0,267 μm/bit");
break;
case LinearDensityField.TwoNine:
sb.AppendLine("Pitch size is 0,147 μm/bit");
break;
case LinearDensityField.FourZero:
sb.AppendLine("Pitch size is between 0,409 μm/bit and 0,435 μm/bit");
break;
case LinearDensityField.TwoEight:
sb.AppendLine("Pitch size is between 0,140 μm/bit and 0,148 μm/bit");
break;
case LinearDensityField.OneFive:
sb.AppendLine("Pitch size is 0,153 μm/bit");
break;
case LinearDensityField.OneThree:
sb.AppendLine("Pitch size is between 0,130 μm/bit and 0,140 μm/bit");
break;
case LinearDensityField.ThreeFive:
sb.AppendLine("Pitch size is 0,353 μm/bit");
break;
default:
sb.AppendFormat("Unknown pitch size key {0}", decoded.LinearDensity).AppendLine();
break;
}
switch(decoded.TrackDensity)
{
case TrackDensityField.Seven:
sb.AppendLine("Track size is 0,74 μm");
break;
case TrackDensityField.Eight:
sb.AppendLine("Track size is 0,80 μm");
break;
case TrackDensityField.Six:
sb.AppendLine("Track size is 0,615 μm");
break;
case TrackDensityField.Four:
sb.AppendLine("Track size is 0,40 μm");
break;
case TrackDensityField.Three:
sb.AppendLine("Track size is 0,34 μm");
break;
default:
sb.AppendFormat("Unknown track size key {0}", decoded.LinearDensity).AppendLine();
break;
}
if(decoded.DataAreaStartPSN > 0)
{
if(decoded.DataAreaEndPSN > 0)
{
sb.AppendFormat("Data area starts at PSN {0:X}h", decoded.DataAreaStartPSN).AppendLine();
sb.AppendFormat("Data area ends at PSN {0:X}h", decoded.DataAreaEndPSN).AppendLine();
if(decoded.Layers == 1 && !decoded.TrackPath)
sb.AppendFormat("Layer 0 ends at PSN {0:X}h", decoded.Layer0EndPSN).AppendLine();
}
else
sb.AppendLine("Disc is empty");
}
else
sb.AppendLine("Disc is empty");
if(decoded.BCA)
sb.AppendLine("Disc has a burst cutting area");
if(decoded.DiskCategory == DiskCategory.UMD)
sb.AppendFormat("Media attribute is {0}", decoded.MediaAttribute).AppendLine();
if(decoded.DiskCategory == DiskCategory.DVDRAM)
{
switch(decoded.DiscType)
{
case DVDRAMDiscType.Cased:
sb.AppendLine("Disc shall be recorded with a case");
break;
case DVDRAMDiscType.Uncased:
sb.AppendLine("Disc can be recorded with or without a case");
break;
default:
sb.AppendFormat("Unknown DVD-RAM case type key {0}", decoded.DiscType).AppendLine();
break;
}
if(decoded.PartVersion == 6)
{
sb.AppendFormat("Disc manufacturer is {0}", decoded.DiskManufacturer).AppendLine();
sb.AppendFormat("Disc manufacturer supplementary information is {0}", decoded.DiskManufacturerSupplementary).AppendLine();
}
}
if((decoded.DiskCategory == DiskCategory.DVDR &&
decoded.PartVersion < 6) ||
(decoded.DiskCategory == DiskCategory.DVDRW &&
decoded.PartVersion < 3))
{
sb.AppendFormat("Current Border-Out first sector is PSN {0:X}h", decoded.CurrentBorderOutSector).AppendLine();
sb.AppendFormat("Next Border-In first sector is PSN {0:X}h", decoded.NextBorderInSector).AppendLine();
}
if(decoded.DiskCategory == DiskCategory.DVDPR ||
decoded.DiskCategory == DiskCategory.DVDPRW ||
decoded.DiskCategory == DiskCategory.DVDPRDL ||
decoded.DiskCategory == DiskCategory.DVDPRWDL)
{
if(decoded.VCPS)
sb.AppendLine("Disc contains extended information for VCPS");
sb.AppendFormat("Disc application code is {0}", decoded.ApplicationCode).AppendLine();
sb.AppendFormat("Disc manufacturer is {0}", decoded.DiskManufacturerID).AppendLine();
sb.AppendFormat("Disc media type is {0}", decoded.MediaTypeID).AppendLine();
sb.AppendFormat("Disc product revision is {0}", decoded.ProductRevision).AppendLine();
}
if((decoded.DiskCategory == DiskCategory.DVDR &&
decoded.PartVersion >= 6) ||
(decoded.DiskCategory == DiskCategory.DVDRW &&
decoded.PartVersion >= 3))
{
sb.AppendFormat("Current RMD in extra Border zone starts at PSN {0:X}h", decoded.CurrentRMDExtraBorderPSN).AppendLine();
sb.AppendFormat("PFI in extra Border zone starts at PSN {0:X}h", decoded.PFIExtraBorderPSN).AppendLine();
if(!decoded.PreRecordedControlDataInv)
sb.AppendLine("Control Data Zone is pre-recorded");
if(decoded.PreRecordedLeadIn)
sb.AppendLine("Lead-In is pre-recorded");
if(decoded.PreRecordedLeadOut)
sb.AppendLine("Lead-Out is pre-recorded");
}
return sb.ToString();
}
public static string Prettify(byte[] response)
{
return Prettify(Decode(response));
}
}
}