共用方式為


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 迷你埠 驅動程式模型。
 

主要程序代碼

IRP_MJ_DEVICE_CONTROL

輸入緩衝區

此結構包含 SCSI CDB,呼叫端必須初始化,但埠驅動程式填入的路徑、目標標識碼和 LUN 除外。 如果是數據輸出命令,要傳輸的數據必須位於配接器裝置對齊緩衝區中。 SCSI_PASS_THROUGH_DIRECT的 DataBuffer 成員是此配接器裝置對齊緩衝區的指標。 如果呼叫端要求要求感知數據,則呼叫端必須遵循 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 上提供的快取對齊緩衝區。

狀態區塊

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

備註

對於數據傳輸作業,需要符合配接器裝置對齊方式的緩衝區。 應用程式可以使用 StorageAdapterProperty 的查詢類型發出IOCTL_STORAGE_QUERY_PROPERTY控件程式代碼要求,以擷取裝置對齊遮罩。 對齊遮罩位於傳回之STORAGE_ADAPTER_DESCRIPTOR結構的AlignmentMask成員中。 驅動程式也可以使用配接器 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