Fungsi WdfIoQueueFindRequest (wdfio.h)

[Berlaku untuk KMDF dan UMDF]

Metode WdfIoQueueFindRequest menemukan permintaan berikutnya dalam antrean I/O, atau permintaan berikutnya yang cocok dengan kriteria yang ditentukan, tetapi tidak memberikan kepemilikan permintaan kepada driver.

Sintaks

NTSTATUS WdfIoQueueFindRequest(
  [in]           WDFQUEUE                Queue,
  [in, optional] WDFREQUEST              FoundRequest,
  [in, optional] WDFFILEOBJECT           FileObject,
  [in, out]      PWDF_REQUEST_PARAMETERS Parameters,
  [out]          WDFREQUEST              *OutRequest
);

Parameter

[in] Queue

Handel ke objek antrean kerangka kerja.

[in, optional] FoundRequest

Penanganan objek permintaan yang diterima driver dari panggilan sebelumnya ke WdfIoQueueFindRequest. Parameter ini bersifat opsional dan dapat berupa NULL.

[in, optional] FileObject

Handel ke objek file kerangka kerja. Parameter ini bersifat opsional dan dapat berupa NULL.

[in, out] Parameters

Pointer ke struktur WDF_REQUEST_PARAMETERS yang dialokasikan driver yang menerima parameter yang terkait dengan permintaan yang ditemukan. Parameter ini bersifat opsional dan dapat berupa NULL.

[out] OutRequest

Penunjuk ke lokasi yang menerima handel ke permintaan yang ditemukan. Jika tidak ada kecocokan yang ditemukan, lokasi akan menerima NULL.

Nilai kembali

WdfIoQueueFindRequest mengembalikan STATUS_SUCCESS jika operasi berhasil. Jika tidak, metode ini mungkin mengembalikan salah satu nilai berikut:

Menampilkan kode Deskripsi
STATUS_INVALID_PARAMETER
Driver menyediakan handel yang tidak valid.
STATUS_NOT_FOUND
Permintaan yang diidentifikasi oleh parameter FoundRequest tidak dapat ditemukan dalam antrean I/O.
STATUS_NO_MORE_ENTRIES
Kerangka kerja mencapai akhir antrean I/O tanpa menemukan permintaan yang cocok dengan kriteria pencarian.
 

Metode ini juga dapat mengembalikan nilai NTSTATUS lainnya.

Pemeriksaan bug terjadi jika driver menyediakan handel objek yang tidak valid.

Keterangan

Metode WdfIoQueueFindRequest mencari antrean I/O tertentu dan mencoba menemukan permintaan I/O.

Driver Anda dapat memanggil WdfIoQueueFindRequest hanya jika driver menggunakan metode pengiriman manual untuk antrean I/O yang ditentukan.

Jika FileObject bukan NULL, WdfIoQueueFindRequest hanya memeriksa permintaan yang terkait dengan handel objek file yang ditentukan.

Jika FoundRequest adalah NULL, metode ini menemukan permintaan pertama dalam antrean I/O yang cocok dengan nilai FileObject . Jika FoundRequest bukan NULL, metode mulai mencari pada permintaan yang diidentifikasi oleh FoundRequest. Untuk membuat perulangan berulang, tentukan NULL untuk panggilan pertama, lalu gunakan handel yang dikembalikan sebagai parameter FoundRequest untuk panggilan berikutnya.

Jika Parameter bukan NULL, metode ini menyalin parameter permintaan yang ditemukan ke dalam struktur yang disediakan driver.

Setiap panggilan ke WdfIoQueueFindRequest yang mengembalikan STATUS_SUCCESS menaikkan jumlah referensi objek permintaan yang handelnya dikembalikan di OutRequest. Oleh karena itu, driver Anda harus memanggil WdfObjectDereference setelah Anda selesai menggunakan handel.

Memanggil WdfIoQueueFindRequesttidak memberikan kepemilikan driver atas permintaan apa pun. Jika Anda ingin driver Anda mendapatkan kepemilikan permintaan sehingga dapat memproses permintaan, driver harus memanggil WdfIoQueueRetrieveFoundRequest. Bahkan, driver hanya dapat melakukan hal berikut dengan handel yang diterimanya untuk parameter OutRequest :

Jika panggilan ke WdfIoQueueFindRequest mengembalikan STATUS_NOT_FOUND, permintaan yang sebelumnya ada dalam antrean telah dihapus. Permintaan mungkin telah dibatalkan. Panggilan ke WdfIoQueueRetrieveFoundRequest juga dapat mengembalikan STATUS_NOT_FOUND.

Untuk informasi selengkapnya tentang metode WdfIoQueueFindRequest , lihat Mengelola Antrean I/O.

Contoh

Contoh 1

Contoh kode berikut berasal dari driver sampel PCIDRV . Contoh ini mencari antrean I/O untuk permintaan yang berisi kode fungsi I/O tertentu. Jika permintaan yang cocok ditemukan, contoh memanggil 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;

}

Contoh 2

Contoh kode berikut menunjukkan bagaimana Anda dapat membuat rutinitas pencarian tujuan umum yang memanggil subroutine khusus pencarian. Jika driver Anda harus mencari satu atau beberapa antrean untuk beberapa jenis informasi, Anda dapat menyediakan beberapa subrutin khusus pencarian. Setiap kali driver Anda memanggil rutinitas pencarian tujuan umum, driver menentukan alamat salah satu subroutine khusus pencarian Anda.

//
// 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.
    //
...
}
... 

Persyaratan

Persyaratan Nilai
Target Platform Universal
Versi KMDF minimum 1,0
Versi UMDF minimum 2.0
Header wdfio.h (termasuk Wdf.h)
Pustaka Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
Aturan kepatuhan DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), wdfioqueuefindrequestfailed, WdfIoQueueFindRequestFailed(kmdf), wdfioqueueretrievefoundrequest, WdfIoQueueRetrieveFoundRequest(kmdf), wdfioqueueretrievenextrequest, WdfIoQueueRetrieveNextRequest(kmdf)

Lihat juga

WDF_REQUEST_PARAMETERS

WdfIoQueueRetrieveFoundRequest

WdfIoQueueStop

WdfObjectDereference