WdfIoQueueFindRequest 函式 (wdfio.h)
[適用於 KMDF 和 UMDF]
WdfIoQueueFindRequest 方法會在 I/O 佇列中找出下一個要求,或符合指定準則的下一個要求,但不會將要求的擁有權授與驅動程式。
語法
NTSTATUS WdfIoQueueFindRequest(
[in] WDFQUEUE Queue,
[in, optional] WDFREQUEST FoundRequest,
[in, optional] WDFFILEOBJECT FileObject,
[in, out] PWDF_REQUEST_PARAMETERS Parameters,
[out] WDFREQUEST *OutRequest
);
參數
[in] Queue
架構佇列物件的句柄。
[in, optional] FoundRequest
驅動程式從先前呼叫 WdfIoQueueFindRequest 收到的要求物件句柄。 此參數是選擇性的,可以是 NULL。
[in, optional] FileObject
架構檔案物件的句柄。 此參數是選擇性的,可以是 NULL。
[in, out] Parameters
驅動程式配置的 WDF_REQUEST_PARAMETERS 結構的指標,可接收與找到要求相關聯的參數。 此參數是選擇性的,可以是 NULL。
[out] OutRequest
接收所找到要求句柄之位置的指標。 如果找不到相符專案,則位置會收到 NULL。
傳回值
如果作業成功,WdfIoQueueFindRequest 會傳回STATUS_SUCCESS。 否則,此方法可能會傳回下列其中一個值:
傳回碼 | Description |
---|---|
|
驅動程式提供無效的句柄。 |
|
在 I/O 佇列中找不到 FoundRequest 參數所識別的要求。 |
|
架構到達 I/O 佇列的結尾,但找不到符合搜尋準則的要求。 |
這個方法也可能傳回其他 NTSTATUS值。
如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。
備註
WdfIoQueueFindRequest 方法會搜尋指定的 I/O 佇列,並嘗試尋找 I/O 要求。
只有在驅動程式使用指定 I/O 佇列的手動分派方法時,您的驅動程式才能呼叫 WdfIoQueueFindRequest。
如果 FileObject 不是 NULL,WdfIoQueueFindRequest 只會檢查與指定之檔案物件句柄相關聯的要求。
如果 FoundRequest 為 NULL,這個方法會在符合 FileObject 值的 I/O 佇列中找出第一個要求。 如果 FoundRequest 不是 NULL,則方法會開始搜尋 FoundRequest 所識別的要求。 若要建立反覆迴圈,請為第一次呼叫指定 NULL ,然後使用傳回的句柄作為後續呼叫的 FoundRequest 參數。
如果 Parameters 不是 NULL,這個方法會將找到的要求參數複製到驅動程式提供的結構中。
每個對 WdfIoQueueFindRequest 的呼叫都會傳回STATUS_SUCCESS遞增在 OutRequest 中傳回其句柄的要求對象的參考計數。 因此,您的驅動程式在使用句柄完成之後,必須呼叫 WdfObjectDereference 。
呼叫 WdfIoQueueFindRequest不會 授與任何要求的驅動程式 擁有權 。 如果您想要讓驅動程式取得要求的擁有權,以便處理要求,驅動程序必須呼叫 WdfIoQueueRetrieveFoundRequest。 事實上,驅動程式只能針對 OutRequest 參數接收的句柄執行下列動作:
- 在後續呼叫 WdfIoQueueFindRequest 時,使用它作為 FoundRequest 參數。
- 在後續呼叫 WdfIoQueueRetrieveFoundRequest 時,使用它作為 FoundRequest 參數。
- 使用它作為 後續呼叫 WdfObjectGetTypedContext 的輸入參數,或用來存取物件 內容空間的驅動程式定義方法。
- 使用它作為 WdfObjectDereference 的輸入參數。
如需 WdfIoQueueFindRequest 方法的詳細資訊,請參閱 管理 I/O 佇列。
範例
範例 1
下列程式代碼範例來自 PCIDRV 範例驅動程式。 此範例會搜尋 I/O 佇列中含有指定 I/O 函式程式碼的要求。 如果找到相符的要求,此範例會呼叫 WdfIoQueueRetrieveFoundRequest。
NTSTATUS
NICGetIoctlRequest(
IN WDFQUEUE Queue,
IN ULONG FunctionCode,
OUT WDFREQUEST* Request
)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
WDF_REQUEST_PARAMETERS params;
WDFREQUEST tagRequest;
WDFREQUEST prevTagRequest;
WDF_REQUEST_PARAMETERS_INIT(¶ms);
*Request = NULL;
prevTagRequest = tagRequest = NULL;
do {
WDF_REQUEST_PARAMETERS_INIT(¶ms);
status = WdfIoQueueFindRequest(
Queue,
prevTagRequest,
NULL,
¶ms,
&tagRequest
);
if (prevTagRequest) {
WdfObjectDereference(prevTagRequest);
}
if (status == STATUS_NO_MORE_ENTRIES) {
status = STATUS_UNSUCCESSFUL;
break;
}
if (status == STATUS_NOT_FOUND) {
//
// The prevTagRequest request has disappeared from the
// queue. There might be other requests that match
// the criteria, so restart the search.
//
prevTagRequest = tagRequest = NULL;
continue;
}
if (!NT_SUCCESS(status)) {
status = STATUS_UNSUCCESSFUL;
break;
}
if (FunctionCode == params.Parameters.DeviceIoControl.IoControlCode){
//
// Found a match. Retrieve the request from the queue.
//
status = WdfIoQueueRetrieveFoundRequest(
Queue,
tagRequest,
Request
);
WdfObjectDereference(tagRequest);
if (status == STATUS_NOT_FOUND) {
//
// The tagRequest request has disappeared from the
// queue. There might be other requests that match
// the criteria, so restart the search.
//
prevTagRequest = tagRequest = NULL;
continue;
}
if (!NT_SUCCESS(status)) {
status = STATUS_UNSUCCESSFUL;
break;
}
//
// Found a request.
//
ASSERT(*Request == tagRequest);
status = STATUS_SUCCESS;
break;
} else {
//
// This request is not the correct one. Drop the reference
// on the tagRequest after the driver obtains the next request.
//
prevTagRequest = tagRequest;
continue;
}
} while (TRUE);
return status;
}
範例 2
下列程式代碼範例示範如何建立呼叫搜尋特定子程式的一般用途搜尋例程。 如果您的驅動程式必須搜尋一或多個佇列以取得多種資訊類型,您可以提供多個搜尋特定的子程式。 每次驅動程式呼叫一般用途搜尋例程時,都會指定其中一個搜尋特定子程序的位址。
//
// Type declaration for the driver's search-specific subroutines.
//
typedef BOOLEAN (*PFN_CALLBACK_COMPARE)(WDFREQUEST, ULONG);
//
// General-purpose search routine. One of the routine's
// parameters is the address of a search-specific
// subroutine. The search routine calls back to the
// subroutine.
//
WDFREQUEST
FindRequestWithMatchingData(
__in WDFQUEUE Queue,
__in PFN_CALLBACK_COMPARE CallbackCompare,
__in ULONG Data
)
{
WDFREQUEST prevTagRequest = NULL;
WDFREQUEST tagRequest = NULL;
WDFREQUEST outRequest = NULL;
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PAGED_CODE();
do {
status = WdfIoQueueFindRequest(Queue,
prevTagRequest,
NULL,
NULL,
&tagRequest);
if (prevTagRequest) {
//
// WdfIoQueueFindRequest incremented the
// reference count of the prevTagRequest object,
// so we decrement the count here.
//
WdfObjectDereference(prevTagRequest);
}
if (status == STATUS_NO_MORE_ENTRIES) {
KdPrint(("WdfIoQueueFindRequest returned status 0x%x\n", status));
break;
}
if (status == STATUS_NOT_FOUND) {
//
// The prevTagRequest object is no longer
// in the queue.
//
prevTagRequest = tagRequest = NULL;
continue;
}
if ( !NT_SUCCESS(status)) {
KdPrint(("WdfIoQueueFindRequest failed 0x%x\n", status));
break;
}
//
// We have a handle to the next request that is
// in the queue. Now we call the subroutine
// that determines if this request matches our
// search criteria.
//
if (CallbackCompare(tagRequest, Data)) {
//
// We found a match. Get the request handle.
//
status = WdfIoQueueRetrieveFoundRequest(Queue,
tagRequest,
&outRequest);
//
// WdfIoQueueRetrieveFoundRequest incremented the
// reference count of the TagRequest object,
// so we decrement the count here.
//
WdfObjectDereference(tagRequest);
if (status == STATUS_NOT_FOUND) {
//
// The TagRequest object is no longer
// in the queue. But other requests might
// match our criteria, so we restart the search.
//
prevTagRequest = tagRequest = NULL;
continue;
}
if (!NT_SUCCESS(status)) {
KdPrint(("WdfIoQueueRetrieveFoundRequest failed 0x%x\n",
status));
}
//
// We found the request we were looking for.
//
break;
} else {
//
// The request did not match our criteria.
// Get another request.
//
prevTagRequest = tagRequest;
continue;
}
} while(TRUE);
return outRequest;
}
/
// An example of a driver's search-specific subroutine.
// Your driver can have multiple subroutines to handle
// multiple types of searches.
//
BOOLEAN
CallbackCheckForInfo1(
__in WDFREQUEST Request,
__in ULONG DataToBeMatched
)
{
PREQUEST_CONTEXT reqContext;
PAGED_CODE();
//
// Retrieve information that the driver has stored
// in the request object's context space.
//
reqContext = GetRequestContext(Request);
if (reqContext->ContextInfo1 == DataToBeMatched) {
return TRUE;
}
else {
return FALSE;
}
}
//
// This code shows a call to the FindRequestWithMatchingData routine.
//
WDFREQUEST matchedRequest = NULL;
...
matchedRequest = FindRequestWithMatchingData(readQueue,
CallbackCheckForInfo1,
INFO_VALUE);
if (matchedRequest != NULL) {
//
// Found a request with a context value of INFO_VALIUE.
//
...
}
...
規格需求
需求 | 值 |
---|---|
目標平台 | Universal |
最小 KMDF 版本 | 1.0 |
最低UMDF版本 | 2.0 |
標頭 | wdfio.h (包含 Wdf.h) |
程式庫 | Wdf01000.sys (KMDF) ;WUDFx02000.dll (UMDF) |
IRQL | <= DISPATCH_LEVEL |
DDI 合規性規則 | DriverCreate (kmdf) , KmdfIrql (kmdf) , KmdfIrql2 (kmdf) , KmdfIrqlExplicit (kmdf) , wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed (kmdf) , wdfioqueueretrievefoundrequest, WdfIoQueueRetrieveFoundRequest (kmdf) , wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest (kmdf) |