Поделиться через


IOCTL_SCSI_PASS_THROUGH_DIRECT IOCTL (ntddscsi.h)

Позволяет приложению отправлять почти любую команду SCSI на целевое устройство со следующими ограничениями:

  • Команды multitarget, такие как COPY, запрещены.
  • Двунаправленные операции передачи данных не поддерживаются.
  • Если существует драйвер класса для целевого типа устройства, запрос должен быть отправлен в этот драйвер класса. Таким образом, приложение может отправлять этот запрос непосредственно в драйвер системного порта для целевой логической единицы, только если для типа устройства, подключенного к этому LU, нет драйвера класса.
  • Этот запрос должен быть выполнен, если входной CDB может потребовать, чтобы базовый драйвер минипорта мог напрямую получить доступ к памяти.
Вызывающее приложение создает блок дескриптора команды SCSI, который может включать запрос на получение данных с чувством запроса при возникновении условия CHECK. Если CDB запрашивает операцию передачи данных, вызывающий объект должен настроить буфер адаптера, выровненный из которого или в который драйвер минипорта может передавать данные напрямую. Этот запрос обычно используется для передачи больших объемов данных (>16K).

Приложения могут отправлять этот запрос с помощью запроса IRP_MJ_DEVICE_CONTROL.

Драйверы классов хранилища задают дополнительный номер IRP для IRP_MN_SCSI_CLASS, чтобы указать, что запрос был обработан драйвером класса хранилища.

примечание модели драйверов портов SCSI и мини-порта SCSI могут быть изменены или недоступны в будущем. Вместо этого мы рекомендуем использовать драйвера Storport и минипорта Storport модели драйверов.
 

Основной код

IRP_MJ_DEVICE_CONTROL

Входной буфер

Эта структура включает CDB SCSI, которая должна быть инициализирована вызывающим объектом, за исключением пути, целевого идентификатора и LUN, которые заполняются драйвером порта. Для команды вывода данных передаваемые данные должны находиться в буфере, выровненном на устройстве адаптера. Элемент DataBufferSCSI_PASS_THROUGH_DIRECT является указателем на этот буфер, выровненный на устройство адаптера. Вызывающий объект должен выделить дополнительное хранилище, следуя SCSI_PASS_THROUGH_DIRECT структуре, если вызывающий запрашивает данные о запросе.

Длина входного буфера

Parameters.DeviceIoControl.InputBufferLength указывает размер буфера в байтах в Irp->AssociatedIrp.SystemBuffer, который должен быть по крайней мере (смысле размер данных + размер (SCSI_PASS_THROUGH_DIRECT)). Размер структуры SCSI_PASS_THROUGH_DIRECT исправлен.

Выходной буфер

Драйвер порта возвращает все данные с чувством запроса и структуру SCSI_PASS_THROUGH_DIRECT буферу в Irp->AssociatedIrp.SystemBuffer.

Длина выходного буфера

SenseInfoLength и DataTransferLeng th обновляются, чтобы указать объем передаваемых данных. Драйвер порта возвращает все данные, передаваемые с устройства в предоставленный буфер, выровненный в кэше, в DataBuffer.

Блок состояния

В поле сведений задано количество байтов, возвращаемых в выходном буфере в Irp->AssociatedIrp.SystemBuffer. Поле "Состояние" имеет значение STATUS_SUCCESSили, возможно, STATUS_BUFFER_TOO_SMALL или STATUS_INVALID_PARAMETER, если входное значение длина в SCSI_PASS_THROUGH_DIRECT неправильно задано или буфер, указанный в DataBuffer, не соответствует правильному выравниванию устройства.

Замечания

Для операций передачи данных требуется буфер с выравниванием, соответствующим устройству адаптера. Приложения могут получить маску выравнивания устройства, выдав запрос кода IOCTL_STORAGE_QUERY_PROPERTY с типом запроса PropertyStandardQuery и идентификатором свойства StorageAdapterProperTy. Маска выравнивания найдена в элементе AlignmentMask возвращаемой структуры STORAGE_ADAPTER_DESCRIPTOR. Драйверы также могут использовать значение в элементе AlignmentMaskDeviceObject адаптера.

В следующем примере функции буфер подготавливается как буфер, выровняемый устройством буфер передачи данных.

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

Требования

Требование Ценность
заголовка ntddscsi.h (include Ntddscsi.h)

См. также

IOCTL_SCSI_PASS_THROUGH

IOCTL_STORAGE_QUERY_PROPERTY

SCSI_PASS_THROUGH_DIRECT