Click here to Skip to main content
15,886,578 members
Articles / Programming Languages / C#

SCSI Library in C# - Burn CDs and DVDs, Access Hard Disks, etc.

Rate me:
Please Sign up or sign in to vote.
4.77/5 (48 votes)
19 Jun 2017Ms-PL6 min read 145.3K   8.1K   146  
Ever wonder how programs like Nero work? They make their own SCSI libraries... like this!
using System.Diagnostics;
using System.Runtime.InteropServices;
using System;
using Helper;
namespace SCSI.Multimedia
{
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class BlankCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte BLANKING_TYPE_MASK = 0x07;

		public BlankCommand() : base(OpCode.Blank) { }

		public BlankCommand(BlankingType blankingType, bool immediate, uint startAddressOrLogicalTrackNumber)
			: this() { this.BlankingType = blankingType; this.Immediate = immediate; this.StartAddressOrLogicalTrackNumber = startAddressOrLogicalTrackNumber; }
		
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public bool Immediate { get { return this.byte1[4]; } set { this.byte1[4] = value; } }
		public BlankingType BlankingType
		{
			get { return (BlankingType)Helper.Bits.ExtractValueMask((byte)this.byte1, 0, BLANKING_TYPE_MASK); }
			set { this.byte1 = Helper.Bits.PutValueMask((byte)this.byte1, (byte)value, 0, BLANKING_TYPE_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _StartAddressOrLogicalTrackNumber;
		public uint StartAddressOrLogicalTrackNumber { get { return Bits.FromBigEndian(this._StartAddressOrLogicalTrackNumber); } set { this._StartAddressOrLogicalTrackNumber = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte7;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte8;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte9;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte10;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class CloseSessionOrTrackCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte FUNCTION_MASK = 0x7;

		public CloseSessionOrTrackCommand() : base(OpCode.CloseSessionOrTrack) { }

		public CloseSessionOrTrackCommand(bool immediate, TrackSessionCloseFunction function, ushort trackNumber)
			: this()
		{
			this.Immediate = immediate;
			this.Function = function;
			this.TrackNumber = trackNumber;
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public bool Immediate { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte2;
		public TrackSessionCloseFunction Function
		{
			get { return (TrackSessionCloseFunction)Helper.Bits.ExtractValueMask((byte)this.byte2, 0, FUNCTION_MASK); }
			set { this.byte2 = Helper.Bits.PutValueMask((byte)this.byte2, (byte)value, 0, FUNCTION_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		private ushort _TrackNumber;
		public ushort TrackNumber { get { return Bits.FromBigEndian(this._TrackNumber); } set { this._TrackNumber = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte7;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte8;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class Erase10Command : SCSICommand
	{
		public Erase10Command() : base(OpCode.Erase10) { }

		public Erase10Command(bool eraseAll, bool immediate, uint lba, ushort numBlocks)
			: this()
		{
			this.EraseAll = eraseAll;
			this.Immediate = immediate;
			this.LogicalBlockAddress = lba;
			this.NumberOfBlocks = numBlocks;
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public bool EraseAll { get { return this.byte1[2]; } set { this.byte1[2] = value; } }
		public bool Immediate { get { return this.byte1[1]; } set { this.byte1[1] = value; } }
		[Obsolete("Must be zero.", true)]
		public bool RelativeAddress { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _LogicalBlockAddress;
		public uint LogicalBlockAddress { get { return Bits.FromBigEndian(this._LogicalBlockAddress); } set { this._LogicalBlockAddress = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _NumberOfBlocks;
		public ushort NumberOfBlocks { get { return Bits.FromBigEndian(this._NumberOfBlocks); } set { this._NumberOfBlocks = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class FormatUnitCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte FORMAT_CODE_MASK = 0x7;

		public FormatUnitCommand() : base(OpCode.FormatUnit) { this.FormatData = true; this.FormatCode = FormatCode.Other; }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		/// <summary>Should be one.</summary>
		public bool FormatData { get { return this.byte1[4]; } set { this.byte1[4] = value; } }
		/// <summary>Should be zero on most discs except DVD-RAM.</summary>
		public bool CompleteList { get { return this.byte1[3]; } set { this.byte1[3] = value; } }
		public FormatCode FormatCode
		{
			get { return (FormatCode)Helper.Bits.ExtractValueMask((byte)this.byte1, 0, FORMAT_CODE_MASK); }
			set { this.byte1 = Helper.Bits.PutValueMask((byte)this.byte1, (byte)value, 0, FORMAT_CODE_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte2;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _InterleaveValue;
		[Obsolete("Should be zero.", true)]
		public ushort InterleaveValue { get { return Bits.FromBigEndian(this._InterleaveValue); } set { this._InterleaveValue = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class GetConfigurationCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte REQUEST_TYPE_MASK = 0x03;

		public GetConfigurationCommand() : base(OpCode.GetConfiguration) { }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public RequestType RequestType
		{
			get { return (RequestType)Helper.Bits.ExtractValueMask((byte)this.byte1, 0, REQUEST_TYPE_MASK); }
			set { this.byte1 = Helper.Bits.PutValueMask((byte)this.byte1, (byte)value, 0, REQUEST_TYPE_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _StartingFeatureNumber;
		public ushort StartingFeatureNumber { get { return Bits.FromBigEndian(this._StartingFeatureNumber); } set { this._StartingFeatureNumber = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte4;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte5;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _AllocationLength;
		internal ushort AllocationLength { get { return Bits.FromBigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class GetPerformanceCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte DATA_TYPE_MASK = 0x1F;

		public GetPerformanceCommand() : base(OpCode.GetPerformance) { }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public PerformanceDataType DataType
		{
			get { return new PerformanceDataType(Helper.Bits.ExtractValueMask((byte)this.byte1, 0, DATA_TYPE_MASK)); }
			set { this.byte1 = Helper.Bits.PutValueMask((byte)this.byte1, value.Value, 0, DATA_TYPE_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _StartingLBA;
		public uint StartingLBA { get { return Bits.FromBigEndian(this._StartingLBA); } set { this._StartingLBA = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte7;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _MaximumNumberOfDescriptors;
		public ushort MaximumNumberOfDescriptors { get { return Bits.FromBigEndian(this._MaximumNumberOfDescriptors); } set { this._MaximumNumberOfDescriptors = Bits.ToBigEndian(value); } }
		public PerformanceType Type;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class GetEventStatusNotificationCommand : SCSICommand
	{
		public GetEventStatusNotificationCommand() : base(OpCode.GetEventStatusNotification) { this.Polled = true; }

		public GetEventStatusNotificationCommand(NotificationClassFlags notificationClassRequest)
			: this() { this.NotificationClassRequest = notificationClassRequest; }


		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public bool Polled { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte2;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private NotificationClassFlags _NotificationClassRequest;
		public NotificationClassFlags NotificationClassRequest { get { return this._NotificationClassRequest; } set { this._NotificationClassRequest = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte5;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _AllocationLength;
		internal ushort AllocationLength { get { return Bits.FromBigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }

	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class LoadUnloadMediumCommand : SCSICommand
	{
		public LoadUnloadMediumCommand() : base(OpCode.LoadUnloadMedium) { }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public bool Immediate { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte2;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte4;
		public bool LoUnlo { get { return this.byte4[1]; } set { this.byte4[1] = value; } }
		public bool Start { get { return this.byte4[0]; } set { this.byte4[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte5;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte7;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte _Slot;
		public byte Slot { get { return this._Slot; } set { this._Slot = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte9;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte10;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class PreventAllowMediumRemovalCommand : SCSICommand
	{
		public PreventAllowMediumRemovalCommand() : base(OpCode.PreventAllowMediumRemoval) { }
		public PreventAllowMediumRemovalCommand(bool prevent) : this() { this.Prevent = prevent; }
		public PreventAllowMediumRemovalCommand(bool prevent, bool persistent) : this(prevent) { this.Persistent = persistent; }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte2;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte4;
		public bool Persistent { get { return this.byte4[1]; } set { this.byte4[1] = value; } }
		public bool Prevent { get { return this.byte4[0]; } set { this.byte4[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class ReadBufferCapacityCommand : SCSICommand
	{
		public ReadBufferCapacityCommand() : base(OpCode.ReadBufferCapacity) { }
		public ReadBufferCapacityCommand(bool returnInBlocksInsteadOfBytes) : this() { this.Block = returnInBlocksInsteadOfBytes; }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public bool Block { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte2;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte4;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte5;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _AllocationLength;
		internal ushort AllocationLength { get { return Bits.FromBigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class ReadCDCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte EXPECTED_SECTOR_TYPE_MASK = 0x1C;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte C2_ERROR_CODE_MASK = 0x06;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte HEADER_CODES_MASK = 0x60;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte SUB_CHANNEL_SELECTION_BITS_MASK = 0x07;

		public ReadCDCommand() : base(OpCode.ReadCD) { }

		private BitVector8 byte1;
		public SectorType ExpectedSectorType
		{
			get { return (SectorType)Helper.Bits.ExtractValueMask((byte)this.byte1, 2, EXPECTED_SECTOR_TYPE_MASK); }
			set { this.byte1 = Helper.Bits.PutValueMask((byte)this.byte1, (byte)value, 2, EXPECTED_SECTOR_TYPE_MASK); }
		}
		public bool DigitalAudioPlay { get { return this.byte1[1]; } set { this.byte1[1] = value; } }
		private uint _StartingLBA;
		public uint StartingLBA { get { return Bits.FromBigEndian(this._StartingLBA); } set { this._StartingLBA = Bits.ToBigEndian(value); } }
		private byte _byte6; //msb
		private byte _byte7;
		private byte _byte8; //lsb
		internal uint TransferLength
		{
			get { unchecked { return (uint)this._byte8 | ((uint)this._byte7 << 8) | ((uint)this._byte6 << 16); } }
			set { unchecked { this._byte8 = (byte)(value >> 0); this._byte7 = (byte)(value >> 8); this._byte6 = (byte)(value >> 16); } }
		}
		private BitVector8 byte9;
		public C2ErrorCode C2ErrorInformation
		{
			get { return (C2ErrorCode)Helper.Bits.ExtractValueMask((byte)this.byte9, 1, C2_ERROR_CODE_MASK); }
			set { this.byte9 = Helper.Bits.PutValueMask((byte)this.byte9, (byte)value, 1, C2_ERROR_CODE_MASK); }
		}
		public HeaderCode HeaderCode
		{
			get { return (HeaderCode)Helper.Bits.ExtractValueMask((byte)this.byte9, 5, HEADER_CODES_MASK); }
			set { this.byte9 = Helper.Bits.PutValueMask((byte)this.byte9, (byte)value, 5, HEADER_CODES_MASK); }
		}
		public bool EDC_ECC { get { return this.byte9[3]; } set { this.byte9[3] = value; } }
		public bool UserData { get { return this.byte9[4]; } set { this.byte9[4] = value; } }
		private BitVector8 byte10;
		public SubChannelSelection SubChannelSelectionBits
		{
			get { return (SubChannelSelection)Helper.Bits.ExtractValueMask((byte)this.byte10, 0, SUB_CHANNEL_SELECTION_BITS_MASK); }
			set { this.byte10 = Helper.Bits.PutValueMask((byte)this.byte10, (byte)value, 0, SUB_CHANNEL_SELECTION_BITS_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class ReadDiscInformationCommand : SCSICommand
	{
		public ReadDiscInformationCommand() : base(OpCode.ReadDiscInformation) { }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte2;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte4;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte5;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _AllocationLength;
		internal ushort AllocationLength { get { return Bits.FromBigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class ReadFormatCapacitiesCommand : SCSICommand
	{
		public ReadFormatCapacitiesCommand() : base(OpCode.ReadFormatCapacities) { }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte2;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte4;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte5;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _AllocationLength;
		internal ushort AllocationLength { get { return Bits.FromBigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class ReadTrackInformationCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte ADDRESS_OR_NUMBER_TYPE_MASK = 0x3;

		public ReadTrackInformationCommand() : base(OpCode.ReadTrackInformation) { }

		public ReadTrackInformationCommand(bool findFirstOpen, TrackIdentificationType addressOrNumberType, uint trackNumberOrSessionNumberOrLBA)
			: this()
		{
			this.Open = findFirstOpen;
			this.AddressOrNumberType = addressOrNumberType;
			this.TrackNumberOrSessionNumberOrLBA = trackNumberOrSessionNumberOrLBA;
		}

		private BitVector8 byte1;
		/// <summary>If <c>false</c>, finds the logical track that contains the given LBA, logical track number, or logical session number. If <c>true</c>, finds the first open logical track with a logical track number that is GREATER than the given LBA, logical track number, or logical session number.</summary>
		public bool Open { get { return this.byte1[2]; } set { this.byte1[2] = value; } }
		public TrackIdentificationType AddressOrNumberType
		{
			get { return (TrackIdentificationType)Helper.Bits.ExtractValueMask((byte)this.byte1, 0, ADDRESS_OR_NUMBER_TYPE_MASK); }
			set { this.byte1 = Helper.Bits.PutValueMask((byte)this.byte1, (byte)value, 0, ADDRESS_OR_NUMBER_TYPE_MASK); }
		}
		private uint _TrackNumberOrSessionNumberOrLBA;
		public uint TrackNumberOrSessionNumberOrLBA { get { return Bits.FromBigEndian(this._TrackNumberOrSessionNumberOrLBA); } set { this._TrackNumberOrSessionNumberOrLBA = Bits.ToBigEndian(value); } }
		private byte byte6;
		private ushort _AllocationLength;
		internal ushort AllocationLength { get { return Bits.FromBigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class ReportKeyCommand : SCSICommand
	{
		private const byte KEY_FORMAT_MASK = 0x3F;
		private const byte AGID_MASK = 0xC0;
		public ReportKeyCommand() : base(OpCode.ReportKey) { }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _ReservedOrLBAOrStartingOffset;
		public uint ReservedOrLBAOrStartingOffset { get { return Bits.FromBigEndian(this._ReservedOrLBAOrStartingOffset); } set { this._ReservedOrLBAOrStartingOffset = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte _ReservedOrBlockCountOrVCPSFunction;
		public byte ReservedOrBlockCountOrVCPSFunction { get { return this._ReservedOrBlockCountOrVCPSFunction; } set { this._ReservedOrBlockCountOrVCPSFunction = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private KeyClass _KeyClass;
		public KeyClass KeyClass { get { return this._KeyClass; } set { this._KeyClass = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _AllocationLength;
		public ushort AllocationLength { get { return Bits.FromBigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte10;
		public KeyFormat KeyFormat
		{
			get { return (KeyFormat)Helper.Bits.ExtractValueMask((byte)this.byte10, 0, KEY_FORMAT_MASK); }
			set { this.byte10 = Helper.Bits.PutValueMask((byte)this.byte10, (byte)value, 0, KEY_FORMAT_MASK); }
		}
		public byte AGID
		{
			get { return Helper.Bits.ExtractValueMask((byte)this.byte10, 6, AGID_MASK); }
			set { this.byte10 = Helper.Bits.PutValueMask((byte)this.byte10, (byte)value, 6, AGID_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class ReserveTrackCommand : SCSICommand
	{
		public ReserveTrackCommand() : base(OpCode.ReserveTrack) { }

		public ReserveTrackCommand(bool isLBA, LogicalTrackReservationParameter reservation)
			: this()
		{
			this.ARSV = isLBA;
			this.LogicalTrackReservationParameter = reservation;
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		/// <summary>Should be zero for non-HD-DVDs.</summary>
		public bool RMZ { get { return this.byte1[1]; } set { this.byte1[1] = value; } }
		/// <summary>When set to <c>false</c>, indicates that the <see cref="Multimedia.LogicalTrackReservationParameter.ReservationSize"/> property is set. When set to <c>true</c>, means that the <see cref="Multimedia.LogicalTrackReservationParameter.ReservationLBA"/> property is set.</summary>
		public bool ARSV { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		public LogicalTrackReservationParameter LogicalTrackReservationParameter;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class SendOPCInformationCommand : SCSICommand
	{
		public SendOPCInformationCommand() : base(OpCode.SendOPCInformation) { }
		public SendOPCInformationCommand(bool exclude0, bool exclude1)
			: this()
		{
			this.Exclude0 = exclude0;
			this.Exclude1 = exclude1;
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		internal bool DoOPC { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte2;
		public bool Exclude0 { get { return this.byte2[0]; } set { this.byte2[0] = value; } }
		public bool Exclude1 { get { return this.byte2[1]; } set { this.byte2[1] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte4;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte5;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _ParameterListLength;
		internal ushort ParameterListLength { get { return Bits.FromBigEndian(this._ParameterListLength); } set { this._ParameterListLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class SetCDSpeedCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte ROTATION_CONTROL_MASK = 0x03;

		public SetCDSpeedCommand() : base(OpCode.SetCDSpeed) { }
		public SetCDSpeedCommand(ushort readSpeed, ushort writeSpeed, RotationControl rotationControl)
			: this()
		{
			this.LogicalUnitReadSpeed = readSpeed;
			this.LogicalUnitWriteSpeed = writeSpeed;
			this.RotationControl = rotationControl;
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public RotationControl RotationControl
		{
			get { return (RotationControl)Helper.Bits.ExtractValueMask((byte)this.byte1, 0, ROTATION_CONTROL_MASK); }
			set { this.byte1 = Helper.Bits.PutValueMask((byte)this.byte1, (byte)value, 0, ROTATION_CONTROL_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _LogicalUnitReadSpeed;
		public ushort LogicalUnitReadSpeed { get { return Bits.FromBigEndian(this._LogicalUnitReadSpeed); } set { this._LogicalUnitReadSpeed = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _LogicalUnitWriteSpeed;
		public ushort LogicalUnitWriteSpeed { get { return Bits.FromBigEndian(this._LogicalUnitWriteSpeed); } set { this._LogicalUnitWriteSpeed = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte7;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte8;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte9;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte10;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class SetReadAheadCommand : SCSICommand
	{
		public SetReadAheadCommand() : base(OpCode.SetReadAhead) { }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _TriggerLBA;
		public uint TriggerLBA { get { return Bits.FromBigEndian(this._TriggerLBA); } set { this._TriggerLBA = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _ReadAheadLBA;
		public uint ReadAheadLBA { get { return Bits.FromBigEndian(this._ReadAheadLBA); } set { this._ReadAheadLBA = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte10;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class SetStreamingCommand : SCSICommand
	{
		public SetStreamingCommand() : base(OpCode.SetStreaming) { }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte2;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte3;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte4;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte5;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte7;
		internal StreamingDataType Type;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _ParameterListLength;
		internal ushort ParameterListLength { get { return Bits.FromBigEndian(this._ParameterListLength); } set { this._ParameterListLength = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class StartStopUnitCommand : SCSICommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte FORMAT_LAYER_NUMBER_MASK = 0x03;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte POWER_CONDITIONS_MASK = 0xF0;

		public StartStopUnitCommand() : base(OpCode.StartStopUnit) { }
		public StartStopUnitCommand(bool loadEject, bool start) : this(loadEject, start, false) { }
		public StartStopUnitCommand(bool loadEject, bool start, bool immediate) : this(loadEject, start, 0, default(PowerConditions), false) { }
		public StartStopUnitCommand(PowerConditions powerCondition, byte? formatLayerNumber) : this(powerCondition, formatLayerNumber, false) { }
		public StartStopUnitCommand(PowerConditions powerCondition, byte? formatLayerNumber, bool immediate) : this(false, false, formatLayerNumber, powerCondition, immediate) { }
		private StartStopUnitCommand(bool loadEject, bool start, byte? formatLayerNumber, PowerConditions powerConditions, bool immediate)
			: this()
		{
			this.LoEj = loadEject;
			this.Start = start;
			this.FormatLayerNumber = formatLayerNumber;
			this.PowerConditions = powerConditions;
			this.Immediate = immediate;
		}

		private BitVector8 byte1;
		/// <summary>If <see cref="Immediate"/> is set to <c>false</c>, status shall be returned only after the operation is completed. If <see cref="Immediate"/> is set to <c>true</c>, status shall be returned as soon as the CDB has been validated.</summary>
		public bool Immediate { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		private byte byte2;
		private byte byte3;
		/// <summary>The Format-layer Number field specifies the Format-layer the Host has requested to be online. The number set in this field shall be less than the Number of recognized Format-layers field value reported by the Hybrid disc structure of READ DISC STRUCTURE command. If the value set in the Format-layer Number field is out of range, the Drive shall terminate the command with CHECK CONDITION status and set sense bytes SK/ASC/ASCQ to ILLEGAL REQUEST/INVALID FIELD IN CDB.</summary>
		public byte? FormatLayerNumber
		{
			get { return this.byte4[2] ? (byte?)Helper.Bits.ExtractValueMask((byte)this.byte3, 0, FORMAT_LAYER_NUMBER_MASK) : null; }
			set
			{
				this.byte4[2] = value != null;
				//Either reset to 0, or set to value
				this.byte3 = Helper.Bits.PutValueMask((byte)this.byte3, (byte)value.GetValueOrDefault(), 0, FORMAT_LAYER_NUMBER_MASK);
			}
		}
		private BitVector8 byte4;
		public PowerConditions PowerConditions
		{
			get { return (PowerConditions)Helper.Bits.ExtractValueMask((byte)this.byte4, 4, POWER_CONDITIONS_MASK); }
			set { this.byte4 = Helper.Bits.PutValueMask((byte)this.byte4, (byte)value, 4, POWER_CONDITIONS_MASK); }
		}
		public bool LoEj { get { return this.byte4[1]; } set { this.byte4[1] = value; } }
		public bool Start { get { return this.byte4[0]; } set { this.byte4[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;

		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class Verify10Command : SCSICommand
	{
		public Verify10Command() : base(OpCode.Verify10) { }
		public Verify10Command(uint lba, ushort numberOfBlocks)
			: this()
		{
			this.LBA = lba;
			this.NumberOfBlocks = numberOfBlocks;
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		/// <summary>Should be zero.</summary>
		public bool DisablePageOut { get { return this.byte1[4]; } set { this.byte1[4] = value; } }
		/// <summary>Should be zero.</summary>
		public bool ByteCheck { get { return this.byte1[1]; } set { this.byte1[1] = value; } }
		[Obsolete("Should be zero.", true)]
		public bool RelativeAddress { get { return this.byte1[0]; } set { this.byte1[0] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _LBA;
		public uint LBA { get { return Bits.FromBigEndian(this._LBA); } set { this._LBA = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte6;
		public bool Group3Timeout { get { return this.byte6[7]; } set { this.byte6[7] = value; } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _NumberOfBlocks;
		public ushort NumberOfBlocks { get { return Bits.FromBigEndian(this._NumberOfBlocks); } set { this._NumberOfBlocks = Bits.ToBigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Control _Control;
		public override Control Control { get { return this._Control; } set { this._Control = value; } }
	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions