WdfRequestSend 函式 (wdfrequest.h)
[適用於 KMDF 和 UMDF]
WdfRequestSend 方法會將指定的 I/O 要求傳送至指定的 I/O 目標。
語法
BOOLEAN WdfRequestSend(
[in] WDFREQUEST Request,
[in] WDFIOTARGET Target,
PWDF_REQUEST_SEND_OPTIONS Options
);
參數
[in] Request
架構要求物件的句柄。
[in] Target
架構 I/O 目標物件的句柄。 如需如何取得此句柄的詳細資訊,請參閱下列一節。
Options
包含呼叫端提供要求選項 之WDF_REQUEST_SEND_OPTIONS 結構的指標。 此參數是選擇性的,如果您不想啟用任何要求選項,則可以是 NULL 。
傳回值
如果要求傳送至目標,WdfRequestSend 會傳回 TRUE。 否則,此方法會傳回 FALSE,而呼叫 WdfRequestGetStatus 會傳回失敗NT_SUCCESS () 测试的状态。
如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。
備註
驅動程式為 Request 參數指定的要求物件可以是它 收到的 物件,或是呼叫 WdfRequestCreate 方法所建立的要求物件。
若要取得 I/O 目標物件的句柄,驅動程式可以執行下列其中一項:
- 如果驅動程式使用一般 I/O 目標,它會呼叫 WdfDeviceGetIoTarget。 如需詳細資訊,請參閱 初始化一般 I/O 目標。
- 如果驅動程式使用特製化 I/O 目標,它會呼叫特製化目標物件所定義的一或多個方法。 例如,USB 裝置的驅動程式可以呼叫 WdfUsbTargetDeviceGetIoTarget 或 WdfUsbTargetPipeGetIoTarget。
如果 WdfRequestSend 失敗,或驅動程式設定WDF_REQUEST_SEND_OPTION_SYNCHRONOUS旗標,驅動程式可以在呼叫 WdfRequestSend 之後立即呼叫 WdfRequestGetStatus。
如果 WdfRequestSend 成功,而且您的驅動程式未設定WDF_REQUEST_SEND_OPTION_SYNCHRONOUS旗標,驅動程式通常會從 CompletionRoutine 回呼函式內呼叫 WdfRequestGetStatus。
如果驅動程式以同步方式傳送要求,建議驅動程式 在WDF_REQUEST_SEND_OPTIONS 結構中設定逾時值,以及此結構的 Flags 成員中的逾時旗標。
如果驅動程式提供逾時值,它應該先呼叫 WdfRequestAllocateTimer ,再呼叫 WdfRequestSend。 這可確保如果系統資源不足而無法配置定時器, WdfRequestSend 將不會失敗。
如果驅動程式設定 WDF_REQUEST_SEND_OPTION_SYNCHRONOUS 旗標,則必須在 IRQL = PASSIVE_LEVEL呼叫 WdfRequestSend 。 如果未設定此旗標,驅動程序必須在 IRQL <= DISPATCH_LEVEL呼叫此方法。 WdfRequestSend 會在呼叫端的 IRQL 傳送要求。
如果驅動程式已為管道設定連續讀取器,驅動程式就無法呼叫 WdfRequestSend 將 I/O 要求傳送至 USB 管道。
將要求傳送至 UMDF 驅動程式時,內核模式驅動程式必須遵循 UMDF 驅動程式中支援 Kernel-Mode 用戶端中所述的 IRQL 限制。
如需 WdfRequestSend 的詳細資訊,請參閱 轉送 I/O 要求。
範例
下列程式代碼範例是kmdf_fx2範例驅動程式中 EvtIoWrite 回呼函式的縮短版本。 函式會驗證要求的緩衝區長度、取得緩衝區的句柄、格式化 USB 目標的要求,以及傳送要求。
VOID
OsrFxEvtIoWrite(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
WDFUSBPIPE pipe;
NTSTATUS status;
WDFMEMORY reqMemory;
PDEVICE_CONTEXT pDeviceContext;
UNREFERENCED_PARAMETER(Queue);
//
// Check if the transfer size is valid.
//
if (Length > MAX_TRANSFER_BUFFER_SIZE) {
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
//
// Get driver-defined context space from
// the device object. The driver stored the
// pipe handle there.
//
pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
pipe = pDeviceContext->BulkWritePipe;
//
// Get a handle to a memory object that represents
// the input buffer.
//
status = WdfRequestRetrieveInputMemory(Request, &reqMemory);
if (!NT_SUCCESS(status)){
goto Exit;
}
//
// Format the request so it can be sent to a USB target.
//
status = WdfUsbTargetPipeFormatRequestForWrite(
pipe,
Request,
reqMemory,
NULL // Offsets
);
if (!NT_SUCCESS(status)) {
goto Exit;
}
//
// Set a CompletionRoutine callback function.
//
WdfRequestSetCompletionRoutine(
Request,
EvtRequestReadCompletionRoutine,
pipe
);
//
// Send the request. If an error occurs, complete the request.
//
if (WdfRequestSend(
Request,
WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(Request);
goto Exit;
}
Exit:
if (!NT_SUCCESS(status)) {
WdfRequestCompleteWithInformation(
Request,
status,
0
);
}
return;
}
規格需求
需求 | 值 |
---|---|
目標平台 | Universal |
最低 KMDF 版本 | 1.0 |
最低UMDF版本 | 2.0 |
標頭 | wdfrequest.h (包含 Wdf.h) |
程式庫 | Wdf01000.sys (KMDF) ;WUDFx02000.dll (UMDF) |
IRQL | 請參閱一節。 |
DDI 合規性規則 | DeferredRequestCompleted (kmdf) 、 DriverCreate (kmdf) 、 InvalidReqAccess (kmdf) 、 InvalidReqAccessLocal (kmdf ) 、 KmdfIrql (kmdf) 、 ReqCompletionRoutine (kmdf) 、 ReqMarkCancelableSend (kmdf) 、 ReqSendFail (kmdf) 、 ReqSendWhileSpinlock (kmdf ) 、 RequestCompleted (kmdf) 、 RequestCompletedLocal (kmdf) 、 RequestFormattedValid (kmdf) 、 RequestGetStatusValid (kmdf) 、 RequestSendAndForgetNoFormatting (kmdf) 、 RequestSendAndForgetNoFormatting2 (kmdf) , SyncReqSend2 (kmdf) , WdfRequestSendSyncAtDispatch (kmdf) , WdfRequestSendSyncAtDispatch2 (kmdf) |