Click here to Skip to main content
15,892,927 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 146K   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;
using System.ComponentModel;
namespace Scsi.Multimedia
{
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public class BlankCommand : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte BLANKING_TYPE_MASK = 0x07;

		public BlankCommand() : base(ScsiCommandCode.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)Bits.GetValueMask((byte)this.byte1, 0, BLANKING_TYPE_MASK); }
			set { this.byte1 = (BitVector8)Bits.PutValueMask((byte)this.byte1, (byte)value, 0, BLANKING_TYPE_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _StartAddressOrLogicalTrackNumber;
		public uint StartAddressOrLogicalTrackNumber { get { return Bits.BigEndian(this._StartAddressOrLogicalTrackNumber); } set { this._StartAddressOrLogicalTrackNumber = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte FUNCTION_MASK = 0x7;

		public CloseSessionOrTrackCommand() : base(ScsiCommandCode.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)Bits.GetValueMask((byte)this.byte2, 0, FUNCTION_MASK); }
			set { this.byte2 = (BitVector8)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.BigEndian(this._TrackNumber); } set { this._TrackNumber = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		public Erase10Command() : base(ScsiCommandCode.Erase10) { }

		public Erase10Command(bool eraseAll, bool immediate, uint logicalBlockAddress, ushort numBlocks)
			: this()
		{
			this.EraseAll = eraseAll;
			this.Immediate = immediate;
			this.LogicalBlockAddress = logicalBlockAddress;
			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.BigEndian(this._LogicalBlockAddress); } set { this._LogicalBlockAddress = Bits.BigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte6;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _NumberOfBlocks;
		public ushort NumberOfBlocks { get { return Bits.BigEndian(this._NumberOfBlocks); } set { this._NumberOfBlocks = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte FORMAT_CODE_MASK = 0x7;

		public FormatUnitCommand() : base(ScsiCommandCode.Format) { 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)Bits.GetValueMask((byte)this.byte1, 0, FORMAT_CODE_MASK); }
			set { this.byte1 = (BitVector8)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.BigEndian(this._InterleaveValue); } set { this._InterleaveValue = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte REQUEST_TYPE_MASK = 0x03;

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

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public RequestType RequestType { get { return (RequestType)Bits.GetValueMask((byte)this.byte1, 0, REQUEST_TYPE_MASK); } set { this.byte1 = (BitVector8)Bits.PutValueMask((byte)this.byte1, (byte)value, 0, REQUEST_TYPE_MASK); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _StartingFeatureNumber;
		public ushort StartingFeatureNumber { get { return Bits.BigEndian(this._StartingFeatureNumber); } set { this._StartingFeatureNumber = Bits.BigEndian(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;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public ushort AllocationLength { get { return Bits.BigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte DATA_TYPE_MASK = 0x1F;

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

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public PerformanceDataType DataType
		{
			get { return new PerformanceDataType(Bits.GetValueMask((byte)this.byte1, 0, DATA_TYPE_MASK)); }
			set { this.byte1 = (BitVector8)Bits.PutValueMask((byte)this.byte1, value.Value, 0, DATA_TYPE_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _StartingLogicalBlockAddress;
		public uint StartingLogicalBlockAddress { get { return Bits.BigEndian(this._StartingLogicalBlockAddress); } set { this._StartingLogicalBlockAddress = Bits.BigEndian(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.BigEndian(this._MaximumNumberOfDescriptors); } set { this._MaximumNumberOfDescriptors = Bits.BigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private PerformanceType _PerformanceType;
		public PerformanceType PerformanceType { get { return Bits.BigEndian(this._PerformanceType); } set { this._PerformanceType = Bits.BigEndian(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 GetEventStatusNotificationCommand : FixedLengthScsiCommand
	{
		public GetEventStatusNotificationCommand() : base(ScsiCommandCode.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;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public ushort AllocationLength { get { return Bits.BigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		public LoadUnloadMediumCommand() : base(ScsiCommandCode.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 LoadUnload { 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 : FixedLengthScsiCommand
	{
		public PreventAllowMediumRemovalCommand() : base(ScsiCommandCode.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 : FixedLengthScsiCommand
	{
		public ReadBufferCapacityCommand() : base(ScsiCommandCode.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;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public ushort AllocationLength { get { return Bits.BigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		[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(ScsiCommandCode.ReadCD) { }

		private BitVector8 byte1;
		public SectorType ExpectedSectorType
		{
			get { return (SectorType)Bits.GetValueMask((byte)this.byte1, 2, EXPECTED_SECTOR_TYPE_MASK); }
			set { this.byte1 = (BitVector8)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 _StartingLogicalBlockAddress;
		public uint StartingLogicalBlockAddress { get { return Bits.BigEndian(this._StartingLogicalBlockAddress); } set { this._StartingLogicalBlockAddress = Bits.BigEndian(value); } }
		private byte _byte6; //msb
		private byte _byte7;
		private byte _byte8; //lsb
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public 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)Bits.GetValueMask((byte)this.byte9, 1, C2_ERROR_CODE_MASK); }
			set { this.byte9 = (BitVector8)Bits.PutValueMask((byte)this.byte9, (byte)value, 1, C2_ERROR_CODE_MASK); }
		}
		public HeaderCodes HeaderCode
		{
			get { return (HeaderCodes)Bits.GetValueMask((byte)this.byte9, 5, HEADER_CODES_MASK); }
			set { this.byte9 = (BitVector8)Bits.PutValueMask((byte)this.byte9, (byte)value, 5, HEADER_CODES_MASK); }
		}
		public bool ErrorDetectionCodeOrErrorCorrectionCode { 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)Bits.GetValueMask((byte)this.byte10, 0, SUB_CHANNEL_SELECTION_BITS_MASK); }
			set { this.byte10 = (BitVector8)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 : FixedLengthScsiCommand
	{
		public ReadDiscInformationCommand() : base(ScsiCommandCode.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;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public ushort AllocationLength { get { return Bits.BigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.BigEndian(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 ReadDiscStructureCommand : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte AGID_MASK = 0xC0;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte MEDIA_TYPE_MASK = 0x0F;

		public ReadDiscStructureCommand() : base(ScsiCommandCode.ReadDiscStructure) { }

		public ReadDiscStructureCommand(GenericDiscStructureFormatCode formatCode, uint address, byte layerNumber, byte authenticationGrantId)
			: this(default(ReadDiscStructureMediaType), (byte)formatCode, address, layerNumber, authenticationGrantId) { }

		public ReadDiscStructureCommand(BDStructureFormatCode formatCode, uint address, byte layerNumber, byte authenticationGrantId)
			: this(ReadDiscStructureMediaType.BD, (byte)formatCode, address, layerNumber, authenticationGrantId) { }

		public ReadDiscStructureCommand(DvdStructureFormatCode formatCode, uint address, byte layerNumber, byte authenticationGrantId)
			: this(ReadDiscStructureMediaType.DvdAndHDDvd, (byte)formatCode, address, layerNumber, authenticationGrantId) { }

		public ReadDiscStructureCommand(ReadDiscStructureMediaType subCommand, byte formatCode, uint address, byte layerNumber, byte authenticationGrantId)
			: this() { this.MediaType = subCommand; this.Format = formatCode; this.Address = address; this.LayerNumber = layerNumber; this.AuthenticationGrantId = authenticationGrantId; }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		public ReadDiscStructureMediaType MediaType { get { return (ReadDiscStructureMediaType)Bits.GetValueMask(this.byte1, 0, MEDIA_TYPE_MASK); } set { this.byte1 = Bits.PutValueMask(this.byte1, (byte)value, 0, MEDIA_TYPE_MASK); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _Address;
		public uint Address { get { return Bits.BigEndian(this._Address); } set { this._Address = Bits.BigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte _LayerNumber;
		public byte LayerNumber { get { return Bits.BigEndian(this._LayerNumber); } set { this._LayerNumber = Bits.BigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte _Format;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public byte Format { get { return Bits.BigEndian(this._Format); } set { this._Format = Bits.BigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _AllocationLength;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public ushort AllocationLength { get { return Bits.BigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.BigEndian(value); } }
		[DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
		private byte _byte10;
		public byte AuthenticationGrantId { get { return Bits.GetValueMask(this._byte10, 6, AGID_MASK); } set { this._byte10 = Bits.PutValueMask(this._byte10, 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 ReadFormatCapacitiesCommand : FixedLengthScsiCommand
	{
		public ReadFormatCapacitiesCommand() : base(ScsiCommandCode.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;
		public ushort AllocationLength { get { return Bits.BigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte ADDRESS_OR_NUMBER_TYPE_MASK = 0x3;

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

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

		private BitVector8 byte1;
		/// <summary>If <c>false</c>, finds the logical track that contains the given LogicalBlockAddress, 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 LogicalBlockAddress, logical track number, or logical session number.</summary>
		[Description("If false, finds the logical track that contains the given LogicalBlockAddress, logical track number, or logical session number. If true, finds the first open logical track with a logical track number that is GREATER than the given LogicalBlockAddress, logical track number, or logical session number.")]
		public bool Open { get { return this.byte1[2]; } set { this.byte1[2] = value; } }
		public TrackIdentificationType AddressOrNumberType
		{
			get { return (TrackIdentificationType)Bits.GetValueMask((byte)this.byte1, 0, ADDRESS_OR_NUMBER_TYPE_MASK); }
			set { this.byte1 = (BitVector8)Bits.PutValueMask((byte)this.byte1, (byte)value, 0, ADDRESS_OR_NUMBER_TYPE_MASK); }
		}
		private uint _TrackNumberOrSessionNumberOrLogicalBlockAddress;
		public uint TrackNumberOrSessionNumberOrLogicalBlockAddress { get { return Bits.BigEndian(this._TrackNumberOrSessionNumberOrLogicalBlockAddress); } set { this._TrackNumberOrSessionNumberOrLogicalBlockAddress = Bits.BigEndian(value); } }
		private byte byte6;
		private ushort _AllocationLength;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public ushort AllocationLength { get { return Bits.BigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		private const byte KEY_FORMAT_MASK = 0x3F;
		private const byte AuthenticationGrantId_MASK = 0xC0;
		public ReportKeyCommand() : base(ScsiCommandCode.ReportKey) { }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _ReservedOrLogicalBlockAddressOrStartingOffset;
		public uint ReservedOrLogicalBlockAddressOrStartingOffset { get { return Bits.BigEndian(this._ReservedOrLogicalBlockAddressOrStartingOffset); } set { this._ReservedOrLogicalBlockAddressOrStartingOffset = Bits.BigEndian(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.BigEndian(this._AllocationLength); } set { this._AllocationLength = Bits.BigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte10;
		public KeyFormat KeyFormat
		{
			get { return (KeyFormat)Bits.GetValueMask((byte)this.byte10, 0, KEY_FORMAT_MASK); }
			set { this.byte10 = (BitVector8)Bits.PutValueMask((byte)this.byte10, (byte)value, 0, KEY_FORMAT_MASK); }
		}
		public byte AuthenticationGrantId
		{
			get { return Bits.GetValueMask((byte)this.byte10, 6, AuthenticationGrantId_MASK); }
			set { this.byte10 = (BitVector8)Bits.PutValueMask((byte)this.byte10, (byte)value, 6, AuthenticationGrantId_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 : FixedLengthScsiCommand
	{
		public ReserveTrackCommand() : base(ScsiCommandCode.ReserveTrack) { }

		public ReserveTrackCommand(bool isLogicalBlockAddressInsteadOfReservationSize, LogicalTrackReservationParameter reservation)
			: this()
		{
			this.ARSV = isLogicalBlockAddressInsteadOfReservationSize;
			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.ReservationLogicalBlockAddress"/> property is set.</summary>
		[Description("When set to false, indicates that the Multimedia.LogicalTrackReservationParameter.ReservationSize property is set. When set to true, means that the Multimedia.LogicalTrackReservationParameter.ReservationLogicalBlockAddress property is set.")]
		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 SendOptimumPowerCalibrationInformationCommand : FixedLengthScsiCommand
	{
		public SendOptimumPowerCalibrationInformationCommand() : base(ScsiCommandCode.SendOpcInformation) { }
		public SendOptimumPowerCalibrationInformationCommand(bool exclude0, bool exclude1)
			: this()
		{
			this.Exclude0 = exclude0;
			this.Exclude1 = exclude1;
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private BitVector8 byte1;
		public bool DoOptimumPowerCalibration { 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;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public ushort ParameterListLength { get { return Bits.BigEndian(this._ParameterListLength); } set { this._ParameterListLength = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte ROTATION_CONTROL_MASK = 0x03;

		public SetCDSpeedCommand() : base(ScsiCommandCode.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)Bits.GetValueMask((byte)this.byte1, 0, ROTATION_CONTROL_MASK); }
			set { this.byte1 = (BitVector8)Bits.PutValueMask((byte)this.byte1, (byte)value, 0, ROTATION_CONTROL_MASK); }
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _LogicalUnitReadSpeed;
		/// <summary>The read speed, in KB (1000 bytes) per second. (This is NOT KiB/s, or 1024 B/s.)</summary>
		[Description("The read speed, in KB (1000 bytes) per second. (This is NOT KiB/s, or 1024 B/s.)")]
		public ushort LogicalUnitReadSpeed { get { return Bits.BigEndian(this._LogicalUnitReadSpeed); } set { this._LogicalUnitReadSpeed = Bits.BigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _LogicalUnitWriteSpeed;
		/// <summary>The write speed, in KB (1000 bytes) per second. (This is NOT KiB/s, or 1024 B/s.)</summary>
		[Description("The write speed, in KB (1000 bytes) per second. (This is NOT KiB/s, or 1024 B/s.)")]
		public ushort LogicalUnitWriteSpeed { get { return Bits.BigEndian(this._LogicalUnitWriteSpeed); } set { this._LogicalUnitWriteSpeed = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		public SetReadAheadCommand() : base(ScsiCommandCode.SetReadAhead) { }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private byte byte1;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _TriggerLogicalBlockAddress;
		public uint TriggerLogicalBlockAddress { get { return Bits.BigEndian(this._TriggerLogicalBlockAddress); } set { this._TriggerLogicalBlockAddress = Bits.BigEndian(value); } }
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private uint _ReadAheadLogicalBlockAddress;
		public uint ReadAheadLogicalBlockAddress { get { return Bits.BigEndian(this._ReadAheadLogicalBlockAddress); } set { this._ReadAheadLogicalBlockAddress = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		public SetStreamingCommand() : base(ScsiCommandCode.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;
		public StreamingDataType Type;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ushort _ParameterListLength;
		/// <summary>Do not use this value unless you are responsible for calling the <see cref="IScsiPassThrough.ExecuteCommand"/> method directly.</summary>
		public ushort ParameterListLength { get { return Bits.BigEndian(this._ParameterListLength); } set { this._ParameterListLength = Bits.BigEndian(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 : FixedLengthScsiCommand
	{
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte FORMAT_LAYER_NUMBER_MASK = 0x03;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private const byte POWER_CONDITIONS_MASK = 0xF0;

		public StartStopUnitCommand() : base(ScsiCommandCode.StartStopUnit) { }
		public StartStopUnitCommand(bool loadEject, bool start) : this(loadEject, start, false) { }
		public StartStopUnitCommand(bool loadEject, bool start, bool immediate) : this(loadEject, start, 0, default(PowerCondition), immediate) { }
		public StartStopUnitCommand(PowerCondition powerCondition, byte? formatLayerNumber) : this(powerCondition, formatLayerNumber, false) { }
		public StartStopUnitCommand(PowerCondition powerCondition, byte? formatLayerNumber, bool immediate) : this(false, false, formatLayerNumber, powerCondition, immediate) { }
		private StartStopUnitCommand(bool loadEject, bool start, byte? formatLayerNumber, PowerCondition powerConditions, bool immediate)
			: this()
		{
			this.LoadEject = 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 is returned only after the operation is completed. If <see cref="Immediate"/> is set to <c>true</c>, status is 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>This field specifies the Format-layer the host has requested to be online. The number set in this field is 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 this field is out of range, the Drive terminates 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?)Bits.GetValueMask((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 = Bits.PutValueMask(this.byte3, (byte)value.GetValueOrDefault(), 0, FORMAT_LAYER_NUMBER_MASK);
			}
		}
		private BitVector8 byte4;
		public PowerCondition PowerConditions
		{
			get { return (PowerCondition)Bits.GetValueMask((byte)this.byte4, 4, POWER_CONDITIONS_MASK); }
			set { this.byte4 = (BitVector8)Bits.PutValueMask((byte)this.byte4, (byte)value, 4, POWER_CONDITIONS_MASK); }
		}
		public bool LoadEject { 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 : FixedLengthScsiCommand
	{
		public Verify10Command() : base(ScsiCommandCode.Verify10) { }
		public Verify10Command(uint logicalBlockAddress, ushort numberOfBlocks)
			: this()
		{
			this.LogicalBlockAddress = logicalBlockAddress;
			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 _LogicalBlockAddress;
		public uint LogicalBlockAddress { get { return Bits.BigEndian(this._LogicalBlockAddress); } set { this._LogicalBlockAddress = Bits.BigEndian(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.BigEndian(this._NumberOfBlocks); } set { this._NumberOfBlocks = Bits.BigEndian(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