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 요청을 찾으려고 시도합니다.
드라이버가 지정된 I/O 큐에 수동 디스패치 메서드를 사용하는 경우에만 드라이버가 WdfIoQueueFindRequest를 호출할 수 있습니다.
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
다음 코드 예제에서는 검색 특정 서브루틴을 호출하는 범용 검색 루틴을 만드는 방법을 보여줍니다. 드라이버가 여러 유형의 정보를 위해 하나 이상의 큐를 검색해야 하는 경우 여러 검색 관련 하위 경로를 제공할 수 있습니다. 드라이버가 범용 검색 루틴을 호출할 때마다 검색 특정 하위 경로 중 하나의 주소를 지정합니다.
//
// 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 | <= DISPATCH_LEVEL |
DDI 규정 준수 규칙 | DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed(kmdf), wdfioqueueretrievevefoundrequest, WdfIoQueueRetrieveFoundRequest(kmdf), wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest(kmdf) |