共用方式為


IOCTL_SCSI_PASS_THROUGH_DIRECT IOCTL (ntddscsi.h)

允許應用程式使用下列限制,將幾乎所有的 SCSI 命令傳送至目標裝置:

  • 不允許多目標命令,例如 COPY。
  • 不支援雙向數據傳輸作業。
  • 如果裝置目標類型的類別驅動程式存在,則必須將要求傳送至該類別驅動程式。 因此,只有在連線至該 LU 的裝置類型沒有類別驅動程式時,應用程式才能將這個要求直接傳送至目標邏輯單元的系統埠驅動程式。
  • 如果輸入CDB可能需要基礎迷你埠驅動程式直接存取記憶體,則必須 此要求
呼叫的應用程式會建立 SCSI 命令描述元區塊,如果發生 CHECK CONDITION,可以包含要求感知數據的要求。 如果CDB要求數據傳輸作業,呼叫端必須設定配接器裝置對齊緩衝區,迷你埠驅動程式可以從該緩衝區或小型埠驅動程式直接傳輸數據。 此要求通常用於傳輸大量數據(>16K)。

應用程式可以透過 IRP_MJ_DEVICE_CONTROL 要求傳送此要求。

記憶體類別驅動程式會將次要 IRP 編號設定為 IRP_MN_SCSI_CLASS,表示記憶體類別驅動程式已處理要求。

注意 SCSI 連接埠驅動程式和 SCSI 迷你埠驅動程式模型未來可能會改變或無法使用。 相反地,我們建議使用 Storport 驅動程式Storport miniport 驅動程式模型。
 

主要程序代碼

IRP_MJ_DEVICE_CONTROL

輸入緩衝區

此結構包含 SCSI CDB,其必須由呼叫端初始化,但埠驅動程式所填入的路徑、目標標識元和 LUN 除外。 針對數據輸出命令,要傳輸的數據必須位於配接器裝置對齊的緩衝區中。 DataBuffer 成員 SCSI_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

輸出緩衝區長度

SenseInfoLengthDataTransferLength 會更新,以指出傳輸的數據量。 埠驅動程式會傳回從裝置傳送到所提供快取對齊緩衝區的任何數據,DataBuffer

狀態區塊

Information 位元段會設定為 Irp->AssociatedIrp.SystemBuffer 輸出緩衝區中所傳回的位元組數目。 [狀態] 欄位會設定為 [STATUS_SUCCESS],或者,如果 SCSI_PASS_THROUGH_DIRECT 中的輸入 Length 值未正確設定,或 DataBuffer 中指定的緩衝區未正確對齊,則 [狀態] 字段會設定為 STATUS_BUFFER_TOO_SMALLSTATUS_SUCCESSSTATUS_INVALID_PARAMETER

言論

針對數據傳輸作業,需要符合配接器裝置的對齊方式緩衝區。 應用程式可以藉由發出具有 PropertyStandardQuery 查詢類型的 IOCTL_STORAGE_QUERY_PROPERTY 控件程序代碼要求,以及 storageAdapterProperty屬性標識符,以擷取裝置對齊遮罩。 對齊遮罩位於所傳回 STORAGE_ADAPTER_DESCRIPTOR 結構的 AlignmentMask 成員中。 驅動程式也可以使用 adapter DeviceObjectAlignmentMask 成員中的值。

在下列範例函式中,緩衝區會準備為裝置對齊的數據傳輸緩衝區。

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 (包括 Ntddscsi.h)

另請參閱

IOCTL_SCSI_PASS_THROUGH

IOCTL_STORAGE_QUERY_PROPERTY

SCSI_PASS_THROUGH_DIRECT