Exemplo n.º 1
0
        private void InterceptModeSense6(LogicalUnit logicalUnit, byte[] commandBytes, byte[] response)
        {
            ModeParameterHeader6 header = new ModeParameterHeader6(response, 0);

            if (header.BlockDescriptorLength == ShortLBAModeParameterBlockDescriptor.Length)
            {
                ShortLBAModeParameterBlockDescriptor descriptor = new ShortLBAModeParameterBlockDescriptor(response, ModeParameterHeader6.Length);
                logicalUnit.BlockSize = descriptor.LogicalBlockLength;
                Log(Severity.Verbose, "LUN: {0}, BlockSize updated to {1}", logicalUnit.AssociatedLun, logicalUnit.BlockSize);
            }
        }
Exemplo n.º 2
0
        public SCSIStatusCodeName ModeSense6(ModeSense6CommandDescriptorBlock command, LUNStructure lun, out byte[] response)
        {
            if (lun >= m_disks.Count)
            {
                response = FormatSenseData(SenseDataParameter.GetIllegalRequestInvalidLUNSenseData());
                return(SCSIStatusCodeName.CheckCondition);
            }

            ISCSIServer.Log("[ModeSense6] Page code: 0x{0}, Sub page code: 0x{1}", command.PageCode.ToString("X"), command.SubpageCode.ToString("X"));
            byte[] pageData;

            switch ((ModePageCodeName)command.PageCode)
            {
            case ModePageCodeName.CachingParametersPage:
            {
                CachingParametersPage page = new CachingParametersPage();
                page.RCD = true;
                pageData = page.GetBytes();
                break;
            }

            case ModePageCodeName.ControlModePage:
            {
                ControlModePage page = new ControlModePage();
                pageData = page.GetBytes();
                break;
            }

            case ModePageCodeName.PowerConditionModePage:
            {
                if (command.SubpageCode == 0x00)
                {
                    PowerConditionModePage page = new PowerConditionModePage();
                    pageData = page.GetBytes();
                    break;
                }
                else if (command.SubpageCode == 0x01)
                {
                    PowerConsumptionModePage page = new PowerConsumptionModePage();
                    pageData = page.GetBytes();
                    break;
                }
                else
                {
                    response = FormatSenseData(SenseDataParameter.GetIllegalRequestInvalidFieldInCDBSenseData());
                    ISCSIServer.Log("[ModeSense6] Power condition subpage 0x{0} is not implemented", command.SubpageCode.ToString("x"));
                    return(SCSIStatusCodeName.CheckCondition);
                }
            }

            case ModePageCodeName.InformationalExceptionsControlModePage:
            {
                InformationalExceptionsControlModePage page = new InformationalExceptionsControlModePage();
                pageData = page.GetBytes();
                break;
            }

            case ModePageCodeName.ReturnAllPages:
            {
                CachingParametersPage page1 = new CachingParametersPage();
                page1.RCD = true;
                InformationalExceptionsControlModePage page2 = new InformationalExceptionsControlModePage();

                pageData = new byte[page1.Length + page2.Length];
                Array.Copy(page1.GetBytes(), pageData, page1.Length);
                Array.Copy(page2.GetBytes(), 0, pageData, page1.Length, page2.Length);
                break;
            }

            case ModePageCodeName.VendorSpecificPage:
            {
                // Microsoft iSCSI Target running under Windows 2000 will request this page, we immitate Microsoft iSCSI Target by sending back an empty page
                VendorSpecificPage page = new VendorSpecificPage();
                pageData = page.GetBytes();
                break;
            }

            default:
            {
                response = FormatSenseData(SenseDataParameter.GetIllegalRequestInvalidFieldInCDBSenseData());
                ISCSIServer.Log("[ModeSense6] ModeSense6 page 0x{0} is not implemented", command.PageCode.ToString("x"));
                return(SCSIStatusCodeName.CheckCondition);
            }
            }

            ModeParameterHeader6 header = new ModeParameterHeader6();

            header.WP     = m_disks[lun].IsReadOnly; // Write protected, even when set to true, Windows does not always prevent the disk from being written to.
            header.DPOFUA = true;                    // Microsoft iSCSI Target support this
            byte[] descriptorBytes = new byte[0];
            if (!command.DBD)
            {
                ShortLBAModeParameterBlockDescriptor descriptor = new ShortLBAModeParameterBlockDescriptor();
                descriptor.LogicalBlockLength = (uint)m_disks[lun].BytesPerSector;
                descriptorBytes = descriptor.GetBytes();
            }
            header.BlockDescriptorLength = (byte)descriptorBytes.Length;
            header.ModeDataLength       += (byte)(descriptorBytes.Length + pageData.Length);

            response = new byte[1 + header.ModeDataLength];
            Array.Copy(header.GetBytes(), 0, response, 0, header.Length);
            Array.Copy(descriptorBytes, 0, response, header.Length, descriptorBytes.Length);
            Array.Copy(pageData, 0, response, header.Length + descriptorBytes.Length, pageData.Length);
            return(SCSIStatusCodeName.Good);
        }