다음을 통해 공유


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_NOT_FOUND
FoundRequest 매개 변수로 식별되는 요청은 I/O 큐에서 찾을 수 없습니다.
STATUS_NO_MORE_ENTRIES
프레임워크가 검색 조건과 일치하는 요청을 찾지 않고 I/O 큐의 끝에 도달했습니다.
 

이 메서드는 다른NTSTATUS 값을 반환할 수도 있습니다.

드라이버에서 잘못된 개체 핸들을 제공하면 버그 검사가 수행됩니다.

비고

WdfIoQueueFindRequest 메서드는 지정된 I/O 큐를 검색하고 I/O 요청을 찾으려고 시도합니다.

드라이버는 지정된 I/O 큐에 대한 수동 디스패치 메서드 사용하는 경우에만 WdfIoQueueFindRequest 호출할 수 있습니다.

FileObject NULL 않으면 WdfIoQueueFindRequest 지정된 파일 개체 핸들과 연결된 요청만 검사합니다.

FoundRequest NULL 경우 이 메서드는 FileObject 값과 일치하는 첫 번째 요청을 I/O 큐에서 찾습니다. FoundRequest NULL 않으면 메서드는 FoundRequest의해 식별되는 요청에서 검색을 시작합니다. 반복 루프를 만들려면 첫 번째 호출에 NULL 지정한 다음 반환된 핸들을 후속 호출에 대한 FoundRequest 매개 변수로 사용합니다.

매개 변수 NULL 않으면 이 메서드는 찾은 요청의 매개 변수를 드라이버 제공 구조에 복사합니다.

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

다음 코드 예제에서는 검색 특정 서브루틴을 호출하는 범용 검색 루틴을 만드는 방법을 보여줍니다. 드라이버가 여러 유형의 정보를 위해 하나 이상의 큐를 검색해야 하는 경우 여러 검색 특정 하위 루틴을 제공할 수 있습니다. 드라이버가 범용 검색 루틴을 호출할 때마다 검색 특정 하위 경로 중 하나의 주소를 지정합니다.

//
// 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
헤더 wdfio.h(Wdf.h 포함)
라이브러리 Wdf01000.sys(KMDF); WUDFx02000.dll(UMDF)
IRQL <= 디스패치_레벨
DDI 규정 준수 규칙 DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed(kmdf), wdfioqueueretrievevefoundrequest, WdfIoQueueRetrieveFoundRequest(kmdf), wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest(kmdf)

참고하십시오

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop

WdfObjectDereference