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を返します。 それ以外の場合、このメソッドは次のいずれかの値を返す可能性があります。
リターン コード | 説明 |
---|---|
|
ドライバーは無効なハンドルを提供します。 |
|
FoundRequest パラメーターで識別される要求が I/O キューに見つかりません。 |
|
フレームワークは、検索条件に一致する要求を見つけずに I/O キューの末尾に達しました。 |
このメソッドは、他の NTSTATUS 値を返す場合もあります。
ドライバーが無効なオブジェクト ハンドルを提供すると、バグ チェックが発生します。
注釈
WdfIoQueueFindRequest メソッドは、指定された I/O キューを検索し、I/O 要求の検索を試みます。
ドライバーで WdfIoQueueFindRequest を呼び出すことができるのは、ドライバーが指定された I/O キューに対 して手動ディスパッチ メソッドを使用している 場合のみです。
FileObject が NULL でない場合、WdfIoQueueFindRequest は、指定されたファイル オブジェクト ハンドルに関連付けられている要求のみを調べます。
FoundRequest が NULL の場合、このメソッドは FileObject 値に一致する I/O キュー内の最初の要求を検索します。 FoundRequest が NULL でない場合、メソッドは FoundRequest によって識別される要求で検索を開始します。 反復ループを作成するには、最初の呼び出しに NULL を 指定し、返されたハンドルを後続の呼び出しの FoundRequest パラメーターとして使用します。
Parameters が NULL でない場合、このメソッドは検出された要求のパラメーターをドライバー指定の構造体にコピーします。
STATUS_SUCCESSを返す WdfIoQueueFindRequest を呼び出すたびに、 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
次のコード例は、検索固有のサブルーチンを呼び出す汎用検索ルーチンを作成する方法を示しています。 ドライバーで 1 つ以上のキューで複数の種類の情報を検索する必要がある場合は、複数の検索固有のサブルーチンを指定できます。 ドライバーが汎用検索ルーチンを呼び出すたびに、検索固有のサブルーチンの 1 つのアドレスが指定されます。
//
// 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.
//
...
}
...
要件
要件 | 値 |
---|---|
対象プラットフォーム | ユニバーサル |
最小 KMDF バージョン | 1.0 |
最小 UMDF バージョン | 2.0 |
Header | wdfio.h (Wdf.h を含む) |
Library | 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) |