/// <summary> /// Returns the size of layer 0 for DL media (DVD+R DL and DVD-R DL) /// </summary> /// <param name="isfixed">return value, if true size of L0 is changable</param> /// <param name="size">return value, the current size of L0</param> /// <returns>status of the command</returns> public CommandStatus ReadDvdLayer0Size(out bool isfixed, out uint size) { if (m_logger != null) { string args = "ReadDvdLayer0Size, out bool isfixed, out uint size"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructure(" + args + ")")); } size = 0; isfixed = false; using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 12, Command.CmdDirection.In, 5 * 60)) { cmd.SetCDB8(7, 0x20); // Read manufacturing information cmd.SetCDB8(8, 12); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; if ((cmd.GetBuffer8(4) & 0x80) != 0) isfixed = true; size = cmd.GetBuffer32(8); } return CommandStatus.Success; }
/// <summary> /// Write data to the device into a memory buffer /// </summary> /// <param name="force">If true, the data is forced from the media and cannot be read from the cache</param> /// <param name="streaming">If true, this is a streaming read</param> /// <param name="lba">The starting logical address for the data</param> /// <param name="sector_size">the size of a sector in bytes</param> /// <param name="length">The length of the data to write in sectors</param> /// <param name="data">The buffer to receive the data</param> /// <returns></returns> public CommandStatus Write(bool force, bool streaming, int lba, int sector_size, int length, IntPtr data) { if (m_logger != null) { string args = force.ToString() + ", " + streaming.ToString() + ", " + lba.ToString() + ", " + length.ToString() + ", IntPtr, "; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Write(" + args + ")")); } if (streaming || length > 65535) { using (Command cmd = new Command(ScsiCommandCode.Write12, 12, data, length * sector_size, Command.CmdDirection.Out, 5 * 60)) { if (force) cmd.SetCDB8(1, 4); // Set the FUA bit cmd.SetCDB32(2, lba); cmd.SetCDB32(6, length); if (streaming) cmd.SetCDB8(10, 0x80); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) { m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 4, "Write failed at lba " + lba.ToString())); return st; } } } else { using (Command cmd = new Command(ScsiCommandCode.Write, 10, data, length * sector_size, Command.CmdDirection.Out, 5 * 60)) { if (force) cmd.SetCDB8(1, 4); // Set the FUA bit cmd.SetCDB32(2, lba); cmd.SetCDB16(7, (ushort)length); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) { m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 4, "Write failed at lba " + lba.ToString())); return st; } } } return CommandStatus.Success; }
private CommandStatus SendCommand(Command cmd) { return (m_ossize == 32) ? SendCommand32(cmd) : SendCommand64(cmd); }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus SynchronizeCache(bool immd) { if (m_logger != null) { string args = ""; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SynchronizeCache(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.SyncronizeCache, 10, 0, Command.CmdDirection.None, 30 * 60)) { if (immd) cmd.SetCDB8(1, 2); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus Verify(int start, int size) { if (m_logger != null) { string args = start.ToString() + ", " + size.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Verify(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.Verify, 10, 2048, Command.CmdDirection.None, 60 * 60)) { cmd.SetCDB32(2, (uint)start); cmd.SetCDB16(7, (ushort)size); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus SetStreaming(SpeedDescriptor desc) { if (m_logger != null) { string args = "desc"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetStreaming(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.SetStreaming, 12, 28, Command.CmdDirection.Out, 2)) { cmd.SetCDB8(8, 0); // Performance Descriptor cmd.SetCDB16(9, 28); // Length of the performance descriptor byte b = 0; if (desc.Exact) b |= 0x02; int wrc = (int)(desc.WRC) ; b |= (byte)(wrc << 3); cmd.SetBuffer8(0, b); // Control info, byte 0 cmd.SetBuffer32(4, 0); // Start LBA cmd.SetBuffer32(8, (uint)desc.EndLBA); // End LBA cmd.SetBuffer32(12, (uint)desc.ReadSpeed); // Read size cmd.SetBuffer32(16, 1000); // Read time cmd.SetBuffer32(20, (uint)desc.WriteSpeed); // Write size cmd.SetBuffer32(24, 1000); // Write time CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus StartStopUnit(bool immd, PowerControl pc, StartState state) { if (m_logger != null) { string args = immd.ToString() + ", " + pc.ToString() + ", " + state.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.StartStopUnit(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.StartStopUnit, 6, 0, Command.CmdDirection.None, 30)) { if (immd) cmd.SetCDB8(1, 1) ; byte b = (byte)(((byte)pc << 4) | ((byte)state)) ; cmd.SetCDB8(4, b) ; CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// This method reads the ATIP information from a CD media /// </summary> /// <returns></returns> public CommandStatus ReadAtip(out AtipInfo info) { ushort len; info = null; if (m_logger != null) { string args = "info"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadAtip(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 32, Command.CmdDirection.In, 5 * 60)) { cmd.SetCDB8(2, 4); cmd.SetCDB16(7, 32); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; len = cmd.GetBuffer16(0); len += 2; } if (len <= 4) return CommandStatus.Success; using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, 5 * 60)) { cmd.SetCDB8(2, 4); cmd.SetCDB16(7, len); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; info = new AtipInfo(cmd.GetBuffer(), len); } return CommandStatus.Success; }
/// <summary> /// This method reads the ATIP information from a CD media /// </summary> /// <returns></returns> public CommandStatus ReadPMA(out byte[] data) { ushort len; data = null; if (m_logger != null) { string args = "info"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadFullToc(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 320, Command.CmdDirection.In, 5 * 60)) { cmd.SetCDB8(1, 2); cmd.SetCDB8(2, 3); cmd.SetCDB16(7, 320); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; len = cmd.GetBuffer16(0); len += 2; if (len <= 320) { data = new byte[len]; Marshal.Copy(cmd.GetBuffer(), data, 0, len); return CommandStatus.Success; } } using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, 5 * 60)) { cmd.SetCDB8(2, 3); cmd.SetCDB16(7, len); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; //info = new AtipInfo(cmd.GetBuffer(), len); data = new byte[len]; Marshal.Copy(cmd.GetBuffer(), data, 0, len); } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus ReadFormatCapacities(bool all, out IList<CapacityDescriptor> caplist) { caplist = new List<CapacityDescriptor>(); if (m_logger != null) { string args = all.ToString() + ", out caplist"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadFormatCapacities(" + args + ")")); } int len; using (Command cmd = new Command(ScsiCommandCode.ReadFormatCapacities, 10, 8, Command.CmdDirection.In, 60)) { cmd.SetCDB16(7, 8); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; len = cmd.GetBuffer8(3) + 4; } using (Command cmd = new Command(ScsiCommandCode.ReadFormatCapacities, 10, len, Command.CmdDirection.In, 60)) { cmd.SetCDB16(7, (ushort)len); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; int offset = 4; len = cmd.GetBuffer8(3) + 4; while (offset < len) { caplist.Add(new CapacityDescriptor(cmd.GetBuffer(), offset, cmd.BufferSize)); offset += 8; } } return CommandStatus.Success; }
/// <summary> /// Read the table of contents from the disk /// </summary> /// <param name="track">the track or session to find the TOC for</param> /// <param name="toc">a list return value containins a list of table of content entryies</param> /// <param name="mode">time versus lba mode</param> /// <returns></returns> public CommandStatus ReadToc(byte track, bool mode, out IList<TocEntry> toc) { ushort len; toc = null; if (m_logger != null) { string args = "info"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadToc(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 16, Command.CmdDirection.In, 5 * 60)) { if (mode) cmd.SetCDB8(1, 2); cmd.SetCDB8(6, track); cmd.SetCDB16(7, 16); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; len = cmd.GetBuffer16(0); len += 2; } using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, 5 * 60)) { if (mode) cmd.SetCDB8(1, 2); cmd.SetCDB8(6, track); cmd.SetCDB16(7, len); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; int offset = 4; toc = new List<TocEntry>(); while (offset + 8 <= len) { TocEntry entry = new TocEntry(cmd.GetBuffer(), offset, cmd.BufferSize, mode); toc.Add(entry); offset += 8; } } return CommandStatus.Success; }
/// <summary> /// Send the layer boundary information to the drive. /// </summary> /// <param name="boundary">the location of the boundary between layers in blocks</param> /// <returns>the status of the command</returns> public CommandStatus SendDvdLayerBoundaryInformation(uint boundary) { if (m_logger != null) { string args = "SendDvdLayerBoundaryInformation, boundary=" + boundary.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SendDvdStructure(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.SendDvdStructure, 12, 12, Command.CmdDirection.Out, 5 * 60)) { cmd.SetCDB8(7, 0x20); cmd.SetCDB16(8, 12); cmd.SetBuffer16(0, 10); cmd.SetBuffer32(8, boundary); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// This method returns the remapping address (DVD-R DL( /// </summary> /// <param name="location">the remapping address</param> /// <returns>the command status</returns> public CommandStatus ReadDvdRemappingAddress(out uint location) { if (m_logger != null) { string args = "ReadDvdRemappingAddress, out uint size"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructure(" + args + ")")); } location = 0; using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 12, Command.CmdDirection.In, 5 * 60)) { cmd.SetCDB8(7, 0x24); cmd.SetCDB8(8, 12); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; location = cmd.GetBuffer32(8); } return CommandStatus.Success; }
/// <summary> /// Returns the start address of the Layer 0 middle zone (DVD+R DL, DVD-R DL) /// </summary> /// <param name="isfixed">return value, if true, the middle zone start is changeable</param> /// <param name="location">return value, the location of the L0 middle zone</param> /// <returns>status of the command</returns> public CommandStatus ReadDvdMiddleZoneStartAddr(out bool isfixed, out uint location) { if (m_logger != null) { string args = "ReadDvdMiddleZoneStartAddr, out bool isfixed, out uint size"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructure(" + args + ")")); } location = 0; isfixed = false; using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 12, Command.CmdDirection.In, 5 * 60)) { cmd.SetCDB8(7, 0x21); cmd.SetCDB8(8, 12); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; if ((cmd.GetBuffer8(4) & 0x80) != 0) isfixed = true; location = cmd.GetBuffer32(8); } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus SetCdSpeedDA(RotationalControl ctrl, ushort read, ushort write) { if (m_logger != null) { string args = ctrl.ToString() + ", " + read.ToString() + ", " + write.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetCdSpeed(" + args + ")")); } using (Command cmd = new Command((ScsiCommandCode)0xDA, 12, 0, Command.CmdDirection.None, 2)) { cmd.SetCDB8(1, (byte)ctrl); cmd.SetCDB16(2, read); cmd.SetCDB16(4, write); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus ReadTrackInformation(ReadTrackType type, uint addr, out TrackInformation info) { info = null; if (m_logger != null) { string args = "info"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadTrackInformation(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.ReadTrackInformation, 10, 48, Command.CmdDirection.In, 5 * 60)) { cmd.SetCDB8(1, (byte)type); cmd.SetCDB32(2, addr); cmd.SetCDB16(7, 40); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; info = new TrackInformation(cmd.GetBuffer(), cmd.BufferSize); } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus SetReadAhead(uint trigger, uint lba) { if (m_logger != null) { string args = trigger.ToString() + ", " + lba.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetReadAhead(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.SetReadAhead, 12, 0, Command.CmdDirection.None, 2)) { cmd.SetCDB32(2, trigger); cmd.SetCDB32(6, lba); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus RequestSense() { if (m_logger != null) { m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.RequestSense()")); } using (Command cmd = new Command(ScsiCommandCode.RequestSense, 6, 18, Command.CmdDirection.None, 5*60)) { cmd.SetCDB8(4, 18); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; m_sense_info = new byte[18]; Marshal.Copy(cmd.GetBuffer(), m_sense_info, 0, 18); } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus SetStreaming(RotationalControl rot, int startlba, int endlba, int readsize, int readtime, int writesize, int writetime) { if (m_logger != null) { string args = "desc"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetStreaming(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.SetStreaming, 12, 28, Command.CmdDirection.Out, 60*5)) { cmd.SetCDB8(8, 0); // Performance Descriptor cmd.SetCDB16(9, 28); // Length of the performance descriptor byte b = 0; int wrc = (int)rot; b |= (byte)(wrc << 3); cmd.SetBuffer8(0, b); // Control info, byte 0 cmd.SetBuffer32(4, (uint)startlba); // Start LBA cmd.SetBuffer32(8, (uint)endlba); // End LBA cmd.SetBuffer32(12, (uint)readsize); // Read size cmd.SetBuffer32(16, (uint)readtime); // Read time cmd.SetBuffer32(20, (uint)writesize); // Write size cmd.SetBuffer32(24, (uint)writetime); // Write time CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus ReserveTrack(uint size) { if (m_logger != null) { string args = size.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReserveTrack(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.ReserveTrack, 10, 0, Command.CmdDirection.None, 5 * 60)) { cmd.SetCDB32(5, size); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus StopPlayScan() { using (Command cmd = new Command(ScsiCommandCode.StopPlayScan, 10, 0, Command.CmdDirection.None, 30)) { if (m_logger != null) { string args = ""; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.StopPlayScan(" + args + ")")); } CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus Scan(ScanDirection dir, uint lba, ScanType type) { if (m_logger != null) { string args = dir.ToString() + ", " + lba.ToString() + ", " + type.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Scan(" + args + ")")); } if (type == ScanType.Reserved) throw new Exception("type parameter is of type Reserved"); using (Command cmd = new Command(ScsiCommandCode.Scan, 12, 0, Command.CmdDirection.None, 10)) { if (dir == ScanDirection.Reverse) cmd.SetCDB8(1, 0x10); cmd.SetCDB32(2, lba); cmd.SetCDB8(9, (byte)((byte)type << 6)); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus TestUnitReady(out bool ready) { if (m_logger != null) { string args = "out ready"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 9, "Bwg.Scsi.Device.TestUnitReady(" + args + ")")); } ready = true; using (Command cmd = new Command(ScsiCommandCode.TestUnitReady, 6, 0, Command.CmdDirection.None, 60)) { CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) { ready = false ; if (st == CommandStatus.DeviceFailed && GetSenseKey() == SenseKeyType.NotReady) st = CommandStatus.Success; return st; } } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus Seek(uint lba) { if (m_logger != null) { string args = lba.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Seek(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.Seek, 10, 0, Command.CmdDirection.None, 10)) { CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// This method requests that the SCSI device transfer data from the given buffer to the device /// </summary> /// <param name="force">If true, the data is forced from the media and cannot be read from the cache</param> /// <param name="streaming">If true, this is a streaming read</param> /// <param name="lba">The starting logical address for the data</param> /// <param name="sector_size">the size of the sector data in bytes</param> /// <param name="length">The length of the data to write in sectors</param> /// <param name="data">The data buffer to received the data</param> /// <returns></returns> public CommandStatus Write(bool force, bool streaming, int lba, int sector_size, int length, ref byte[] data) { if (m_logger != null) { string args = force.ToString() + ", " + streaming.ToString() + ", " + lba.ToString() + ", " + length.ToString() + ", buffer"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Write(" + args + ")")); } Debug.Assert(length == data.GetLength(0) * sector_size); fixed (byte *bptr = &data[0]) { IntPtr bufptr = new IntPtr(bptr); if (streaming || length > 65535) { using (Command cmd = new Command(ScsiCommandCode.Write12, 12, bufptr, length * sector_size, Command.CmdDirection.Out, 5 * 60)) { if (force) cmd.SetCDB8(1, 4); // Set the FUA bit cmd.SetCDB32(2, lba); cmd.SetCDB32(6, length); if (streaming) cmd.SetCDB8(10, 0x80); // Set the streaming bit CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } } else { using (Command cmd = new Command(ScsiCommandCode.Write, 10, bufptr, length * sector_size, Command.CmdDirection.Out, 5 * 60)) { if (force) cmd.SetCDB8(1, 4); // Set the FUA bit cmd.SetCDB32(2, lba); cmd.SetCDB16(7, (ushort)length); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } } } return CommandStatus.Success; }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus SendCueSheet(byte [] sheet) { if (m_logger != null) { string args = sheet.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SendCueSheet(" + args + ")")); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 1, "Cue Sheet")); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 1, "----------------------------------------------")); for (int i = 0; i < sheet.GetLength(0) / 8; i++) { string s = "" ; for (int j = 0; j < 8; j++) { if (j != 0) s += " "; s += sheet[i * 8 + j].ToString("x2"); } m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 1, s)); } m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 1, "----------------------------------------------")); } ushort len = (ushort)sheet.GetLength(0); using (Command cmd = new Command(ScsiCommandCode.SendCueSheet, 10, len, Command.CmdDirection.Out, 10)) { cmd.SetCDB32(5, len); cmd.SetCDB8(5, 0); Marshal.Copy(sheet, 0, cmd.GetBuffer(), len); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
/// <summary> /// Send the sense information to the logger /// </summary> private void LogSenseInformation(Command cmd) { if (m_ignore_long_write_error && IsLongWriteInProgress(GetSenseAsc(), GetSenseAscq())) return; if (m_logger != null && LogSenseState) { int len = GetSenseLength(); int offset = 0; int line = 0; UserMessage m; string str; Logger logger = GetLogger(); str = "SCSI Operation Failed: " ; str += LookupSenseError(GetSenseAsc(), GetSenseAscq()) ; m = new UserMessage(UserMessage.Category.Error, 0, str); m_logger.LogMessage(m); str = " SenseKey = " + GetSenseKey().ToString("X"); m = new UserMessage(UserMessage.Category.Error, 0, str); m_logger.LogMessage(m); str = " SenseAsc = " + GetSenseAsc().ToString("X"); m = new UserMessage(UserMessage.Category.Error, 0, str); m_logger.LogMessage(m); str = " SenseAscq = " + GetSenseAscq().ToString("X"); m = new UserMessage(UserMessage.Category.Error, 0, str); m_logger.LogMessage(m); while (offset < len) { line = 0; str = " SenseData:"; while (offset < len && line < 8) { str += " " + GetSenseByte(offset++).ToString("X2"); line++; } m = new UserMessage(UserMessage.Category.Error, 0, str); logger.LogMessage(m); } if (GetSenseAsc() == 0x24 && GetSenseAscq() == 0x00) { // This is invalid field in CDB, so dump the CDB to the log str = "INVALID CDB:"; for (byte i = 0; i < cmd.GetCDBLength(); i++) { byte b = cmd.GetCDB(i); str += " " + b.ToString("X"); } m = new UserMessage(UserMessage.Category.Error, 0, str); m_logger.LogMessage(m); } } }
/// <summary> /// /// </summary> /// <returns></returns> public CommandStatus SendOpcInformation(bool doopc, object o) { if (m_logger != null) { string args = doopc.ToString(); m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SendOpcInformation(" + args + ")")); } ushort len = 0; if (o != null) throw new Exception("SendOpcInformation() - non-null OPC information not supported"); using (Command cmd = new Command(ScsiCommandCode.SendOpcInformation, 10, len, Command.CmdDirection.Out, 60)) { if (doopc) cmd.SetCDB8(1, 1); CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; } return CommandStatus.Success; }
private CommandStatus SendCommand32(Command cmd) { SCSI_PASS_THROUGH_DIRECT32 f = new SCSI_PASS_THROUGH_DIRECT32(); f.Length = m_scsi_request_size_32; f.CdbLength = (byte)cmd.GetCDBLength(); f.DataIn = 0; if (cmd.Direction == Command.CmdDirection.In) f.DataIn = 1; f.DataTransferLength = (uint)cmd.BufferSize; f.TimeOutValue = (uint)cmd.TimeOut; for (byte i = 0; i < f.CdbLength; i++) f.CdbData[i] = cmd.GetCDB(i); f.SenseInfoOffset = 48; f.SenseInfoLength = 24; uint total = (uint)Marshal.SizeOf(f); uint ret = 0; // Set the buffer field f.DataBuffer = cmd.GetBuffer(); // Send through ioctl field IntPtr pt = new IntPtr(&f); if (!Control(IOCTL_SCSI_PASS_THROUGH_DIRECT, pt, total, pt, total, ref ret, IntPtr.Zero)) { string str ; str = "IOCTL_SCSI_PASS_THROUGH_DIRECT failed - " + Win32ErrorToString(LastError); m_logger.LogMessage(new UserMessage(UserMessage.Category.Error, 0, str)); return CommandStatus.IoctlFailed; } m_scsi_status = f.ScsiStatus; if (f.SenseInfoLength != 0) { m_sense_info = new byte[f.SenseInfoLength]; for (int i = 0; i < f.SenseInfoLength; i++) m_sense_info[i] = f.SenseInfo[i]; } else m_sense_info = null; if (m_scsi_status != 0) { LogSenseInformation(cmd); return CommandStatus.DeviceFailed; } return CommandStatus.Success; }
/// <summary> /// Query the media for the spare sectors available /// </summary> /// <param name="primary">the number of primary spare sectors available</param> /// <param name="sec_avail">the number of secondary spare sectors available</param> /// <param name="sec_total">the number of secondary spare sectors total</param> /// <returns></returns> public CommandStatus ReadDVDRamSpareAreaInfo(out uint primary, out uint sec_avail, out uint sec_total) { primary = 0; sec_avail = 0; sec_total = 0; if (m_logger != null) { string args = "out primary, out sec_avail, out sec_total"; m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDVDRamSpareAreaInfo(" + args + ")")); } using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 2048, Command.CmdDirection.In, 60)) { cmd.SetCDB8(7, 0x0a); // Read manufacturing information cmd.SetCDB16(8, 16); // Up to 2k of data CommandStatus st = SendCommand(cmd); if (st != CommandStatus.Success) return st; primary = cmd.GetBuffer32(4); sec_avail = cmd.GetBuffer32(8); sec_total = cmd.GetBuffer32(12); } return CommandStatus.Success; }