WdfRequestProbeAndLockUserBufferForRead 函式 (wdfrequest.h)

[僅適用於 KMDF]

WdfRequestProbeAndLockUserBufferForRead 方法會驗證 I/O 要求的使用者模式緩衝區是可讀取的,然後它會鎖定緩衝區的實體記憶體頁面,讓驅動程式堆棧中的驅動程式可以讀取緩衝區。

語法

NTSTATUS WdfRequestProbeAndLockUserBufferForRead(
  [in]  WDFREQUEST Request,
  [in]  PVOID      Buffer,
  [in]  size_t     Length,
  [out] WDFMEMORY  *MemoryObject
);

參數

[in] Request

架構要求物件的句柄。

[in] Buffer

要求輸入緩衝區的指標。 如需詳細資訊,請參閱接下來的<備註>一節。

[in] Length

要求的輸入緩衝區長度,以位元組為單位。

[out] MemoryObject

接收架構記憶體物件句柄的位置指標,表示使用者輸入緩衝區。

傳回值

WdfRequestProbeAndLockUserBufferForRead 會在作業成功時傳回STATUS_SUCCESS。 否則,此方法可能會傳回下列其中一個值:

傳回碼 Description
STATUS_INVALID_PARAMETER
輸入參數無效。
STATUS_INVALID_USER_BUFFER
Length 參數為零。
STATUS_INVALID_DEVICE_REQUEST
要求已經完成或無效。
STATUS_ACCESS_VIOLATION
目前的線程不是 I/O 要求的建立者。
STATUS_INSUFFICIENT_RESOURCES
記憶體不足,無法完成作業。
 

這個方法也可能傳回其他 NTSTATUS值

如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。

備註

只有最上層驅動程式可以呼叫 WdfRequestProbeAndLockUserBufferForRead 方法,因為方法需要建立 I/O 要求之進程的進程內容。

使用者輸入緩衝區通常包含要寫入裝置的資訊。

Buffer 參數指定的使用者模式緩衝區可以是 WdfRequestRetrieveUnsafeUserInputBuffer 擷取的緩衝區,或者它可以是不同的使用者模式輸入緩衝區。 例如,使用緩衝存取方法的 I/O 控制項程式代碼可能會傳遞包含使用者模式緩衝區內嵌指標的結構。 在這種情況下,驅動程式可以使用WdfRequestProbeAndLockUserBufferForRead 來取得緩衝區的記憶體物件。

Length 參數指定的緩衝區長度不能大於緩衝區的實際大小。 否則,驅動程式可以在緩衝區外部存取記憶體,這是安全性風險。

如果 WdfRequestProbeAndLockUserBufferForRead 傳回STATUS_SUCCESS,驅動程式會接收代表使用者模式緩衝區的架構記憶體物件的句柄。 若要存取緩衝區,驅動程式必須呼叫 WdfMemoryGetBuffer

驅動程式呼叫 WdfRequestComplete 時,會自動釋放架構記憶體物件。

如需 WdfRequestProbeAndLockUserBufferForRead 的詳細資訊,請參閱 存取 Framework-Based 驅動程式中的數據緩衝區

範例

下列程式代碼範例是 NONPNP 範例驅動程式包含的 EvtIoInCallerContext 回呼函式的縮短版本。 當回呼函式收到 I/O 要求時,它會判斷要求是否包含具有METHOD_NEITHER傳輸類型的 I/O 控制項程式碼。 如果要求確實包含這類 I/O 控制項程式碼,則函式:

  1. 呼叫 WdfRequestRetrieveUnsafeUserInputBufferWdfRequestRetrieveUnsafeUserOutputBuffer ,以取得要求的讀取和寫入緩衝區虛擬位址。
  2. 呼叫 WdfRequestProbeAndLockUserBufferForReadWdfRequestProbeAndLockUserBufferForWrite 來探查和鎖定緩衝區,並取得代表每個緩衝區的架構記憶體物件的句柄。
VOID
NonPnpEvtIoInCallerContext(
    IN WDFDEVICE  Device,
    IN WDFREQUEST Request
    )
{
    NTSTATUS  status = STATUS_SUCCESS;
    PREQUEST_CONTEXT  reqContext = NULL;
    WDF_OBJECT_ATTRIBUTES  attributes;
    WDF_REQUEST_PARAMETERS  params;
    size_t  inBufLen, outBufLen;
    PVOID  inBuf, outBuf;

    WDF_REQUEST_PARAMETERS_INIT(&params);
    WdfRequestGetParameters(
                            Request,
                            &params
                            );

    //
    // Check to see whether the driver received a METHOD_NEITHER I/O control code.
    // If not, just send the request back to the framework.
    //
    if(!(params.Type == WdfRequestTypeDeviceControl &&
            params.Parameters.DeviceIoControl.IoControlCode ==
                                    IOCTL_NONPNP_METHOD_NEITHER)) {
        status = WdfDeviceEnqueueRequest(
                                         Device,
                                         Request
                                         );
        if( !NT_SUCCESS(status) ) {
            goto End;
        }
        return;
    }

    //
    // The I/O control code is METHOD_NEITHER.
    // First, retrieve the virtual addresses of 
    // the input and output buffers.
    //
    status = WdfRequestRetrieveUnsafeUserInputBuffer(
                                                     Request,
                                                     0,
                                                     &inBuf,
                                                     &inBufLen
                                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }
    status = WdfRequestRetrieveUnsafeUserOutputBuffer(
                                                      Request,
                                                      0,
                                                      &outBuf,
                                                      &outBufLen
                                                      );
    if(!NT_SUCCESS(status)) {
       goto End;
    }

    //
    // Next, allocate context space for the request, so that the
    // driver can store handles to the memory objects that will
    // be created for input and output buffers.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes,
                                        REQUEST_CONTEXT);
    status = WdfObjectAllocateContext(
                                      Request,
                                      &attributes,
                                      &reqContext
                                      );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    //
    // Next, probe and lock the read and write buffers.
    //
    status = WdfRequestProbeAndLockUserBufferForRead(
                                                     Request,
                                                     inBuf,
                                                     inBufLen,
                                                     &reqContext->InputMemoryBuffer
                                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    status = WdfRequestProbeAndLockUserBufferForWrite(
                                                      Request,
                                                      outBuf,
                                                      outBufLen,
                                                      &reqContext->OutputMemoryBuffer
                                                      );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    //
    // Finally, return the request to the framework.
    //
    status = WdfDeviceEnqueueRequest(
                                     Device,
                                     Request
                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }
    return;

End:
    WdfRequestComplete(
                       Request,
                       status
                       );
    return;
}

規格需求

需求
目標平台 Universal
最小 KMDF 版本 1.0
標頭 wdfrequest.h (包含 Wdf.h)
程式庫 Wdf01000.sys (請參閱 Framework Library Versioning.)
IRQL PASSIVE_LEVEL
DDI 合規性規則 DriverCreate (kmdf) InvalidReqAccess (kmdf ) , InvalidReqAccessLocal (kmdf ) , KmdfIrql (kmdf) KmdfIrql2 (kmdf) , KmdfIrqlExplicit (kmdf)

另請參閱

WdfMemoryGetBuffer

WdfRequestProbeAndLockUserBufferForWrite

WdfRequestRetrieveUnsafeUserInputBuffer