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> /// 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); } } }