// /*************************************************************************** // The Disc Image Chef // ---------------------------------------------------------------------------- // // Filename : Features.cs // Author(s) : Natalia Portillo // // Component : Device structures decoders. // // --[ Description ] ---------------------------------------------------------- // // Decodes SCSI MMC feature structures. // // --[ 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 . // // ---------------------------------------------------------------------------- // Copyright © 2011-2020 Natalia Portillo // ****************************************************************************/ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; using DiscImageChef.CommonTypes.Structs.Devices.SCSI; // ReSharper disable MemberCanBePrivate.Global namespace DiscImageChef.Decoders.SCSI.MMC { /// MMC Feature enumeration [SuppressMessage("ReSharper", "InconsistentNaming")] public enum FeatureNumber : ushort { /// Lists all profiles ProfileList = 0x0000, /// Mandatory behaviour Core = 0x0001, /// Operational changes Morphing = 0x0002, /// Removable medium Removable = 0x0003, /// Ability to control write protection status WriteProtect = 0x0004, /// Ability to read sectors with random addressing RandomRead = 0x0010, /// Reads on OSTA Multi-Read MultiRead = 0x001D, /// Able to read CD structures CDRead = 0x001E, /// Able to read DVD structures DVDRead = 0x001F, /// Ability to write sectors with random addressing RandomWrite = 0x0020, /// Ability to sequentially write IncrementalWrite = 0x0021, /// Support for media that requires erase before write SectorErasable = 0x0022, /// Supports formatting media Formattable = 0x0023, /// Ability to provide defect-free space HardwareDefectMgmt = 0x0024, /// Supports for write-once media in random order WriteOnce = 0x0025, /// Supports for media that shall be written from blocking boundaries RestrictedOverwrite = 0x0026, /// Supports high speed CD-RW CDRWCAV = 0x0027, /// Read and optionally write MRW MRW = 0x0028, /// Ability to control RECOVERED ERROR reporting EnDefectReport = 0x0029, /// Ability to recognize, read and optionally write DVD+RW DVDRWPlus = 0x002A, /// Ability to read DVD+R DVDRPlus = 0x002B, RigidOverWrite = 0x002C, /// Ability to write CD in Track-at-Once CDTAO = 0x002D, /// Ability to write CD in Session-at-Once or RAW CDMastering = 0x002E, /// Ability to write DVD structures DVDRWrite = 0x002F, /// Ability to read DDCD DDCD = 0x0030, /// Ability to write DDCD-R DDCDR = 0x0031, /// Ability to write DDCD-RW DDCDRW = 0x0032, /// Ability to record in layer jump mode LayerJump = 0x0033, /// Ability to perform Layer Jump recording on Rigid Restricted Overwrite LJRigid = 0x0034, /// Ability to stop the long immediate operation StopLong = 0x0035, /// Ability to report CD-RW media sub-types supported for write CDRWMediaWrite = 0x0037, /// Logical block overwrite service on BD-R formatted as SRM+POW BDRPOW = 0x0038, /// Ability to read DVD+RW DL DVDRWDLPlus = 0x003A, /// Ability to read DVD+R DL DVDRDLPlus = 0x003B, /// Ability to read BD discs BDRead = 0x0040, /// Ability to write BD discs BDWrite = 0x0041, /// Timely, Safe Recording TSR = 0x0042, /// Ability to read HD DVD HDDVDRead = 0x0050, /// Ability to write HD DVD HDDVDWrite = 0x0051, /// Ability to write HD DVD-RW fragmented HDDVDRWFragment = 0x0052, /// Supports some Hybrid Discs Hybrid = 0x0080, /// Host and device directed power management PowerMgmt = 0x0100, /// Supports S.M.A.R.T. SMART = 0x0101, /// Single machanism multiple disc changer Changer = 0x0102, /// Ability to play CD audio to an analogue output CDAudioExt = 0x0103, /// Ability to accept new microcode MicrocodeUpgrade = 0x0104, /// Ability to respond to all commands within a specific time Timeout = 0x0105, /// Supports DVD CSS/CPPM CSS = 0x0106, /// Ability to read and write using host requested performance parameters RTS = 0x0107, /// Drive has a unique identifier DriveSerial = 0x0108, /// Ability to return unique Media Serial Number MediaSerial = 0x0109, /// Ability to read and/or write DCBs DCBs = 0x010A, /// Supports DVD CPRM CPRM = 0x010B, /// Firmware creation date report FirmwareInfo = 0x010C, /// Ability to decode and optionally encode AACS AACS = 0x010D, /// Ability to perform DVD CSS managed recording CSSManagedRec = 0x010E, /// Ability to decode and optionally encode VCPS VCPS = 0x0110, /// Supports SecurDisc SecurDisc = 0x0113, /// TCG Optical Security Subsystem Class OSSC = 0x0142 } /// MMC Profile enumeration [SuppressMessage("ReSharper", "InconsistentNaming")] public enum ProfileNumber : ushort { /// Not to use Reserved = 0x0000, /// Non-removable disk profile NonRemovable = 0x0001, /// Rewritable with removable media Removable = 0x0002, /// Magneto-Optical with sector erase MOErasable = 0x0003, /// Optical write once OpticalWORM = 0x0004, /// Advance Storage - Magneto-Optical ASMO = 0x0005, /// Read-only Compact Disc CDROM = 0x0008, /// Write-once Compact Disc CDR = 0x0009, /// Re-writable Compact Disc CDRW = 0x000A, /// Read-only DVD DVDROM = 0x0010, /// Write-once sequentially recorded DVD-R DVDRSeq = 0x0011, /// DVD-RAM DVDRAM = 0x0012, /// Restricted overwrite DVD-RW DVDRWRes = 0x0013, /// Sequential recording DVD-RW DVDRWSeq = 0x0014, /// Sequential recording DVD-R DL DVDRDLSeq = 0x0015, /// Layer jump recording DVD-R DL DVDRDLJump = 0x0016, /// DVD-RW DL DVDRWDL = 0x0017, /// DVD-Download DVDDownload = 0x0018, /// DVD+RW DVDRWPlus = 0x001A, /// DVD+R DVDRPlus = 0x001B, /// DDCD-ROM DDCDROM = 0x0020, /// DDCD-R DDCDR = 0x0021, /// DDCD-RW DDCDRW = 0x0022, /// DVD+RW DL DVDRWDLPlus = 0x002A, /// DVD+R DL DVDRDLPlus = 0x002B, /// BD-ROM BDROM = 0x0040, /// BD-R SRM BDRSeq = 0x0041, /// BD-R RRM BDRRdm = 0x0042, /// BD-RE BDRE = 0x0043, /// HD DVD-ROM HDDVDROM = 0x0050, /// HD DVD-R HDDVDR = 0x0051, /// HD DVD-RAM HDDVDRAM = 0x0052, /// HD DVD-RW HDDVDRW = 0x0053, /// HD DVD-R DL HDDVDRDL = 0x0058, /// HD DVD-RW DL HDDVDRWDL = 0x005A, /// HDBurn CD-ROM HDBURNROM = 0x0080, /// HDBurn CD-R HDBURNR = 0x0081, /// HDBurn CD-RW HDBURNRW = 0x0082, /// Drive does not conform to any profiles Unconforming = 0xFFFF } [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Profile { public ProfileNumber Number; public bool Current; } /// Profile List Feature (0000h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0000 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// All supported profiles public Profile[] Profiles; } /// Core Feature (0001h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0001 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Currently in-use physical interface standard public PhysicalInterfaces PhysicalInterfaceStandard; /// Supports EVPD, Page Code and 16-bit Allocation Length as defined in SPC-3 public bool INQ2; /// Supports Device Busy Event public bool DBE; } /// Morphing Feature (0002h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0002 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports Operational Change Request/Nofitication Class Events of GET EVENT/STATUS NOTIFICATION public bool OCEvent; /// Supports asynchronous GET EVENT/STATUS NOTIFICATION public bool Async; } /// Removable Medium Feature (0003h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0003 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Mechanism type public byte LoadingMechanismType; /// Drive is able to load the medium public bool Load; /// Device can eject medium public bool Eject; /// Device starts in medium ejection/insertion allow public bool PreventJumper; /// Reports Device Busy Class events during medium loading/unloading public bool DBML; /// Medium is currently locked public bool Lock; } /// Write Protect Feature (0004h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0004 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Drive can read/write Disc Write Protect PAC on BD-R/-RE media public bool DWP; /// Supports reading/writing Write Inhibit DCB on DVD+RW media. public bool WDCB; /// Supports PWP status public bool SPWP; /// Supports SWPP bit of mode page 1Dh public bool SSWPP; } /// Random Readable Feature (0010h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0010 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Bytes per logical block public uint LogicalBlockSize; /// Number of logical blocks per device readable unit public ushort Blocking; /// Read/Write Error Recovery page is present public bool PP; } /// Multi-Read Feature (001Dh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_001D { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// CD Read Feature (001Eh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_001E { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports DAP bit in READ CD and READ CD MSF public bool DAP; /// Supports C2 Error Pointers public bool C2; /// Can read CD-Text with READ TOC/PMA/ATIP public bool CDText; } /// DVD Read Feature (001Fh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_001F { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Compliant with DVD Multi Drive Read-only specifications public bool MULTI110; /// Supports reading all DVD-RW DL public bool DualRW; /// Supports reading all DVD-R DL including remapping public bool DualR; } /// Random Writable Feature (0020h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0020 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Last logical block address public uint LastLBA; /// Bytes per logical block public uint LogicalBlockSize; /// Number of logical blocks per device readable unit public ushort Blocking; /// Read/Write Error Recovery page is present public bool PP; } /// Incremental Streaming Writable Feature (0021h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0021 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Bitmask of supported data types public ushort DataTypeSupported; /// Can report Track Resources Information of READ DISC INFORMATION public bool TRIO; /// Supports Address Mode in RESERVE TRACK public bool ARSV; /// Zero loss linking public bool BUF; /// Logical blocks per link public byte[] LinkSizes; } /// Sector Erasable Feature (0022h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0022 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// Formattable Feature (0023h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0023 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports formatting BD-RE without spare area public bool RENoSA; /// Supports expansion of the spare area on BD-RE public bool Expand; /// Supports FORMAT type 30h sub-type 11b public bool QCert; /// Supports FORMAT type 30h sub-type 10b public bool Cert; /// Supports FORMAT type 18h public bool FRF; /// Supports FORMAT type 00h/32h sub-type 10b on BD-R public bool RRM; } /// Hardware Defect Management Feature (0024h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0024 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports READ DISC STRUCTURE with Format Code 0Ah (Spare Area Information) public bool SSA; } /// Write Once Feature (0025h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0025 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Bytes per logical block public uint LogicalBlockSize; /// Number of logical blocks per device readable unit public ushort Blocking; /// Read/Write Error Recovery page is present public bool PP; } /// Restricted Overwrite Feature (0026h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0026 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// CD-RW CAV Write Feature (0027h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0027 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// MRW Feature (0028h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0028 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can read DVD+MRW discs public bool DVDPRead; /// Can write DVD+MRW discs public bool DVDPWrite; /// Can format and write to CD-MRW discs public bool Write; } /// Enhanced Defect Reporting Feature (0029h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0029 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports DRT-DM public bool DRTDM; /// Maximum number of DBI cache zones device can handle separately public byte DBICacheZones; /// Number of entries in worst case to case DBI overflow public ushort Entries; } /// DVD+RW Feature (002Ah) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_002A { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can format DVD+RW discs public bool Write; /// FORMAT UNIT supports quick start formatting public bool QuickStart; /// Drive only supports read compatibility stop public bool CloseOnly; } /// DVD+R Feature (002Bh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_002B { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can write DVD+R public bool Write; } /// Rigid Restricted Overwrite Feature (002Ch) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_002C { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can generate Defect Status Data during formatting public bool DSDG; /// Can read Defect Status Data recorded on medium public bool DSDR; /// Supports writing on an intermediate state Session and quick formatting public bool Intermediate; /// Supports BLANK command types 00h and 01h public bool Blank; } /// CD Track at Once Feature (002Dh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_002D { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports zero loss linking public bool BUF; /// Supports writing R-W subchannels in raw mode public bool RWRaw; /// Supports writing R-W subchannels in packed mode public bool RWPack; /// Can perform test writes public bool TestWrite; /// Supports overwriting a TAO track with another public bool CDRW; /// Can write R-W subchannels with user provided data public bool RWSubchannel; /// Bitmask of supported data types public ushort DataTypeSupported; } /// CD Mastering (Session at Once) Feature (002Eh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_002E { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports zero loss linking public bool BUF; /// Can write in Session at Once public bool SAO; /// Can write multi-session in RAW public bool RAWMS; /// Can write in RAW public bool RAW; /// Can perform test writes public bool TestWrite; /// Can overwrite previously recorded data public bool CDRW; /// Can write R-W subchannels with user provided data public bool RW; /// Maximum length of a Cue Sheet for Session at Once public uint MaxCueSheet; } /// DVD-R/-RW Write Feature (002Fh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_002F { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Buffer Under-run protection public bool BUF; /// Supports writing DVD-R DL public bool RDL; /// Test write public bool TestWrite; /// Can write and erase DVD-RW public bool DVDRW; } /// Double Density CD Read Feature (0030h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0030 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// Double Density CD-R Write Feature (0031h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0031 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Test write public bool TestWrite; } /// Double Density CD-RW Write Feature (0032h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0032 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports quick formatting public bool Intermediate; /// Supports BLANK command public bool Blank; } /// Layer Jump Recording Feature (0033h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0033 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; public byte[] LinkSizes; } /// Stop Long Operation Feature (0035h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0035 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// CD-RW Media Write Support Feature (0037h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0037 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Bitmask of supported CD-RW media sub-types public byte SubtypeSupport; } /// BD-R Pseudo-Overwrite (POW) Feature (0038h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0038 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// DVD+RW Dual Layer Feature (003Ah) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_003A { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can format DVD+RW DL discs public bool Write; /// FORMAT UNIT supports quick start formatting public bool QuickStart; /// Drive only supports read compatibility stop public bool CloseOnly; } /// DVD+R Dual Layer Feature (003Bh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_003B { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can format DVD+R DL discs public bool Write; /// FORMAT UNIT supports quick start formatting public bool QuickStart; /// Drive only supports read compatibility stop public bool CloseOnly; } /// BD Read Feature (0040h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0040 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can read BCA public bool BCA; /// Supports reading BD-RE Ver.2 public bool RE2; /// Supports reading BD-RE Ver.1 public bool RE1; /// Obsolete public bool OldRE; /// Supports reading BD-R Ver.1 public bool R; /// Obsolete public bool OldR; /// Supports reading BD-ROM Ver.1 public bool ROM; /// Obsolete public bool OldROM; } /// BD Write Feature (0041h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0041 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports verify not required public bool SVNR; /// Supports writing BD-RE Ver.2 public bool RE2; /// Supports writing BD-RE Ver.1 public bool RE1; /// Obsolete public bool OldRE; /// Supports writing BD-R Ver.1 public bool R; /// Obsolete public bool OldR; } /// TSR Feature (0042h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0042 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// HD DVD Read Feature (0050h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0050 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can read HD DVD-R public bool HDDVDR; /// Can read HD DVD-RAM public bool HDDVDRAM; } /// HD DVD Write Feature (0051h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0051 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Can write HD DVD-R public bool HDDVDR; /// Can write HD DVD-RAM public bool HDDVDRAM; } /// Hybrid Disc Feature (0080h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0080 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Reset immunity public bool RI; } /// Power Management Feature (0100h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0100 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// S.M.A.R.T. Feature (0101h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0101 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Mode Page 1Ch is present public bool PP; } /// Embedded Changer Feature (0102h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0102 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Side change capable public bool SCC; /// Supports Disc Present public bool SDP; /// Number of slots - 1 public byte HighestSlotNumber; } /// CD Audio External Play Feature (0103h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0103 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports SCAN command public bool Scan; /// Separate Channel Mute public bool SCM; /// Separate Volume public bool SV; /// Number of volume levels public ushort VolumeLevels; } /// Microcode Upgrade Feature (0104h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0104 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports validating 5-bit mode field of READ BUFFER and WRITE BUFFER commands. public bool M5; } /// Time-Out Feature (0105h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0105 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports G3Enable bit and Group3 Timeout field in Mode Page 1Dh public bool Group3; /// Indicates a unit of block length, in sectors, corresponding to increase a unit of Group 3 time unit public ushort UnitLength; } /// DVD-CSS Feature (0106h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0106 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// CSS version public byte CSSVersion; } /// Real Time Streaming Feature (0107h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0107 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports Set Minimum Performance bit in SET STREAMING public bool SMP; /// Supports READ BUFFER CAPACITY with block bit set public bool RBCB; /// Supports SET CD SPEED public bool SCS; /// Has Mode Page 2Ah with Speed Performance Descriptors public bool MP2A; /// Supports type 03h of GET PERFORMANCE public bool WSPD; /// Supports stream recording public bool SW; } /// Drive serial number (0108h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0108 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Drive serial number public string Serial; } /// Media Serial Number Feature (0109h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0109 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// Disc Control Blocks Feature (010Ah) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_010A { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; public uint[] DCBs; } /// DVD CPRM Feature (010Bh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_010B { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// CPRM version public byte CPRMVersion; } /// Firmware Information Feature (010Ch) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_010C { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; public ushort Century; public ushort Year; public ushort Month; public ushort Day; public ushort Hour; public ushort Minute; public ushort Second; } /// AACS Feature (010Dh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_010D { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Drive supports reading drive certificate public bool RDC; /// Drive can read media key block of CPRM public bool RMC; /// Drive can write bus encrypted blocks public bool WBE; /// Drive supports bus encryption public bool BEC; /// Drive supports generating the binding nonce public bool BNG; /// Blocks required to store the binding nonce for the media public byte BindNonceBlocks; /// Maximum number of AGIDs supported concurrently public byte AGIDs; /// AACS version public byte AACSVersion; } /// DVD CSS Managed Recording Feature (010Eh) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_010E { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Maximum number of Scramble Extent information entries in a single SEND DISC STRUCTURE public byte MaxScrambleExtent; } /// SecurDisc Feature (0113h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0113 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } /// OSSC Feature (0142h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0142 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; /// Supports PSA updates on write-once media public bool PSAU; /// Supports linked OSPBs public bool LOSPB; /// Restricted to recording only OSSC disc format public bool ME; public ushort[] Profiles; } /// VCPS Feature (0110h) [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct Feature_0110 { /// Feature version public byte Version; /// Feature is persistent public bool Persistent; /// Feature is currently in use public bool Current; } public static class Features { public static Feature_0000? Decode_0000(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0000) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0000(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); int offset = 4; List listProfiles = new List(); while(offset < feature.Length) { var prof = new Profile { Number = (ProfileNumber)((feature[offset] << 8) + feature[offset + 1]) }; prof.Current |= (feature[offset + 2] & 0x01) == 0x01; listProfiles.Add(prof); offset += 4; } decoded.Profiles = listProfiles.ToArray(); return decoded; } public static Feature_0001? Decode_0001(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0001) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0001(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.PhysicalInterfaceStandard = (PhysicalInterfaces)((feature[4] << 24) + (feature[5] << 16) + (feature[6] << 8) + feature[7]); if(decoded.Version >= 1 && feature.Length >= 12) decoded.DBE |= (feature[8] & 0x01) == 0x01; if(decoded.Version >= 2 && feature.Length >= 12) decoded.INQ2 |= (feature[8] & 0x02) == 0x02; return decoded; } public static Feature_0002? Decode_0002(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0002) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0002(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Async |= (feature[4] & 0x01) == 0x01; if(decoded.Version >= 1) decoded.OCEvent |= (feature[4] & 0x02) == 0x02; return decoded; } public static Feature_0003? Decode_0003(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0003) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0003(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.LoadingMechanismType = (byte)((feature[4] & 0xE0) >> 5); decoded.Eject |= (feature[4] & 0x08) == 0x08; decoded.PreventJumper |= (feature[4] & 0x04) == 0x04; decoded.Lock |= (feature[4] & 0x01) == 0x01; if(decoded.Version < 2) return decoded; decoded.Load |= (feature[4] & 0x10) == 0x10; decoded.DBML |= (feature[4] & 0x02) == 0x02; return decoded; } public static Feature_0004? Decode_0004(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0004) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0004(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.SPWP |= (feature[4] & 0x02) == 0x02; decoded.SSWPP |= (feature[4] & 0x01) == 0x01; if(decoded.Version >= 1) decoded.WDCB |= (feature[4] & 0x04) == 0x04; if(decoded.Version >= 2) decoded.DWP |= (feature[4] & 0x08) == 0x08; return decoded; } public static Feature_0010? Decode_0010(byte[] feature) { if(feature == null) return null; if(feature.Length < 12) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0010) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0010(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.LogicalBlockSize = (uint)((feature[4] << 24) + (feature[5] << 16) + (feature[6] << 8) + feature[7]); decoded.Blocking = (ushort)((feature[8] << 8) + feature[9]); decoded.PP |= (feature[10] & 0x01) == 0x01; return decoded; } public static Feature_001D? Decode_001D(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x001D) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_001D(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_001E? Decode_001E(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x001E) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_001E(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version >= 1) { decoded.C2 |= (feature[4] & 0x02) == 0x02; decoded.CDText |= (feature[4] & 0x01) == 0x01; } if(decoded.Version >= 2) decoded.DAP |= (feature[4] & 0x80) == 0x80; return decoded; } public static Feature_001F? Decode_001F(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x001F) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_001F(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version >= 2 && feature.Length >= 8) { decoded.MULTI110 |= (feature[4] & 0x01) == 0x01; decoded.DualR |= (feature[6] & 0x01) == 0x01; } // TODO: Check this if(decoded.Version >= 2 && feature.Length >= 8) decoded.DualRW |= (feature[6] & 0x02) == 0x02; return decoded; } public static Feature_0020? Decode_0020(byte[] feature) { if(feature == null) return null; if(feature.Length < 16) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0020) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0020(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version < 1) return decoded; decoded.LastLBA = (uint)((feature[4] << 24) + (feature[5] << 16) + (feature[6] << 8) + feature[7]); decoded.LogicalBlockSize = (uint)((feature[8] << 24) + (feature[9] << 16) + (feature[10] << 8) + feature[11]); decoded.Blocking = (ushort)((feature[12] << 8) + feature[13]); decoded.PP |= (feature[14] & 0x01) == 0x01; return decoded; } public static Feature_0021? Decode_0021(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0021) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0021(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version >= 1) { decoded.DataTypeSupported = (ushort)((feature[4] << 8) + feature[5]); decoded.BUF |= (feature[6] & 0x01) == 0x01; decoded.LinkSizes = new byte[feature[7]]; if(feature.Length > feature[7] + 8) Array.Copy(feature, 8, decoded.LinkSizes, 0, feature[7]); } if(decoded.Version < 3) return decoded; decoded.TRIO |= (feature[6] & 0x04) == 0x04; decoded.ARSV |= (feature[6] & 0x02) == 0x02; return decoded; } public static Feature_0022? Decode_0022(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0022) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0022(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0023? Decode_0023(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0023) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0023(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version >= 1 && feature.Length >= 12) { decoded.RENoSA |= (feature[4] & 0x08) == 0x08; decoded.Expand |= (feature[4] & 0x04) == 0x04; decoded.QCert |= (feature[4] & 0x02) == 0x02; decoded.Cert |= (feature[4] & 0x01) == 0x01; decoded.RRM |= (feature[8] & 0x01) == 0x01; } if(decoded.Version >= 2 && feature.Length >= 12) decoded.FRF |= (feature[4] & 0x80) == 0x80; return decoded; } public static Feature_0024? Decode_0024(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0024) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0024(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version >= 1 && feature.Length >= 8) decoded.SSA |= (feature[4] & 0x80) == 0x80; return decoded; } public static Feature_0025? Decode_0025(byte[] feature) { if(feature == null) return null; if(feature.Length < 12) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0025) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0025(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.LogicalBlockSize = (uint)((feature[4] << 24) + (feature[5] << 16) + (feature[6] << 8) + feature[7]); decoded.Blocking = (ushort)((feature[8] << 8) + feature[9]); decoded.PP |= (feature[10] & 0x01) == 0x01; return decoded; } public static Feature_0026? Decode_0026(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0026) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0026(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0027? Decode_0027(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0027) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0027(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0028? Decode_0028(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0028) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0028(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Write |= (feature[4] & 0x01) == 0x01; if(decoded.Version < 1) return decoded; decoded.DVDPWrite |= (feature[4] & 0x04) == 0x04; decoded.DVDPRead |= (feature[4] & 0x02) == 0x02; return decoded; } public static Feature_0029? Decode_0029(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0029) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0029(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.DRTDM |= (feature[4] & 0x01) == 0x01; decoded.DBICacheZones = feature[5]; decoded.Entries = (ushort)((feature[6] << 8) + feature[7]); return decoded; } public static Feature_002A? Decode_002A(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x002A) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_002A(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Write |= (feature[4] & 0x01) == 0x01; decoded.CloseOnly |= (feature[5] & 0x01) == 0x01; if(decoded.Version >= 1) decoded.QuickStart |= (feature[5] & 0x02) == 0x02; return decoded; } public static Feature_002B? Decode_002B(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x002B) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_002B(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Write |= (feature[4] & 0x01) == 0x01; return decoded; } public static Feature_002C? Decode_002C(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x002C) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_002C(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.DSDG |= (feature[4] & 0x08) == 0x08; decoded.DSDR |= (feature[4] & 0x04) == 0x04; decoded.Intermediate |= (feature[4] & 0x02) == 0x02; decoded.Blank |= (feature[4] & 0x01) == 0x01; return decoded; } public static Feature_002D? Decode_002D(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x002D) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_002D(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.TestWrite |= (feature[4] & 0x04) == 0x04; decoded.CDRW |= (feature[4] & 0x02) == 0x02; decoded.RWSubchannel |= (feature[4] & 0x01) == 0x01; decoded.DataTypeSupported = (ushort)((feature[6] << 8) + feature[7]); if(decoded.Version < 2) return decoded; decoded.BUF |= (feature[4] & 0x40) == 0x40; decoded.RWRaw |= (feature[4] & 0x10) == 0x10; decoded.RWPack |= (feature[4] & 0x08) == 0x08; return decoded; } public static Feature_002E? Decode_002E(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x002E) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_002E(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.SAO |= (feature[4] & 0x20) == 0x20; decoded.RAWMS |= (feature[4] & 0x10) == 0x10; decoded.RAW |= (feature[4] & 0x08) == 0x08; decoded.TestWrite |= (feature[4] & 0x04) == 0x04; decoded.CDRW |= (feature[4] & 0x02) == 0x02; decoded.RW |= (feature[4] & 0x01) == 0x01; decoded.MaxCueSheet = (uint)((feature[5] << 16) + (feature[6] << 8) + feature[7]); if(decoded.Version >= 1) decoded.BUF |= (feature[4] & 0x40) == 0x40; return decoded; } public static Feature_002F? Decode_002F(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x002F) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_002F(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.BUF |= (feature[4] & 0x40) == 0x40; decoded.TestWrite |= (feature[4] & 0x04) == 0x04; if(decoded.Version >= 1) decoded.DVDRW |= (feature[4] & 0x02) == 0x02; if(decoded.Version >= 2) decoded.RDL |= (feature[4] & 0x08) == 0x08; return decoded; } public static Feature_0030? Decode_0030(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0030) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0030(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0031? Decode_0031(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0031) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0031(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.TestWrite |= (feature[4] & 0x04) == 0x04; return decoded; } public static Feature_0032? Decode_0032(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0032) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0032(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Intermediate |= (feature[4] & 0x02) == 0x02; decoded.Blank |= (feature[4] & 0x01) == 0x01; return decoded; } public static Feature_0033? Decode_0033(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0033) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0033(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(feature[7] <= 0 || feature.Length <= feature[7] + 8) return decoded; decoded.LinkSizes = new byte[feature[7]]; Array.Copy(feature, 8, decoded.LinkSizes, 0, feature[7]); return decoded; } public static Feature_0035? Decode_0035(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0035) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0035(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0037? Decode_0037(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0037) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0037(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.SubtypeSupport = feature[5]; return decoded; } public static Feature_0038? Decode_0038(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0038) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0038(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_003A? Decode_003A(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x003A) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_003A(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Write |= (feature[4] & 0x01) == 0x01; decoded.QuickStart |= (feature[5] & 0x02) == 0x02; decoded.CloseOnly |= (feature[5] & 0x01) == 0x01; return decoded; } public static Feature_003B? Decode_003B(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x003B) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_003B(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Write |= (feature[4] & 0x01) == 0x01; return decoded; } public static Feature_0040? Decode_0040(byte[] feature) { if(feature == null) return null; if(feature.Length < 32) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0040) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0040(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.OldRE |= (feature[9] & 0x01) == 0x01; decoded.OldR |= (feature[17] & 0x01) == 0x01; decoded.OldROM |= (feature[25] & 0x01) == 0x01; if(decoded.Version < 1) return decoded; decoded.BCA |= (feature[4] & 0x01) == 0x01; decoded.RE2 |= (feature[9] & 0x04) == 0x04; decoded.RE1 |= (feature[9] & 0x02) == 0x02; decoded.R |= (feature[17] & 0x02) == 0x02; decoded.ROM |= (feature[25] & 0x02) == 0x02; return decoded; } public static Feature_0041? Decode_0041(byte[] feature) { if(feature == null) return null; if(feature.Length < 24) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0041) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0041(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.SVNR |= (feature[4] & 0x01) == 0x01; decoded.OldRE |= (feature[9] & 0x01) == 0x01; decoded.OldR |= (feature[17] & 0x01) == 0x01; if(decoded.Version < 1) return decoded; decoded.RE2 |= (feature[9] & 0x04) == 0x04; decoded.RE1 |= (feature[9] & 0x02) == 0x02; decoded.R |= (feature[17] & 0x02) == 0x02; return decoded; } public static Feature_0042? Decode_0042(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0042) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0042(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0050? Decode_0050(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0050) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0050(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.HDDVDR |= (feature[4] & 0x01) == 0x01; decoded.HDDVDRAM |= (feature[6] & 0x01) == 0x01; return decoded; } public static Feature_0051? Decode_0051(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0051) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0051(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.HDDVDR |= (feature[4] & 0x01) == 0x01; decoded.HDDVDRAM |= (feature[6] & 0x01) == 0x01; return decoded; } public static Feature_0080? Decode_0080(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0080) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0080(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.RI |= (feature[4] & 0x01) == 0x01; return decoded; } public static Feature_0100? Decode_0100(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0100) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0100(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0101? Decode_0101(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0101) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0101(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.PP |= (feature[4] & 0x01) == 0x01; return decoded; } public static Feature_0102? Decode_0102(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0102) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0102(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.SCC |= (feature[4] & 0x10) == 0x10; decoded.SDP |= (feature[4] & 0x04) == 0x04; decoded.HighestSlotNumber = (byte)(feature[7] & 0x1F); return decoded; } public static Feature_0103? Decode_0103(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0103) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0103(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Scan |= (feature[4] & 0x04) == 0x04; decoded.SCM |= (feature[4] & 0x02) == 0x02; decoded.SV |= (feature[4] & 0x01) == 0x01; decoded.VolumeLevels = (ushort)((feature[6] << 8) + feature[7]); return decoded; } public static Feature_0104? Decode_0104(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0104) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0104(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version >= 1 && feature.Length >= 8) decoded.M5 |= (feature[4] & 0x01) == 0x01; return decoded; } public static Feature_0105? Decode_0105(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0105) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0105(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version < 1 || feature.Length < 8) return decoded; decoded.Group3 |= (feature[4] & 0x01) == 0x01; decoded.UnitLength = (ushort)((feature[6] << 8) + feature[7]); return decoded; } public static Feature_0106? Decode_0106(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0106) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0106(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.CSSVersion = feature[7]; return decoded; } public static Feature_0107? Decode_0107(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0107) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0107(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); if(decoded.Version >= 3 && feature.Length >= 8) { decoded.RBCB |= (feature[4] & 0x10) == 0x10; decoded.SCS |= (feature[4] & 0x08) == 0x08; decoded.MP2A |= (feature[4] & 0x04) == 0x04; decoded.WSPD |= (feature[4] & 0x02) == 0x02; decoded.SW |= (feature[4] & 0x01) == 0x01; } if(decoded.Version < 5 || feature.Length < 8) return decoded; decoded.SMP |= (feature[4] & 0x20) == 0x20; decoded.RBCB |= (feature[4] & 0x10) == 0x10; return decoded; } public static Feature_0108? Decode_0108(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0108) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0108(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); byte[] serial = new byte[feature.Length]; Array.Copy(feature, 4, serial, 0, feature.Length - 4); decoded.Serial = StringHandlers.CToString(serial).Trim(); return decoded; } public static Feature_0109? Decode_0109(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0109) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0109(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_010A? Decode_010A(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x010A) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_010A(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.DCBs = new uint[feature[3] / 4]; for(int i = 0; i < decoded.DCBs.Length; i++) decoded.DCBs[i] = (uint)((feature[0 + 4 + (i * 4)] << 24) + (feature[1 + 4 + (i * 4)] << 16) + (feature[2 + 4 + (i * 4)] << 8) + feature[3 + 4 + (i * 4)]); return decoded; } public static Feature_010B? Decode_010B(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x010B) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_010B(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.CPRMVersion = feature[7]; return decoded; } public static Feature_010C? Decode_010C(byte[] feature) { if(feature == null) return null; if(feature.Length < 20) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x010C) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_010C(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.Century = (ushort)((feature[4] << 8) + feature[5]); decoded.Year = (ushort)((feature[6] << 8) + feature[7]); decoded.Month = (ushort)((feature[8] << 8) + feature[9]); decoded.Day = (ushort)((feature[10] << 8) + feature[11]); decoded.Hour = (ushort)((feature[12] << 8) + feature[13]); decoded.Minute = (ushort)((feature[14] << 8) + feature[15]); decoded.Second = (ushort)((feature[16] << 8) + feature[17]); return decoded; } public static Feature_010D? Decode_010D(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x010D) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_010D(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.BNG |= (feature[4] & 0x01) == 0x01; decoded.BindNonceBlocks = feature[5]; decoded.AGIDs = (byte)(feature[6] & 0x0F); decoded.AACSVersion = feature[7]; if(decoded.Version < 2) return decoded; decoded.RDC |= (feature[4] & 0x10) == 0x10; decoded.RMC |= (feature[4] & 0x08) == 0x08; decoded.WBE |= (feature[4] & 0x04) == 0x04; decoded.BEC |= (feature[4] & 0x02) == 0x02; return decoded; } public static Feature_010E? Decode_010E(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x010E) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_010E(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.MaxScrambleExtent = feature[4]; return decoded; } public static Feature_0110? Decode_0110(byte[] feature) { if(feature == null) return null; if(feature.Length < 8) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0110) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0110(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0113? Decode_0113(byte[] feature) { if(feature == null) return null; if(feature.Length < 4) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0113) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0113(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); return decoded; } public static Feature_0142? Decode_0142(byte[] feature) { if(feature == null) return null; if(feature.Length < 6) return null; ushort number = (ushort)((feature[0] << 8) + feature[1]); if(number != 0x0142) return null; if(feature[3] + 4 != feature.Length) return null; var decoded = new Feature_0142(); decoded.Current |= (feature[2] & 0x01) == 0x01; decoded.Persistent |= (feature[2] & 0x02) == 0x02; decoded.Version = (byte)((feature[2] & 0x3C) >> 2); decoded.PSAU |= (feature[4] & 0x80) == 0x80; decoded.LOSPB |= (feature[4] & 0x40) == 0x40; decoded.ME |= (feature[4] & 0x01) == 0x01; decoded.Profiles = new ushort[feature[5]]; if((feature[5] * 2) + 6 != feature.Length) return decoded; for(int i = 0; i < feature[5]; i++) decoded.Profiles[i] = (ushort)((feature[0 + 6 + (2 * i)] << 8) + feature[1 + 6 + (2 * i)]); return decoded; } public static string Prettify_0000(Feature_0000? feature) { if(!feature.HasValue) return null; Feature_0000 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Supported Profiles:"); if(ftr.Profiles == null) return sb.ToString(); foreach(Profile prof in ftr.Profiles) { switch(prof.Number) { case ProfileNumber.Reserved: sb.Append("\tDrive reported a reserved profile number"); break; case ProfileNumber.NonRemovable: sb.Append("\tDrive supports non-removable changeable media"); break; case ProfileNumber.Removable: sb.Append("\tDrive supports rewritable and removable media"); break; case ProfileNumber.MOErasable: sb.Append("\tDrive supports Magnet-Optical media"); break; case ProfileNumber.OpticalWORM: sb.Append("\tDrive supports optical write-once media"); break; case ProfileNumber.ASMO: sb.Append("\tDrive supports Advanced Storage - Magneto-Optical"); break; case ProfileNumber.CDROM: sb.Append("\tDrive supports CD-ROM"); break; case ProfileNumber.CDR: sb.Append("\tDrive supports CD-R"); break; case ProfileNumber.CDRW: sb.Append("\tDrive supports CD-RW"); break; case ProfileNumber.DVDROM: sb.Append("\tDrive supports DVD-ROM"); break; case ProfileNumber.DVDRSeq: sb.Append("\tDrive supports DVD-R"); break; case ProfileNumber.DVDRAM: sb.Append("\tDrive supports DVD-RAM"); break; case ProfileNumber.DVDRWRes: sb.Append("\tDrive supports restricted overwrite DVD-RW"); break; case ProfileNumber.DVDRWSeq: sb.Append("\tDrive supports sequentially recorded DVD-RW"); break; case ProfileNumber.DVDRDLSeq: sb.Append("\tDrive supports sequentially recorded DVD-R DL"); break; case ProfileNumber.DVDRDLJump: sb.Append("\tDrive supports layer jump recorded DVD-R DL"); break; case ProfileNumber.DVDRWDL: sb.Append("\tDrive supports DVD-RW DL"); break; case ProfileNumber.DVDDownload: sb.Append("\tDrive supports DVD-Download"); break; case ProfileNumber.DVDRWPlus: sb.Append("\tDrive supports DVD+RW"); break; case ProfileNumber.DVDRPlus: sb.Append("\tDrive supports DVD+R"); break; case ProfileNumber.DDCDROM: sb.Append("\tDrive supports DDCD-ROM"); break; case ProfileNumber.DDCDR: sb.Append("\tDrive supports DDCD-R"); break; case ProfileNumber.DDCDRW: sb.Append("\tDrive supports DDCD-RW"); break; case ProfileNumber.DVDRWDLPlus: sb.Append("\tDrive supports DVD+RW DL"); break; case ProfileNumber.DVDRDLPlus: sb.Append("\tDrive supports DVD+R DL"); break; case ProfileNumber.BDROM: sb.Append("\tDrive supports BD-ROM"); break; case ProfileNumber.BDRSeq: sb.Append("\tDrive supports BD-R SRM"); break; case ProfileNumber.BDRRdm: sb.Append("\tDrive supports BD-R RRM"); break; case ProfileNumber.BDRE: sb.Append("\tDrive supports BD-RE"); break; case ProfileNumber.HDDVDROM: sb.Append("\tDrive supports HD DVD-ROM"); break; case ProfileNumber.HDDVDR: sb.Append("\tDrive supports HD DVD-R"); break; case ProfileNumber.HDDVDRAM: sb.Append("\tDrive supports HD DVD-RAM"); break; case ProfileNumber.HDDVDRW: sb.Append("\tDrive supports HD DVD-RW"); break; case ProfileNumber.HDDVDRDL: sb.Append("\tDrive supports HD DVD-R DL"); break; case ProfileNumber.HDDVDRWDL: sb.Append("\tDrive supports HD DVD-RW DL"); break; case ProfileNumber.HDBURNROM: sb.Append("\tDrive supports HDBurn CD-ROM"); break; case ProfileNumber.HDBURNR: sb.Append("\tDrive supports HDBurn CD-R"); break; case ProfileNumber.HDBURNRW: sb.Append("\tDrive supports HDBurn CD-RW"); break; case ProfileNumber.Unconforming: sb.Append("\tDrive is not conforming to any profile"); break; default: sb.AppendFormat("\tDrive informs of unknown profile 0x{0:X4}", (ushort)prof.Number); break; } if(prof.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); } return sb.ToString(); } public static string Prettify_0001(Feature_0001? feature) { if(!feature.HasValue) return null; Feature_0001 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Core Feature:"); sb.Append("\tDrive uses "); switch(ftr.PhysicalInterfaceStandard) { case PhysicalInterfaces.Unspecified: sb.AppendLine("an unspecified physical interface"); break; case PhysicalInterfaces.SCSI: sb.AppendLine("SCSI interface"); break; case PhysicalInterfaces.ATAPI: sb.AppendLine("ATAPI interface"); break; case PhysicalInterfaces.IEEE1394: sb.AppendLine("IEEE-1394 interface"); break; case PhysicalInterfaces.IEEE1394A: sb.AppendLine("IEEE-1394A interface"); break; case PhysicalInterfaces.FC: sb.AppendLine("Fibre Channel interface"); break; case PhysicalInterfaces.IEEE1394B: sb.AppendLine("IEEE-1394B interface"); break; case PhysicalInterfaces.SerialATAPI: sb.AppendLine("Serial ATAPI interface"); break; case PhysicalInterfaces.USB: sb.AppendLine("USB interface"); break; case PhysicalInterfaces.Vendor: sb.AppendLine("a vendor unique interface"); break; default: sb.AppendFormat("an unknown interface with code {0}", (uint)ftr.PhysicalInterfaceStandard). AppendLine(); break; } if(ftr.DBE) sb.AppendLine("\tDrive supports Device Busy events"); if(ftr.INQ2) sb.AppendLine("\tDrive supports EVPD, Page Code and 16-bit Allocation Length as described in SPC-3"); return sb.ToString(); } public static string Prettify_0002(Feature_0002? feature) { if(!feature.HasValue) return null; Feature_0002 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Morphing:"); sb.AppendLine(ftr.Async ? "\tDrive supports polling and asynchronous GET EVENT STATUS NOTIFICATION" : "\tDrive supports only polling GET EVENT STATUS NOTIFICATION"); if(ftr.OCEvent) sb.AppendLine("\tDrive supports operational change request / notification class events"); return sb.ToString(); } public static string Prettify_0003(Feature_0003? feature) { if(!feature.HasValue) return null; Feature_0003 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Removable Medium:"); switch(ftr.LoadingMechanismType) { case 0: sb.AppendLine("\tDrive uses media caddy"); break; case 1: sb.AppendLine("\tDrive uses a tray"); break; case 2: sb.AppendLine("\tDrive is pop-up"); break; case 4: sb.AppendLine("\tDrive is a changer with individually changeable discs"); break; case 5: sb.AppendLine("\tDrive is a changer using cartridges"); break; default: sb.AppendFormat("\tDrive uses unknown loading mechanism type {0}", ftr.LoadingMechanismType). AppendLine(); break; } if(ftr.Lock) sb.AppendLine("\tDrive can lock media"); if(ftr.PreventJumper) sb.AppendLine("\tDrive power ups locked"); if(ftr.Eject) sb.AppendLine("\tDrive can eject media"); if(ftr.Load) sb.AppendLine("\tDrive can load media"); if(ftr.DBML) sb.AppendLine("\tDrive reports Device Busy Class events during medium loading/unloading"); return sb.ToString(); } public static string Prettify_0004(Feature_0004? feature) { if(!feature.HasValue) return null; Feature_0004 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Write Protect:"); if(ftr.DWP) sb.AppendLine("\tDrive supports reading/writing the Disc Write Protect PAC on BD-R/-RE media"); if(ftr.WDCB) sb.AppendLine("\tDrive supports writing the Write Inhibit DCB on DVD+RW media"); if(ftr.SPWP) sb.AppendLine("\tDrive supports set/release of PWP status"); if(ftr.SSWPP) sb.AppendLine("\tDrive supports the SWPP bit of the Timeout and Protect mode page"); return sb.ToString(); } public static string Prettify_0010(Feature_0010? feature) { if(!feature.HasValue) return null; Feature_0010 ftr = feature.Value; var sb = new StringBuilder(); sb.Append("MMC Random Readable"); if(ftr.Current) sb.Append(" (current)"); sb.AppendLine(":"); if(ftr.PP) sb.AppendLine("\tDrive shall report Read/Write Error Recovery mode page"); if(ftr.LogicalBlockSize > 0) sb.AppendFormat("\t{0} bytes per logical block", ftr.LogicalBlockSize).AppendLine(); if(ftr.Blocking > 1) sb.AppendFormat("\t{0} logical blocks per media readable unit", ftr.Blocking).AppendLine(); return sb.ToString(); } public static string Prettify_001D(Feature_001D? feature) => !feature.HasValue ? null : "Drive claims capability to read all CD formats according to OSTA Multi-Read Specification\n"; public static string Prettify_001E(Feature_001E? feature) { if(!feature.HasValue) return null; Feature_001E ftr = feature.Value; var sb = new StringBuilder(); sb.Append("MMC CD Read"); if(ftr.Current) sb.Append(" (current)"); sb.AppendLine(":"); if(ftr.DAP) sb.AppendLine("\tDrive supports the DAP bit in the READ CD and READ CD MSF commands"); if(ftr.C2) sb.AppendLine("\tDrive supports C2 Error Pointers"); if(ftr.CDText) sb.AppendLine("\tDrive can return CD-Text from Lead-In"); return sb.ToString(); } public static string Prettify_001F(Feature_001F? feature) { if(!feature.HasValue) return null; Feature_001F ftr = feature.Value; var sb = new StringBuilder(); sb.Append("MMC DVD Read"); if(ftr.Current) sb.Append(" (current)"); sb.AppendLine(":"); sb.AppendLine("\tDrive can read DVD media"); if(ftr.DualR) sb.AppendLine("\tDrive can read DVD-R DL from all recording modes"); if(ftr.DualRW) sb.AppendLine("\tDrive can read DVD-RW DL from all recording modes"); if(ftr.MULTI110) sb.AppendLine("\tDrive conforms to DVD Multi Drive Read-only Specifications"); return sb.ToString(); } public static string Prettify_0020(Feature_0020? feature) { if(!feature.HasValue) return null; Feature_0020 ftr = feature.Value; var sb = new StringBuilder(); sb.Append("MMC Random Writable:"); if(ftr.Current) sb.Append(" (current)"); sb.AppendLine(":"); if(ftr.PP) sb.AppendLine("\tDrive shall report Read/Write Error Recovery mode page"); if(ftr.LogicalBlockSize > 0) sb.AppendFormat("\t{0} bytes per logical block", ftr.LogicalBlockSize).AppendLine(); if(ftr.Blocking > 1) sb.AppendFormat("\t{0} logical blocks per media writable unit", ftr.Blocking).AppendLine(); if(ftr.LastLBA > 0) sb.AppendFormat("\tLast adressable logical block is {0}", ftr.LastLBA).AppendLine(); return sb.ToString(); } public static string Prettify_0021(Feature_0021? feature) { if(!feature.HasValue) return null; Feature_0021 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Incremental Streaming Writable:"); if(ftr.DataTypeSupported > 0) { sb.Append("\tDrive supports data block types:"); if((ftr.DataTypeSupported & 0x0001) == 0x0001) sb.Append(" 0"); if((ftr.DataTypeSupported & 0x0002) == 0x0002) sb.Append(" 1"); if((ftr.DataTypeSupported & 0x0004) == 0x0004) sb.Append(" 2"); if((ftr.DataTypeSupported & 0x0008) == 0x0008) sb.Append(" 3"); if((ftr.DataTypeSupported & 0x0010) == 0x0010) sb.Append(" 4"); if((ftr.DataTypeSupported & 0x0020) == 0x0020) sb.Append(" 5"); if((ftr.DataTypeSupported & 0x0040) == 0x0040) sb.Append(" 6"); if((ftr.DataTypeSupported & 0x0080) == 0x0080) sb.Append(" 7"); if((ftr.DataTypeSupported & 0x0100) == 0x0100) sb.Append(" 8"); if((ftr.DataTypeSupported & 0x0200) == 0x0200) sb.Append(" 9"); if((ftr.DataTypeSupported & 0x0400) == 0x0400) sb.Append(" 10"); if((ftr.DataTypeSupported & 0x0800) == 0x0800) sb.Append(" 11"); if((ftr.DataTypeSupported & 0x1000) == 0x1000) sb.Append(" 12"); if((ftr.DataTypeSupported & 0x2000) == 0x2000) sb.Append(" 13"); if((ftr.DataTypeSupported & 0x4000) == 0x4000) sb.Append(" 14"); if((ftr.DataTypeSupported & 0x8000) == 0x8000) sb.Append(" 15"); sb.AppendLine(); } if(ftr.TRIO) sb.AppendLine("\tDrive claims support to report Track Resources Information"); if(ftr.ARSV) sb.AppendLine("\tDrive supports address mode reservation on the RESERVE TRACK command"); if(ftr.BUF) sb.AppendLine("\tDrive is capable of zero loss linking"); return sb.ToString(); } public static string Prettify_0022(Feature_0022? feature) => !feature.HasValue ? null : "Drive supports media that require erasing before writing\n"; public static string Prettify_0023(Feature_0023? feature) { if(!feature.HasValue) return null; Feature_0023 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Formattable:"); sb.AppendLine("\tDrive can format media into logical blocks"); if(ftr.RENoSA) sb.AppendLine("\tDrive can format BD-RE with no spares allocated"); if(ftr.Expand) sb.AppendLine("\tDrive can expand the spare area on a formatted BD-RE disc"); if(ftr.QCert) sb.AppendLine("\tDrive can format BD-RE discs with quick certification"); if(ftr.Cert) sb.AppendLine("\tDrive can format BD-RE discs with full certification"); if(ftr.FRF) sb.AppendLine("\tDrive can fast re-format BD-RE discs"); if(ftr.RRM) sb.AppendLine("\tDrive can format BD-R discs with RRM format"); return sb.ToString(); } public static string Prettify_0024(Feature_0024? feature) { if(!feature.HasValue) return null; Feature_0024 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Hardware Defect Management:"); sb.AppendLine("\tDrive shall be able to provide a defect-free contiguous address space"); if(ftr.SSA) sb.AppendLine("\tDrive can return Spare Area Information"); return sb.ToString(); } public static string Prettify_0025(Feature_0025? feature) { if(!feature.HasValue) return null; Feature_0025 ftr = feature.Value; var sb = new StringBuilder(); sb.Append("MMC Write Once"); if(ftr.Current) sb.Append(" (current)"); sb.AppendLine(":"); if(ftr.PP) sb.AppendLine("\tDrive shall report Read/Write Error Recovery mode page"); if(ftr.LogicalBlockSize > 0) sb.AppendFormat("\t{0} bytes per logical block", ftr.LogicalBlockSize).AppendLine(); if(ftr.Blocking > 1) sb.AppendFormat("\t{0} logical blocks per media writable unit", ftr.Blocking).AppendLine(); return sb.ToString(); } public static string Prettify_0026(Feature_0026? feature) => !feature.HasValue ? null : "Drive shall have the ability to overwrite logical blocks only in fixed sets at a time\n"; public static string Prettify_0027(Feature_0027? feature) { if(!feature.HasValue) return null; Feature_0027 ftr = feature.Value; var sb = new StringBuilder(); sb.Append("Drive can write High-Speed CD-RW"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); return sb.ToString(); } public static string Prettify_0028(Feature_0028? feature) { if(!feature.HasValue) return null; Feature_0028 ftr = feature.Value; var sb = new StringBuilder(); if(ftr.Write && ftr.DVDPRead && ftr.DVDPWrite) sb.Append("Drive can read and write CD-MRW and DVD+MRW"); else if(ftr.DVDPRead && ftr.DVDPWrite) sb.Append("Drive can read and write DVD+MRW"); else if(ftr.Write && ftr.DVDPRead) sb.Append("Drive and read DVD+MRW and read and write CD-MRW"); else if(ftr.Write) sb.Append("Drive can read and write CD-MRW"); else if(ftr.DVDPRead) sb.Append("Drive can read CD-MRW and DVD+MRW"); else sb.Append("Drive can read CD-MRW"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); return sb.ToString(); } public static string Prettify_0029(Feature_0029? feature) { if(!feature.HasValue) return null; Feature_0029 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Enhanced Defect Reporting Feature:"); sb.AppendLine(ftr.DRTDM ? "\tDrive supports DRT-DM mode" : "\tDrive supports Persistent-DM mode"); if(ftr.DBICacheZones > 0) sb.AppendFormat("\tDrive has {0} DBI cache zones", ftr.DBICacheZones).AppendLine(); if(ftr.Entries > 0) sb.AppendFormat("\tDrive has {0} DBI entries", ftr.Entries).AppendLine(); return sb.ToString(); } public static string Prettify_002A(Feature_002A? feature) { if(!feature.HasValue) return null; Feature_002A ftr = feature.Value; var sb = new StringBuilder(); if(ftr.Write) { sb.Append("Drive can read and write DVD+RW"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); sb.AppendLine(ftr.CloseOnly ? "\tDrive supports only the read compatibility stop" : "\tDrive supports both forms of background format stopping"); if(ftr.QuickStart) sb.AppendLine("\tDrive can do a quick start formatting"); } else { sb.Append("Drive can read DVD+RW"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); } return sb.ToString(); } public static string Prettify_002B(Feature_002B? feature) { if(!feature.HasValue) return null; Feature_002B ftr = feature.Value; var sb = new StringBuilder(); if(ftr.Write) { sb.Append("Drive can read and write DVD+R"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); } else { sb.Append("Drive can read DVD+R"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); } return sb.ToString(); } public static string Prettify_002C(Feature_002C? feature) { if(!feature.HasValue) return null; Feature_002C ftr = feature.Value; var sb = new StringBuilder(); sb.Append("MMC Rigid Restricted Overwrite"); sb.AppendLine(ftr.Current ? " (current):" : ":"); if(ftr.Blank) sb.AppendLine("\tDrive supports the BLANK command"); if(ftr.Intermediate) sb.AppendLine("\tDrive supports writing on an intermediate state session and quick formatting"); if(ftr.DSDR) sb.AppendLine("\tDrive can read Defect Status data recorded on the medium"); if(ftr.DSDG) sb.AppendLine("\tDrive can generate Defect Status data during formatting"); return sb.ToString(); } public static string Prettify_002D(Feature_002D? feature) { if(!feature.HasValue) return null; Feature_002D ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive can write CDs in Track at Once Mode:"); if(ftr.RWSubchannel) { sb.AppendLine("\tDrive can write user provided data in the R-W subchannels"); if(ftr.RWRaw) sb.AppendLine("\tDrive accepts RAW R-W subchannel data"); if(ftr.RWPack) sb.AppendLine("\tDrive accepts Packed R-W subchannel data"); } if(ftr.CDRW) sb.AppendLine("\tDrive can overwrite a TAO track with another in CD-RWs"); if(ftr.TestWrite) sb.AppendLine("\tDrive can do a test writing"); if(ftr.BUF) sb.AppendLine("\tDrive supports zero loss linking"); if(ftr.DataTypeSupported <= 0) return sb.ToString(); sb.Append("\tDrive supports data block types:"); if((ftr.DataTypeSupported & 0x0001) == 0x0001) sb.Append(" 0"); if((ftr.DataTypeSupported & 0x0002) == 0x0002) sb.Append(" 1"); if((ftr.DataTypeSupported & 0x0004) == 0x0004) sb.Append(" 2"); if((ftr.DataTypeSupported & 0x0008) == 0x0008) sb.Append(" 3"); if((ftr.DataTypeSupported & 0x0010) == 0x0010) sb.Append(" 4"); if((ftr.DataTypeSupported & 0x0020) == 0x0020) sb.Append(" 5"); if((ftr.DataTypeSupported & 0x0040) == 0x0040) sb.Append(" 6"); if((ftr.DataTypeSupported & 0x0080) == 0x0080) sb.Append(" 7"); if((ftr.DataTypeSupported & 0x0100) == 0x0100) sb.Append(" 8"); if((ftr.DataTypeSupported & 0x0200) == 0x0200) sb.Append(" 9"); if((ftr.DataTypeSupported & 0x0400) == 0x0400) sb.Append(" 10"); if((ftr.DataTypeSupported & 0x0800) == 0x0800) sb.Append(" 11"); if((ftr.DataTypeSupported & 0x1000) == 0x1000) sb.Append(" 12"); if((ftr.DataTypeSupported & 0x2000) == 0x2000) sb.Append(" 13"); if((ftr.DataTypeSupported & 0x4000) == 0x4000) sb.Append(" 14"); if((ftr.DataTypeSupported & 0x8000) == 0x8000) sb.Append(" 15"); sb.AppendLine(); return sb.ToString(); } public static string Prettify_002E(Feature_002E? feature) { if(!feature.HasValue) return null; Feature_002E ftr = feature.Value; var sb = new StringBuilder(); if(ftr.SAO && !ftr.RAW) sb.AppendLine("Drive can write CDs in Session at Once Mode:"); else if(!ftr.SAO && ftr.RAW) sb.AppendLine("Drive can write CDs in raw Mode:"); else sb.AppendLine("Drive can write CDs in Session at Once and in Raw Modes:"); if(ftr.RAW && ftr.RAWMS) sb.AppendLine("\tDrive can write multi-session CDs in raw mode"); if(ftr.RW) sb.AppendLine("\tDrive can write user provided data in the R-W subchannels"); if(ftr.CDRW) sb.AppendLine("\tDrive can write CD-RWs"); if(ftr.TestWrite) sb.AppendLine("\tDrive can do a test writing"); if(ftr.BUF) sb.AppendLine("\tDrive supports zero loss linking"); if(ftr.MaxCueSheet > 0) sb.AppendFormat("\tDrive supports a maximum of {0} bytes in a single cue sheet", ftr.MaxCueSheet). AppendLine(); return sb.ToString(); } public static string Prettify_002F(Feature_002F? feature) { if(!feature.HasValue) return null; Feature_002F ftr = feature.Value; var sb = new StringBuilder(); if(ftr.DVDRW && ftr.RDL) sb.AppendLine("Drive supports writing DVD-R, DVD-RW and DVD-R DL"); else if(ftr.RDL) sb.AppendLine("Drive supports writing DVD-R and DVD-R DL"); else if(ftr.DVDRW) sb.AppendLine("Drive supports writing DVD-R and DVD-RW"); else sb.AppendLine("Drive supports writing DVD-R"); if(ftr.TestWrite) sb.AppendLine("\tDrive can do a test writing"); if(ftr.BUF) sb.AppendLine("\tDrive supports zero loss linking"); return sb.ToString(); } public static string Prettify_0030(Feature_0030? feature) => !feature.HasValue ? null : "Drive can read DDCDs\n"; public static string Prettify_0031(Feature_0031? feature) { if(!feature.HasValue) return null; Feature_0031 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive supports writing DDCD-R"); if(ftr.TestWrite) sb.AppendLine("\tDrive can do a test writing"); return sb.ToString(); } public static string Prettify_0032(Feature_0032? feature) { if(!feature.HasValue) return null; Feature_0032 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive supports writing DDCD-RW"); if(ftr.Blank) sb.AppendLine("\tDrive supports the BLANK command"); if(ftr.Intermediate) sb.AppendLine("\tDrive supports quick formatting"); return sb.ToString(); } public static string Prettify_0033(Feature_0033? feature) { if(!feature.HasValue) return null; Feature_0033 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Layer Jump Recording:"); if(ftr.LinkSizes == null) return sb.ToString(); foreach(byte link in ftr.LinkSizes) sb.AppendFormat("\tCurrent media has a {0} bytes link available", link).AppendLine(); return sb.ToString(); } public static string Prettify_0035(Feature_0035? feature) => !feature.HasValue ? null : "Drive can stop a long immediate operation\n"; public static string Prettify_0037(Feature_0037? feature) { if(!feature.HasValue) return null; Feature_0037 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive can write CD-RW"); if(ftr.SubtypeSupport <= 0) return sb.ToString(); sb.Append("\tDrive supports CD-RW subtypes"); if((ftr.SubtypeSupport & 0x01) == 0x01) sb.Append(" 0"); if((ftr.SubtypeSupport & 0x02) == 0x02) sb.Append(" 1"); if((ftr.SubtypeSupport & 0x04) == 0x04) sb.Append(" 2"); if((ftr.SubtypeSupport & 0x08) == 0x08) sb.Append(" 3"); if((ftr.SubtypeSupport & 0x10) == 0x10) sb.Append(" 4"); if((ftr.SubtypeSupport & 0x20) == 0x20) sb.Append(" 5"); if((ftr.SubtypeSupport & 0x40) == 0x40) sb.Append(" 6"); if((ftr.SubtypeSupport & 0x80) == 0x80) sb.Append(" 7"); sb.AppendLine(); return sb.ToString(); } public static string Prettify_0038(Feature_0038? feature) => !feature.HasValue ? null : "Drive can write BD-R on Pseudo-OVerwrite SRM mode\n"; public static string Prettify_003A(Feature_003A? feature) { if(!feature.HasValue) return null; Feature_003A ftr = feature.Value; var sb = new StringBuilder(); if(ftr.Write) { sb.Append("Drive can read and write DVD+RW DL"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); sb.AppendLine(ftr.CloseOnly ? "\tDrive supports only the read compatibility stop" : "\tDrive supports both forms of background format stopping"); if(ftr.QuickStart) sb.AppendLine("\tDrive can do a quick start formatting"); } else { sb.Append("Drive can read DVD+RW DL"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); } return sb.ToString(); } public static string Prettify_003B(Feature_003B? feature) { if(!feature.HasValue) return null; Feature_003B ftr = feature.Value; var sb = new StringBuilder(); if(ftr.Write) { sb.Append("Drive can read and write DVD+R DL"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); } else { sb.Append("Drive can read DVD+R DL"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); } return sb.ToString(); } public static string Prettify_0040(Feature_0040? feature) { if(!feature.HasValue) return null; Feature_0040 ftr = feature.Value; var sb = new StringBuilder(); sb.Append("MMC BD Read"); sb.AppendLine(ftr.Current ? " (current):" : ":"); if(ftr.OldROM) sb.AppendLine("\tDrive can read BD-ROM pre-1.0"); if(ftr.ROM) sb.AppendLine("\tDrive can read BD-ROM Ver.1"); if(ftr.OldR) sb.AppendLine("\tDrive can read BD-R pre-1.0"); if(ftr.R) sb.AppendLine("\tDrive can read BD-R Ver.1"); if(ftr.OldRE) sb.AppendLine("\tDrive can read BD-RE pre-1.0"); if(ftr.RE1) sb.AppendLine("\tDrive can read BD-RE Ver.1"); if(ftr.RE2) sb.AppendLine("\tDrive can read BD-RE Ver.2"); if(ftr.BCA) sb.AppendLine("\tDrive can read BD's Burst Cutting Area"); return sb.ToString(); } public static string Prettify_0041(Feature_0041? feature) { if(!feature.HasValue) return null; Feature_0041 ftr = feature.Value; var sb = new StringBuilder(); sb.Append("MMC BD Write"); sb.AppendLine(ftr.Current ? " (current):" : ":"); if(ftr.OldR) sb.AppendLine("\tDrive can write BD-R pre-1.0"); if(ftr.R) sb.AppendLine("\tDrive can write BD-R Ver.1"); if(ftr.OldRE) sb.AppendLine("\tDrive can write BD-RE pre-1.0"); if(ftr.RE1) sb.AppendLine("\tDrive can write BD-RE Ver.1"); if(ftr.RE2) sb.AppendLine("\tDrive can write BD-RE Ver.2"); if(ftr.SVNR) sb.AppendLine("\tDrive supports write without verify requirement"); return sb.ToString(); } public static string Prettify_0042(Feature_0042? feature) => !feature.HasValue ? null : "Drive is able to detect and report defective writable unit and behave accordinly\n"; public static string Prettify_0050(Feature_0050? feature) { if(!feature.HasValue) return null; Feature_0050 ftr = feature.Value; var sb = new StringBuilder(); if(ftr.HDDVDR && ftr.HDDVDRAM) sb.Append("Drive can read HD DVD-ROM, HD DVD-RW, HD DVD-R and HD DVD-RAM"); else if(ftr.HDDVDR) sb.Append("Drive can read HD DVD-ROM, HD DVD-RW and HD DVD-R"); else if(ftr.HDDVDRAM) sb.Append("Drive can read HD DVD-ROM, HD DVD-RW and HD DVD-RAM"); else sb.Append("Drive can read HD DVD-ROM and HD DVD-RW"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); return sb.ToString(); } public static string Prettify_0051(Feature_0051? feature) { if(!feature.HasValue) return null; Feature_0051 ftr = feature.Value; var sb = new StringBuilder(); if(ftr.HDDVDR && ftr.HDDVDRAM) sb.Append("Drive can write HD DVD-RW, HD DVD-R and HD DVD-RAM"); else if(ftr.HDDVDR) sb.Append("Drive can write HD DVD-RW and HD DVD-R"); else if(ftr.HDDVDRAM) sb.Append("Drive can write HD DVD-RW and HD DVD-RAM"); else sb.Append("Drive can write HD DVD-RW"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); return sb.ToString(); } public static string Prettify_0080(Feature_0080? feature) { if(!feature.HasValue) return null; Feature_0080 ftr = feature.Value; var sb = new StringBuilder(); sb.Append("Drive is able to access Hybrid discs"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); if(ftr.RI) sb.AppendLine("\tDrive is able to maintain the online format layer through reset and power cycling"); return sb.ToString(); } public static string Prettify_0100(Feature_0100? feature) => !feature.HasValue ? null : "Drive is able to perform host and drive directed power management\n"; public static string Prettify_0101(Feature_0101? feature) { if(!feature.HasValue) return null; Feature_0101 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive supports S.M.A.R.T."); if(ftr.PP) sb.AppendLine("\tDrive supports the Informational Exceptions Control mode page 1Ch"); return sb.ToString(); } public static string Prettify_0102(Feature_0102? feature) { if(!feature.HasValue) return null; Feature_0102 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Embedded Changer:"); if(ftr.SCC) sb.AppendLine("\tDrive can change disc side"); if(ftr.SDP) sb.AppendLine("\tDrive is able to report slots contents after a reset or change"); sb.AppendFormat("\tDrive has {0} slots", ftr.HighestSlotNumber + 1).AppendLine(); return sb.ToString(); } public static string Prettify_0103(Feature_0103? feature) { if(!feature.HasValue) return null; Feature_0103 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive has an analogue audio output"); if(ftr.Scan) sb.AppendLine("\tDrive supports the SCAN command"); if(ftr.SCM) sb.AppendLine("\tDrive is able to mute channels separately"); if(ftr.SV) sb.AppendLine("\tDrive supports separate volume per channel"); sb.AppendFormat("\tDrive has {0} volume levels", ftr.VolumeLevels + 1).AppendLine(); return sb.ToString(); } public static string Prettify_0104(Feature_0104? feature) { if(!feature.HasValue) return null; Feature_0104 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive supports Microcode Upgrade"); if(ftr.M5) sb.AppendLine("Drive supports validating the 5-bit Mode of the READ BUFFER and WRITE BUFFER commands"); return sb.ToString(); } public static string Prettify_0105(Feature_0105? feature) { if(!feature.HasValue) return null; Feature_0105 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive supports Timeout & Protect mode page 1Dh"); if(!ftr.Group3) return sb.ToString(); sb.AppendLine("\tDrive supports the Group3 in Timeout & Protect mode page 1Dh"); if(ftr.UnitLength > 0) sb.AppendFormat("\tDrive has {0} increase of Group 3 time unit", ftr.UnitLength).AppendLine(); return sb.ToString(); } public static string Prettify_0106(Feature_0106? feature) { if(!feature.HasValue) return null; Feature_0106 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendFormat("Drive supports DVD CSS/CPPM version {0}", ftr.CSSVersion); if(ftr.Current) sb.AppendLine(" and current disc is encrypted"); else sb.AppendLine(); return sb.ToString(); } public static string Prettify_0107(Feature_0107? feature) { if(!feature.HasValue) return null; Feature_0107 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("MMC Real Time Streaming:"); if(ftr.SMP) sb.AppendLine("\tDrive supports Set Minimum Performance with the SET STREAMING command"); if(ftr.RBCB) sb.AppendLine("\tDrive supports the block bit in the READ BUFFER CAPACITY command"); if(ftr.SCS) sb.AppendLine("\tDrive supports the SET CD SPEED command"); if(ftr.MP2A) sb.AppendLine("\tDrive supports the Write Speed Performance Descriptor Blocks in the MMC mode page 2Ah"); if(ftr.WSPD) sb.AppendLine("\tDrive supports the Write Speed data of GET PERFORMANCE and the WRC field of SET STREAMING"); if(ftr.SW) sb.AppendLine("\tDrive supports stream recording"); return sb.ToString(); } public static string Prettify_0108(Feature_0108? feature) { if(!feature.HasValue) return null; Feature_0108 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendFormat("Drive serial number: {0}", ftr.Serial).AppendLine(); return sb.ToString(); } public static string Prettify_0109(Feature_0109? feature) => !feature.HasValue ? null : "Drive is able to read media serial number\n"; public static string Prettify_010A(Feature_010A? feature) { if(!feature.HasValue) return null; Feature_010A ftr = feature.Value; var sb = new StringBuilder(); if(ftr.DCBs == null) return sb.ToString(); foreach(uint dcb in ftr.DCBs) sb.AppendFormat("Drive supports DCB {0:X8}h", dcb).AppendLine(); return sb.ToString(); } public static string Prettify_010B(Feature_010B? feature) { if(!feature.HasValue) return null; Feature_010B ftr = feature.Value; var sb = new StringBuilder(); sb.AppendFormat("Drive supports DVD CPRM version {0}", ftr.CPRMVersion); if(ftr.Current) sb.AppendLine(" and current disc is or can be encrypted"); else sb.AppendLine(); return sb.ToString(); } public static string Prettify_010C(Feature_010C? feature) { if(!feature.HasValue) return null; Feature_010C ftr = feature.Value; var sb = new StringBuilder(); byte[] temp = new byte[4]; temp[0] = (byte)((ftr.Century & 0xFF00) >> 8); temp[1] = (byte)(ftr.Century & 0xFF); temp[2] = (byte)((ftr.Year & 0xFF00) >> 8); temp[3] = (byte)(ftr.Year & 0xFF); string syear = Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr.Month & 0xFF00) >> 8); temp[1] = (byte)(ftr.Month & 0xFF); string smonth = Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr.Day & 0xFF00) >> 8); temp[1] = (byte)(ftr.Day & 0xFF); string sday = Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr.Hour & 0xFF00) >> 8); temp[1] = (byte)(ftr.Hour & 0xFF); string shour = Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr.Minute & 0xFF00) >> 8); temp[1] = (byte)(ftr.Minute & 0xFF); string sminute = Encoding.ASCII.GetString(temp); temp = new byte[2]; temp[0] = (byte)((ftr.Second & 0xFF00) >> 8); temp[1] = (byte)(ftr.Second & 0xFF); string ssecond = Encoding.ASCII.GetString(temp); try { var fwDate = new DateTime(int.Parse(syear), int.Parse(smonth), int.Parse(sday), int.Parse(shour), int.Parse(sminute), int.Parse(ssecond), DateTimeKind.Utc); sb.AppendFormat("Drive firmware is dated {0}", fwDate).AppendLine(); } #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch { // ignored } #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body return sb.ToString(); } public static string Prettify_010D(Feature_010D? feature) { if(!feature.HasValue) return null; Feature_010D ftr = feature.Value; var sb = new StringBuilder(); sb.AppendFormat("Drive supports AACS version {0}", ftr.AACSVersion); if(ftr.Current) sb.AppendLine(" and current disc is encrypted"); else sb.AppendLine(); if(ftr.RDC) sb.AppendLine("\tDrive supports reading the Drive Certificate"); if(ftr.RMC) sb.AppendLine("\tDrive supports reading Media Key Block of CPRM"); if(ftr.WBE) sb.AppendLine("\tDrive supports writing with bus encryption"); if(ftr.BEC) sb.AppendLine("\tDrive supports bus encryption"); if(ftr.BNG) { sb.AppendLine("\tDrive supports generating the binding nonce"); if(ftr.BindNonceBlocks > 0) sb.AppendFormat("\t{0} media blocks are required for the binding nonce", ftr.BindNonceBlocks). AppendLine(); } if(ftr.AGIDs > 0) sb.AppendFormat("\tDrive supports {0} AGIDs concurrently", ftr.AGIDs).AppendLine(); return sb.ToString(); } public static string Prettify_010E(Feature_010E? feature) { if(!feature.HasValue) return null; Feature_010E ftr = feature.Value; var sb = new StringBuilder(); sb.Append("Drive supports DVD-Download"); if(ftr.Current) sb.AppendLine(" (current)"); else sb.AppendLine(); if(ftr.MaxScrambleExtent > 0) sb.AppendFormat("\tMaximum {0} scranble extent information entries", ftr.MaxScrambleExtent). AppendLine(); return sb.ToString(); } public static string Prettify_0110(Feature_0110? feature) { if(!feature.HasValue) return null; Feature_0110 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine(ftr.Current ? "Drive and currently inserted media support VCPS" : "Drive supports VCPS"); return sb.ToString(); } public static string Prettify_0113(Feature_0113? feature) { if(!feature.HasValue) return null; Feature_0113 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine(ftr.Current ? "Drive and currently inserted media support SecurDisc" : "Drive supports SecurDisc"); return sb.ToString(); } public static string Prettify_0142(Feature_0142? feature) { if(!feature.HasValue) return null; Feature_0142 ftr = feature.Value; var sb = new StringBuilder(); sb.AppendLine("Drive supports the Trusted Computing Group Optical Security Subsystem Class"); if(ftr.Current) sb.AppendLine("\tCurrent media is initialized with TCG OSSC"); if(ftr.PSAU) sb.AppendLine("\tDrive supports PSA updates on write-once media"); if(ftr.LOSPB) sb.AppendLine("\tDrive supports linked OSPBs"); if(ftr.ME) sb.AppendLine("\tDrive will only record on the OSSC Disc Format"); if(ftr.Profiles == null) return sb.ToString(); for(int i = 0; i < ftr.Profiles.Length; i++) sb.AppendFormat("\tProfile {0}: {1}", i, ftr.Profiles[i]).AppendLine(); return sb.ToString(); } public static string Prettify_0000(byte[] feature) => Prettify_0000(Decode_0000(feature)); public static string Prettify_0001(byte[] feature) => Prettify_0001(Decode_0001(feature)); public static string Prettify_0002(byte[] feature) => Prettify_0002(Decode_0002(feature)); public static string Prettify_0003(byte[] feature) => Prettify_0003(Decode_0003(feature)); public static string Prettify_0004(byte[] feature) => Prettify_0004(Decode_0004(feature)); public static string Prettify_0010(byte[] feature) => Prettify_0010(Decode_0010(feature)); public static string Prettify_001D(byte[] feature) => Prettify_001D(Decode_001D(feature)); public static string Prettify_001E(byte[] feature) => Prettify_001E(Decode_001E(feature)); public static string Prettify_001F(byte[] feature) => Prettify_001F(Decode_001F(feature)); public static string Prettify_0020(byte[] feature) => Prettify_0020(Decode_0020(feature)); public static string Prettify_0021(byte[] feature) => Prettify_0021(Decode_0021(feature)); public static string Prettify_0022(byte[] feature) => Prettify_0022(Decode_0022(feature)); public static string Prettify_0023(byte[] feature) => Prettify_0023(Decode_0023(feature)); public static string Prettify_0024(byte[] feature) => Prettify_0024(Decode_0024(feature)); public static string Prettify_0025(byte[] feature) => Prettify_0025(Decode_0025(feature)); public static string Prettify_0026(byte[] feature) => Prettify_0026(Decode_0026(feature)); public static string Prettify_0027(byte[] feature) => Prettify_0027(Decode_0027(feature)); public static string Prettify_0028(byte[] feature) => Prettify_0028(Decode_0028(feature)); public static string Prettify_0029(byte[] feature) => Prettify_0029(Decode_0029(feature)); public static string Prettify_002A(byte[] feature) => Prettify_002A(Decode_002A(feature)); public static string Prettify_002B(byte[] feature) => Prettify_002B(Decode_002B(feature)); public static string Prettify_002C(byte[] feature) => Prettify_002C(Decode_002C(feature)); public static string Prettify_002D(byte[] feature) => Prettify_002D(Decode_002D(feature)); public static string Prettify_002E(byte[] feature) => Prettify_002E(Decode_002E(feature)); public static string Prettify_002F(byte[] feature) => Prettify_002F(Decode_002F(feature)); public static string Prettify_0030(byte[] feature) => Prettify_0030(Decode_0030(feature)); public static string Prettify_0031(byte[] feature) => Prettify_0031(Decode_0031(feature)); public static string Prettify_0032(byte[] feature) => Prettify_0032(Decode_0032(feature)); public static string Prettify_0033(byte[] feature) => Prettify_0033(Decode_0033(feature)); public static string Prettify_0035(byte[] feature) => Prettify_0035(Decode_0035(feature)); public static string Prettify_0037(byte[] feature) => Prettify_0037(Decode_0037(feature)); public static string Prettify_0038(byte[] feature) => Prettify_0038(Decode_0038(feature)); public static string Prettify_003A(byte[] feature) => Prettify_003A(Decode_003A(feature)); public static string Prettify_003B(byte[] feature) => Prettify_003B(Decode_003B(feature)); public static string Prettify_0040(byte[] feature) => Prettify_0040(Decode_0040(feature)); public static string Prettify_0041(byte[] feature) => Prettify_0041(Decode_0041(feature)); public static string Prettify_0042(byte[] feature) => Prettify_0042(Decode_0042(feature)); public static string Prettify_0050(byte[] feature) => Prettify_0050(Decode_0050(feature)); public static string Prettify_0051(byte[] feature) => Prettify_0051(Decode_0051(feature)); public static string Prettify_0080(byte[] feature) => Prettify_0080(Decode_0080(feature)); public static string Prettify_0100(byte[] feature) => Prettify_0100(Decode_0100(feature)); public static string Prettify_0101(byte[] feature) => Prettify_0101(Decode_0101(feature)); public static string Prettify_0102(byte[] feature) => Prettify_0102(Decode_0102(feature)); public static string Prettify_0103(byte[] feature) => Prettify_0103(Decode_0103(feature)); public static string Prettify_0104(byte[] feature) => Prettify_0104(Decode_0104(feature)); public static string Prettify_0105(byte[] feature) => Prettify_0105(Decode_0105(feature)); public static string Prettify_0106(byte[] feature) => Prettify_0106(Decode_0106(feature)); public static string Prettify_0107(byte[] feature) => Prettify_0107(Decode_0107(feature)); public static string Prettify_0108(byte[] feature) => Prettify_0108(Decode_0108(feature)); public static string Prettify_0109(byte[] feature) => Prettify_0109(Decode_0109(feature)); public static string Prettify_010A(byte[] feature) => Prettify_010A(Decode_010A(feature)); public static string Prettify_010B(byte[] feature) => Prettify_010B(Decode_010B(feature)); public static string Prettify_010C(byte[] feature) => Prettify_010C(Decode_010C(feature)); public static string Prettify_010D(byte[] feature) => Prettify_010D(Decode_010D(feature)); public static string Prettify_010E(byte[] feature) => Prettify_010E(Decode_010E(feature)); public static string Prettify_0110(byte[] feature) => Prettify_0110(Decode_0110(feature)); public static string Prettify_0113(byte[] feature) => Prettify_0113(Decode_0113(feature)); public static string Prettify_0142(byte[] feature) => Prettify_0142(Decode_0142(feature)); public static SeparatedFeatures Separate(byte[] response) { var dec = new SeparatedFeatures { DataLength = (uint)((response[0] << 24) + (response[1] << 16) + (response[2] << 8) + response[4]), CurrentProfile = (ushort)((response[6] << 8) + response[7]) }; uint offset = 8; List descLst = new List(); while(offset + 4 < response.Length) { var desc = new FeatureDescriptor { Code = (ushort)((response[offset + 0] << 8) + response[offset + 1]), Data = new byte[response[offset + 3] + 4] }; if(desc.Data.Length + offset > response.Length) desc.Data = new byte[response.Length - offset]; Array.Copy(response, offset, desc.Data, 0, desc.Data.Length); offset += (uint)desc.Data.Length; descLst.Add(desc); } dec.Descriptors = descLst.ToArray(); return dec; } [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct FeatureDescriptor { public ushort Code; public byte[] Data; } [SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"), SuppressMessage("ReSharper", "NotAccessedField.Global")] public struct SeparatedFeatures { public uint DataLength; public ushort CurrentProfile; public FeatureDescriptor[] Descriptors; } } }