Bagikan melalui


Fungsi WdfDeviceInitAssignWdmIrpPreprocessCallback (wdfdevice.h)

[Hanya berlaku untuk KMDF]

Metode WdfDeviceInitAssignWdmIrpPreprocessCallback mendaftarkan fungsi panggilan balik untuk menangani kode fungsi utama IRP dan, secara opsional, satu atau beberapa kode fungsi minor yang terkait dengan kode fungsi utama.

Sintaks

NTSTATUS WdfDeviceInitAssignWdmIrpPreprocessCallback(
  [in]           PWDFDEVICE_INIT                  DeviceInit,
  [in]           PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmIrpPreprocess,
  [in]           UCHAR                            MajorFunction,
  [in, optional] PUCHAR                           MinorFunctions,
  [in]           ULONG                            NumMinorFunctions
);

Parameter

[in] DeviceInit

Penunjuk ke struktur WDFDEVICE_INIT .

[in] EvtDeviceWdmIrpPreprocess

Penunjuk ke fungsi panggilan balik EvtDeviceWdmIrpPreprocess driver.

[in] MajorFunction

Salah satu kode fungsi utama IRP yang didefinisikan dalam wdm.h.

[in, optional] MinorFunctions

Penunjuk ke array dari satu atau beberapa kode fungsi minor IRP yang terkait dengan kode fungsi utama yang ditentukan. Parameter ini bersifat opsional dan dapat berupa NULL. Untuk informasi selengkapnya, lihat bagian Keterangan berikut ini.

[in] NumMinorFunctions

Jumlah kode fungsi minor yang terkandung dalam array MinorFunctions .

Nilai kembali

Jika operasi berhasil, metode mengembalikan STATUS_SUCCESS. Nilai pengembalian tambahan meliputi:

Menampilkan kode Deskripsi
STATUS_INVALID_PARAMETER
Nilai MajorFunction tidak valid.
STATUS_INSUFFICIENT_RESOURCES
Memori tidak cukup.
STATUS_INVALID_DEVICE_REQUEST
Driver sebelumnya mendaftarkan array MinorFunctions untuk fungsi utama ini dan mencoba menentukan fungsi minor lagi untuk kode MajorFunction yang ditentukan.
 

Metode ini mungkin mengembalikan nilai NTSTATUS lainnya.

Keterangan

Driver dapat memanggil metode WdfDeviceInitAssignWdmIrpPreprocessCallback karena salah satu dari dua alasan:

  • Untuk menangani kode fungsi utama atau minor IRP yang tidak didukung kerangka kerja.

    Misalnya, kerangka kerja tidak mendukung IRP_MJ_FLUSH_BUFFERS. Jika driver Anda harus mendukung IRP ini, driver harus mendaftarkan fungsi panggilan balik EvtDeviceWdmIrpPreprocess yang menangani IRP. Driver harus mengikuti aturan WDM untuk memproses RUNPS.

  • Untuk melakukan praprosces IRP sebelum kerangka kerja menanganinya.

    Dalam kasus yang jarang terjadi, mungkin perlu bagi driver untuk memproses IRP sebelum kerangka kerja memprosesnya. Dalam kasus seperti itu, fungsi panggilan balik EvtDeviceWdmIrpPreprocess driver dapat memproses IRP dan kemudian memanggil WdfDeviceWdmDispatchPreprocessedIrp untuk mengembalikan IRP ke kerangka kerja. Bergantung pada kode fungsi IRP, kerangka kerja mungkin memproses IRP itu sendiri atau mungkin mengirimkan IRP ke driver lagi dalam objek permintaan kerangka kerja.

Kerangka kerja memanggil fungsi panggilan balik EvtDeviceWdmIrpPreprocess setiap kali menerima paket permintaan I/O (IRP) yang berisi kode fungsi utama IRP yang cocok dengan parameter MajorFunction dan kode fungsi minor yang cocok dengan salah satu kode fungsi minor yang ada di array MinorFunctions .

Jika penunjuk array MinorFunctions adalah NULL, kerangka kerja memanggil fungsi panggilan balik untuk semua kode fungsi minor yang terkait dengan kode fungsi utama yang ditentukan. Jika penunjuk array MinorFunctions bukan NULL, kerangka kerja membuat salinan array sehingga driver tidak harus menyimpan array secara permanen.

Jika driver menerima penunjuk DeviceInit dari WdfPdoInitAllocate atau fungsi panggilan balik peristiwa EvtChildListCreateDevice , fungsi panggilan balik EvtDeviceWdmIrpPreprocess driver tidak dapat mengatur rutinitas penyelesaian untuk RUNPS yang berisi kode fungsi utama IRP_MJ_PNP. Jika tidak, Pemverifikasi Driver akan melaporkan kesalahan.

Jika driver Anda memanggil WdfDeviceInitAssignWdmIrpPreprocessCallback satu atau beberapa kali, kerangka kerja akan menaikkan anggota StackSize dari struktur DEVICE_OBJECT WDM driver satu kali. Akibatnya, manajer I/O menambahkan lokasi tumpukan I/O tambahan ke semua RUN sehingga fungsi panggilan balik EvtDeviceWdmIrpPreprocess dapat mengatur rutinitas IoCompletion . Perhatikan bahwa lokasi tumpukan I/O tambahan ini ditambahkan ke semua RUNTIME, bukan hanya yang berisi kode fungsi utama IRP yang Anda tentukan dalam panggilan ke WdfDeviceInitAssignWdmIrpPreprocessCallback. Oleh karena itu, untuk menghindari peningkatan penggunaan kumpulan memori yang tidak bertumpuk secara tidak perlu, Anda harus menghindari penggunaan WdfDeviceInitAssignWdmIrpPreprocessCallback kecuali tidak ada alternatif.

Jika driver Anda memanggil WdfDeviceInitAssignWdmIrpPreprocessCallback lebih dari sekali untuk kode utama yang sama, kerangka kerja hanya mempertahankan fungsi panggilan balik EvtDeviceWdmIrpPreprocess yang terbaru untuk kode utama ini. (Driver Anda tidak dapat mendaftarkan beberapa panggilan balik pra-proses untuk satu kode utama.)

Untuk informasi selengkapnya tentang metode WdfDeviceInitAssignWdmIrpPreprocessCallback , lihat Menangani RUNP WDM Di Luar Kerangka Kerja.

Contoh

Contoh kode berikut mendefinisikan fungsi panggilan balik peristiwa EvtDeviceWdmIrpPreprocess , lalu mendaftarkan fungsi panggilan balik untuk menangani runtime integrasi IRP_MJ_QUERY_INFORMATION .

NTSTATUS
SerialQueryInformationFile(
    IN WDFDEVICE Device,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is used to query the end of file information on
    the opened serial port.  Any other file information request
    is returned with an invalid parameter.

    This routine always returns an end of file of 0.

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    The function value is the final status of the call

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp;

    SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_PNP, ">SerialQueryInformationFile(%p, %p)\n", Device, Irp);

    PAGED_CODE();


    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    Irp->IoStatus.Information = 0L;
    Status = STATUS_SUCCESS;

    if (IrpSp->Parameters.QueryFile.FileInformationClass ==
        FileStandardInformation) {

        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(FILE_STANDARD_INFORMATION))
        {
                Status = STATUS_BUFFER_TOO_SMALL;
        }
        else
        {
            PFILE_STANDARD_INFORMATION Buf = Irp->AssociatedIrp.SystemBuffer;

            Buf->AllocationSize.QuadPart = 0;
            Buf->EndOfFile = Buf->AllocationSize;
            Buf->NumberOfLinks = 0;
            Buf->DeletePending = FALSE;
            Buf->Directory = FALSE;
            Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
        }

    } else if (IrpSp->Parameters.QueryFile.FileInformationClass ==
               FilePositionInformation) {

        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(FILE_POSITION_INFORMATION))
        {
                Status = STATUS_BUFFER_TOO_SMALL;
        }
        else
        {

            ((PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer)->
                CurrentByteOffset.QuadPart = 0;
            Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
        }

    } else {
        Status = STATUS_INVALID_PARAMETER;
    }

    Irp->IoStatus.Status = Status;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;

}

NTSTATUS
SerialEvtDeviceAdd(
    IN WDFDRIVER Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
{
...
    status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
                                                 DeviceInit,
                                                 SerialQueryInformationFile,
                                                 IRP_MJ_QUERY_INFORMATION,
                                                 NULL, // Pointer to the minor function table
                                                 0 // Number of entries in the table
                                                 ); 
    if (!NT_SUCCESS(status)) {
        return status;
    }
...
}

Persyaratan

Persyaratan Nilai
Target Platform Universal
Versi KMDF minimum 1,0
Header wdfdevice.h (termasuk Wdf.h)
Pustaka Wdf01000.sys (lihat Penerapan Versi Pustaka Kerangka Kerja.)
IRQL <= DISPATCH_LEVEL
Aturan kepatuhan DDI ChildDeviceInitAPI(kmdf), ControlDeviceInitAPI(kmdf), DeviceInitAPI(kmdf), DriverCreate(kmdf), InitFreeDeviceCallback(kmdf), InitFreeDeviceCreate(kmdf), InitFreeNull(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), PdoDeviceInitAPI(kmdf), PdoInitFreeDeviceCallback(kmdf), PdoInitFreeDeviceCreate(kmdf)

Lihat juga

WdfDeviceWdmDispatchPreprocessedIrp