Exemplo n.º 1
0
        public SCSIStatusCodeName Read(SCSICommandDescriptorBlock command, LUNStructure lun, out byte[] response)
        {
            Disk disk        = m_disks[lun];
            int  sectorCount = (int)command.TransferLength;

            Log(Severity.Verbose, "LUN {0}: Reading {1} blocks starting from LBA {2}", (ushort)lun, sectorCount, (long)command.LogicalBlockAddress64);
            try
            {
                response = disk.ReadSectors((long)command.LogicalBlockAddress64, sectorCount);
                return(SCSIStatusCodeName.Good);
            }
            catch (ArgumentOutOfRangeException)
            {
                Log(Severity.Error, "Read error: LBA out of range");
                response = FormatSenseData(SenseDataParameter.GetIllegalRequestLBAOutOfRangeSenseData());
                return(SCSIStatusCodeName.CheckCondition);
            }
            catch (CyclicRedundancyCheckException)
            {
                Log(Severity.Error, "Read error: CRC error");
                response = FormatSenseData(SenseDataParameter.GetWriteFaultSenseData());
                return(SCSIStatusCodeName.CheckCondition);
            }
            catch (IOException ex)
            {
                Log(Severity.Error, "Read error: {0}", ex.ToString());
                response = FormatSenseData(SenseDataParameter.GetMediumErrorUnrecoverableReadErrorSenseData());
                return(SCSIStatusCodeName.CheckCondition);
            }
        }
Exemplo n.º 2
0
        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);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// This implementation is not thread-safe.
        /// </summary>
        public override SCSIStatusCodeName ExecuteCommand(byte[] commandBytes, LUNStructure lun, byte[] data, out byte[] response)
        {
            SCSICommandDescriptorBlock command;

            try
            {
                command = SCSICommandDescriptorBlock.FromBytes(commandBytes, 0);
            }
            catch (UnsupportedSCSICommandException)
            {
                Log(Severity.Error, "Unsupported SCSI Command (0x{0})", commandBytes[0].ToString("X"));
                response = FormatSenseData(SenseDataParameter.GetIllegalRequestUnsupportedCommandCodeSenseData());
                return(SCSIStatusCodeName.CheckCondition);
            }

            return(ExecuteCommand(command, lun, data, out response));
        }
Exemplo n.º 4
0
 /// <summary>
 /// This implementation is not thread-safe.
 /// </summary>
 public SCSIStatusCodeName ExecuteCommand(SCSICommandDescriptorBlock command, LUNStructure lun, byte[] data, out byte[] response)
 {
     Log(Severity.Verbose, "Executing command: {0}", command.OpCode);
     if (command.OpCode == SCSIOpCodeName.ReportLUNs)
     {
         uint allocationLength = command.TransferLength;
         return(ReportLUNs(allocationLength, out response));
     }
     else if (lun >= m_disks.Count)
     {
         Log(Severity.Warning, "Initiator error: tried to execute command on LUN {0} which does not exist", lun);
         response = FormatSenseData(SenseDataParameter.GetIllegalRequestInvalidLUNSenseData());
         return(SCSIStatusCodeName.CheckCondition);
     }
     else if (command.OpCode == SCSIOpCodeName.TestUnitReady)
     {
         return(TestUnitReady(lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.RequestSense)
     {
         uint allocationLength = command.TransferLength;
         return(RequestSense(lun, allocationLength, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.Inquiry)
     {
         return(Inquiry((InquiryCommand)command, lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.Reserve6)
     {
         return(Reserve6(lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.Release6)
     {
         return(Release6(lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.ModeSense6)
     {
         return(ModeSense6((ModeSense6CommandDescriptorBlock)command, lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.ReadCapacity10)
     {
         return(ReadCapacity10(lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.Read6 ||
              command.OpCode == SCSIOpCodeName.Read10 ||
              command.OpCode == SCSIOpCodeName.Read16)
     {
         return(Read(command, lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.Write6 ||
              command.OpCode == SCSIOpCodeName.Write10 ||
              command.OpCode == SCSIOpCodeName.Write16)
     {
         return(Write(command, lun, data, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.Verify10 ||
              command.OpCode == SCSIOpCodeName.Verify16)
     {
         return(Verify(lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.SynchronizeCache10)
     {
         return(SynchronizeCache10(lun, out response));
     }
     else if (command.OpCode == SCSIOpCodeName.ServiceActionIn16 &&
              command.ServiceAction == ServiceAction.ReadCapacity16)
     {
         uint allocationLength = command.TransferLength;
         return(ReadCapacity16(lun, allocationLength, out response));
     }
     else
     {
         Log(Severity.Error, "Unsupported SCSI Command (0x{0})", command.OpCode.ToString("X"));
         response = FormatSenseData(SenseDataParameter.GetIllegalRequestUnsupportedCommandCodeSenseData());
         return(SCSIStatusCodeName.CheckCondition);
     }
 }