public SCSIStatusCodeName Write(SCSICommandDescriptorBlock command, LUNStructure lun, byte[] data, out byte[] response) { Disk disk = m_disks[lun]; if (disk.IsReadOnly) { Log(Severity.Verbose, "LUN {0}: Refused attempt to write to a read-only disk", lun); SenseDataParameter senseData = SenseDataParameter.GetDataProtectSenseData(); response = senseData.GetBytes(); return(SCSIStatusCodeName.CheckCondition); } Log(Severity.Verbose, "LUN {0}: Writing {1} blocks starting from LBA {2}", (ushort)lun, command.TransferLength, (long)command.LogicalBlockAddress64); try { disk.WriteSectors((long)command.LogicalBlockAddress64, data); response = new byte[0]; return(SCSIStatusCodeName.Good); } catch (ArgumentOutOfRangeException) { Log(Severity.Error, "Write error: LBA out of range"); response = FormatSenseData(SenseDataParameter.GetIllegalRequestLBAOutOfRangeSenseData()); return(SCSIStatusCodeName.CheckCondition); } catch (IOException ex) { Log(Severity.Error, "Write error: {0}", ex.ToString()); response = FormatSenseData(SenseDataParameter.GetMediumErrorWriteFaultSenseData()); return(SCSIStatusCodeName.CheckCondition); } }
public static byte[] FormatSenseData(SenseDataParameter senseData) { byte[] senseDataBytes = senseData.GetBytes(); byte[] result = new byte[senseDataBytes.Length + 2]; BigEndianWriter.WriteUInt16(result, 0, (ushort)senseDataBytes.Length); ByteWriter.WriteBytes(result, 2, senseDataBytes); return(result); }