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を返します。 それ以外の場合、このメソッドは次のいずれかの値を返す可能性があります。

リターン コード 説明
STATUS_INVALID_PARAMETER
ドライバーは無効なハンドルを提供します。
STATUS_NOT_FOUND
FoundRequest パラメーターで識別される要求が I/O キューに見つかりません。
STATUS_NO_MORE_ENTRIES
フレームワークは、検索条件に一致する要求を見つけずに I/O キューの末尾に達しました。
 

このメソッドは、他の NTSTATUS 値を返す場合もあります。

ドライバーが無効なオブジェクト ハンドルを提供すると、バグ チェックが発生します。

注釈

WdfIoQueueFindRequest メソッドは、指定された I/O キューを検索し、I/O 要求の検索を試みます。

ドライバーで WdfIoQueueFindRequest を呼び出すことができるのは、ドライバーが指定された I/O キューに対 して手動ディスパッチ メソッドを使用している 場合のみです。

FileObjectNULL でない場合、WdfIoQueueFindRequest は、指定されたファイル オブジェクト ハンドルに関連付けられている要求のみを調べます。

FoundRequestNULL の場合、このメソッドは FileObject 値に一致する I/O キュー内の最初の要求を検索します。 FoundRequestNULL でない場合、メソッドは FoundRequest によって識別される要求で検索を開始します。 反復ループを作成するには、最初の呼び出しに NULL を 指定し、返されたハンドルを後続の呼び出しの FoundRequest パラメーターとして使用します。

ParametersNULL でない場合、このメソッドは検出された要求のパラメーターをドライバー指定の構造体にコピーします。

STATUS_SUCCESSを返す WdfIoQueueFindRequest を呼び出すたびに、 OutRequest でハンドルが返される要求オブジェクトの参照カウントがインクリメントされます。 そのため、ハンドルの使用が完了した後、ドライバーは WdfObjectDereference を呼び出す必要があります。

WdfIoQueueFindRequest を呼び出しても、要求のドライバー所有権は付与されません。 要求を処理できるようにドライバーが要求の所有権を取得する場合、ドライバーは WdfIoQueueRetrieveFoundRequest を呼び出す必要があります。 実際、ドライバーは OutRequest パラメーターに対して受け取るハンドルを使用して、次の操作のみを実行できます。

  • WdfIoQueueFindRequest への後続の呼び出しで FoundRequest パラメーターとして使用します。
  • WdfIoQueueRetrieveFoundRequest の後続の呼び出しで FoundRequest パラメーターとして使用します。
  • WdfObjectGetTypedContext の後続の呼び出し、またはオブジェクトのコンテキスト空間にアクセスするためのドライバー定義メソッドの入力パラメーターとして使用します。
  • WdfObjectDereference への入力パラメーターとして使用します。
WdfIoQueueFindRequest の呼び出しがSTATUS_NOT_FOUNDを返した場合、キュー内の以前の要求は削除されています。 要求が取り消された可能性があります。 WdfIoQueueRetrieveFoundRequest を呼び出すと、STATUS_NOT_FOUNDを返すこともできます。

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(&params);
 
    *Request = NULL;
    prevTagRequest = tagRequest = NULL;

    do {
        WDF_REQUEST_PARAMETERS_INIT(&params);
        status = WdfIoQueueFindRequest(
                                       Queue,
                                       prevTagRequest,
                                       NULL,
                                       &params,
                                       &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)

こちらもご覧ください

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop

WdfObjectDereference