IOCTL_SCSI_PASS_THROUGH_DIRECT_EX IOCTL (ntddscsi.h)
Запрос кода управления IOCTL_SCSI_PASS_THROUGH_DIRECT_EX — это расширенная версия запроса IOCTL_SCSI_PASS_THROUGH_DIRECT . Этот запрос обеспечивает поддержку двунаправленной передачи данных и позволяет использовать командный блок данных (CDB) > размером 16 байт.
Позволяет приложению отправлять практически любую команду SCSI на целевое устройство со следующими ограничениями:
- Многоцелевое использование команд, таких как COPY, запрещено.
- Если существует драйвер класса для целевого типа устройства, запрос должен быть отправлен в этот драйвер класса. Таким образом, приложение может отправить этот запрос непосредственно в драйвер системного порта для целевой логической единицы, только если отсутствует драйвер класса для типа устройства, подключенного к этому LU.
- Этот запрос необходимо выполнить, если для входных данных CDB может потребоваться, чтобы базовый драйвер мини-порта мог напрямую обращаться к памяти.
Приложения могут отправлять этот запрос с помощью запроса IRP_MJ_DEVICE_CONTROL .
Драйверы класса хранилища устанавливают дополнительный номер IRP IRP_MN_SCSI_CLASS, чтобы указать, что запрос был обработан драйвером класса хранения.
Основной код
Входной буфер
Parameters.DeviceIoControl.InputBufferLength указывает размер буфера в байтах в Irp->AssociatedIrp.SystemBuffer, который должен быть по крайней мере (значение размера данных + sensesizeof(SCSI_PASS_THROUGH_DIRECT_EX)). Размер структуры SCSI_PASS_THROUGH_DIRECT_EX является фиксированным.Эта структура включает cdb SCSI, который должен быть инициализирован вызывающим объектом, за исключением пути, целевого идентификатора и LUN, которые заполняются драйвером порта. Для выполнения команды вывода данных передаваемые данные должны находиться в буфере, выровненном для устройства адаптера. Элемент DataInBufferSCSI_PASS_THROUGH_DIRECT_EX является указателем на буфер, выровняемый устройством адаптера. Вызывающий объект должен выделить дополнительное хранилище в соответствии со структурой SCSI_PASS_THROUGH_DIRECT_EX , если вызывающий объект запрашивает данные с учетом запроса.
Длина входного буфера
Parameters.DeviceIoControl.InputBufferLength указывает размер буфера в байтах в Irp->AssociatedIrp.SystemBuffer, который должен быть по крайней мере (значение размера данных + sensesizeof(SCSI_PASS_THROUGH_DIRECT_EX)). Размер структуры SCSI_PASS_THROUGH_DIRECT_EX является фиксированным.Выходной буфер
Драйвер порта возвращает все данные о смысле запроса и структуру SCSI_PASS_THROUGH_DIRECT_EX в буфер по адресу Irp-AssociatedIrp.SystemBuffer>.
Длина выходного буфера
SenseInfoLength и DataOutTransferLength обновляются для указания объема передаваемых данных. Драйвер порта возвращает все данные, передаваемые с устройства в предоставленный буфер, выровненный по кэшу, в DataOutBuffer.
Блок состояния
В поле Information задается число байтов, возвращаемых в выходном буфере в Irp-AssociatedIrp.SystemBuffer>. Для поля Состояние задано значение STATUS_SUCCESS или, возможно, значение STATUS_BUFFER_TOO_SMALL или STATUS_INVALID_PARAMETER , если входное значение Length в SCSI_PASS_THROUGH_DIRECT_EX задано неправильно или буфер, указанный в DataInBuffer , неправильно выровнен по устройству.
Комментарии
Для операций передачи данных требуется буфер с выравниванием, соответствующим устройству адаптера. Приложения могут получить маску выравнивания устройства, отправив IOCTL_STORAGE_QUERY_PROPERTY запрос кода управления с типом запроса PropertyStandardQuery и идентификатором свойства StorageAdapterProperty. Маска выравнивания находится в элементе AlignmentMask возвращаемой структуры STORAGE_ADAPTER_DESCRIPTOR . Драйверы также могут использовать значение в элементе AlignmentMaskобъекта DeviceObject адаптера.
В следующем примере функции буфер подготавливается как буфер передачи данных, выровненный по устройству.
PVOID AllocateAlignedBuffer(ULONG size, ULONG AlignmentMask, PVOID *pUnAlignedBuffer)
{
PVOID AlignedBuffer;
ULONG_PTR FullWordMask = (ULONG_PTR)AlignmentMask;
if (AlignmentMask == 0)
{
AlignedBuffer = malloc(size);
// return the original buffer to free later
*pUnAlignedBuffer = AlignedBuffer;
}
else
{
// expand the size for the alignment window
size += AlignmentMask;
AlignedBuffer = malloc(size);
// return the original buffer to free later
*pUnAlignedBuffer = AlignedBuffer;
// adjust buffer pointer for the desired alignment
AlignedBuffer = (PVOID)(((ULONG_PTR)AlignedBuffer + FullWordMask) & ~FullWordMask);
}
return AlignedBuffer;
}
Чтобы отправить запрос IOCTL_SCSI_PASS_THROUGH_DIRECT_EX , базовое запоминающее устройство должно поддерживать расширенные SSPB. Это означает, что поддерживаемый тип SRB — SRB_TYPE_STORAGE_REQUEST_BLOCK. Приложение может запрашивать поддержку SRB с помощью запроса IOCTL_STORAGE_QUERY_PROPERTY с типом запроса PropertyStandardQuery и типом свойства StorageDeviceProperty. Элемент SrbType , возвращенный в структуре STORAGE_ADAPTER_DESCRIPTIOR , будет указывать SRB_TYPE_SCSI_REQUEST_BLOCK или SRB_TYPE_STORAGE_REQUEST_BLOCK.
Требования
Требование | Значение |
---|---|
Заголовок | ntddscsi.h (включая Ntddscsi.h) |