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 |
---|---|
|
Nilai MajorFunction tidak valid. |
|
Memori tidak cukup. |
|
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.
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) |