Função WdfDeviceInitAssignWdmIrpPreprocessCallback (wdfdevice.h)
[Aplica-se somente ao KMDF]
O método WdfDeviceInitAssignWdmIrpPreprocessCallback registra uma função de retorno de chamada para lidar com um código de função principal do IRP e, opcionalmente, um ou mais códigos de função secundários associados ao código de função principal.
Sintaxe
NTSTATUS WdfDeviceInitAssignWdmIrpPreprocessCallback(
[in] PWDFDEVICE_INIT DeviceInit,
[in] PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmIrpPreprocess,
[in] UCHAR MajorFunction,
[in, optional] PUCHAR MinorFunctions,
[in] ULONG NumMinorFunctions
);
Parâmetros
[in] DeviceInit
Um ponteiro para uma estrutura WDFDEVICE_INIT .
[in] EvtDeviceWdmIrpPreprocess
Um ponteiro para a função de retorno de chamada EvtDeviceWdmIrpPreprocess do driver.
[in] MajorFunction
Um dos principais códigos de função IRP definidos em wdm.h.
[in, optional] MinorFunctions
Um ponteiro para uma matriz de um ou mais códigos de função secundária IRP associados ao código de função principal especificado. Esse parâmetro é opcional e pode ser NULL. Para obter mais informações, consulte a seção Comentários a seguir.
[in] NumMinorFunctions
O número de códigos de função secundários contidos na matriz MinorFunctions .
Retornar valor
Se a operação for bem-sucedida, o método retornará STATUS_SUCCESS. Os valores retornados adicionais incluem:
Código de retorno | Descrição |
---|---|
|
O valor MajorFunction é inválido. |
|
Não há memória suficiente. |
|
O driver registrou anteriormente uma matriz MinorFunctions para essa função principal e está tentando especificar funções secundárias novamente para o código MajorFunction especificado. |
O método pode retornar outros valores NTSTATUS.
Comentários
Os drivers podem chamar o método WdfDeviceInitAssignWdmIrpPreprocessCallback por dois motivos:
-
Para lidar com um código de função principal ou secundário do IRP que a estrutura não dá suporte.
Por exemplo, a estrutura não dá suporte a IRP_MJ_FLUSH_BUFFERS. Se o driver precisar dar suporte a esse IRP, ele deverá registrar uma função de retorno de chamada EvtDeviceWdmIrpPreprocess que manipula o IRP. O driver deve seguir as regras do WDM para processar IRPs.
-
Para pré-processar um IRP antes que a estrutura o trate.
Em casos raros, pode ser necessário que um driver processe um IRP antes que a estrutura o processe. Nesses casos, a função de retorno de chamada EvtDeviceWdmIrpPreprocess do driver pode processar o IRP e chamar WdfDeviceWdmDispatchPreprocessedIrp para retornar o IRP para a estrutura. Dependendo do código de função do IRP, a estrutura pode processar o IRP em si ou entregar o IRP ao driver novamente em um objeto de solicitação de estrutura.
Se o ponteiro da matriz MinorFunctions for NULL, a estrutura chamará a função de retorno de chamada para todos os códigos de função secundários associados ao código de função principal especificado. Se o ponteiro da matriz MinorFunctions não for NULL, a estrutura fará uma cópia da matriz para que o driver não precise manter permanentemente sua matriz.
Se o driver recebeu o ponteiro DeviceInit de WdfPdoInitAllocate ou uma função de retorno de chamada de evento EvtChildListCreateDevice , a função de retorno de chamada EvtDeviceWdmIrpPreprocess do driver não pode definir uma rotina de conclusão para IRPs que contenham um código de função principal de IRP_MJ_PNP. Caso contrário, o Verificador de Driver relatará um erro.
Se o driver chamar WdfDeviceInitAssignWdmIrpPreprocessCallback uma ou mais vezes, a estrutura incrementará o membro StackSize do WDM do driver DEVICE_OBJECT estrutura uma vez. Como resultado, o gerenciador de E/S adiciona um local de pilha de E/S adicional a todos os IRPs para que a função de retorno de chamada EvtDeviceWdmIrpPreprocess possa definir uma rotina de IoCompletion . Observe que esse local de pilha de E/S extra é adicionado a todos os IRPs, não apenas aos que contêm um código de função principal IRP que você especifica em uma chamada para WdfDeviceInitAssignWdmIrpPreprocessCallback. Portanto, para evitar aumentar desnecessariamente o uso do pool de memória nãopagado pelo driver, evite usar WdfDeviceInitAssignWdmIrpPreprocessCallback , a menos que não haja alternativa.
Se o driver chamar WdfDeviceInitAssignWdmIrpPreprocessCallback mais de uma vez para o mesmo código principal, a estrutura reterá apenas a função de retorno de chamada EvtDeviceWdmIrpPreprocess definida mais recentemente para esse código principal. (O driver não pode registrar vários retornos de chamada de pré-processamento para um único código principal.)
Para obter mais informações sobre o método WdfDeviceInitAssignWdmIrpPreprocessCallback , consulte Handling WDM IRPs Outside of the Framework.
Exemplos
O exemplo de código a seguir define uma função de retorno de chamada de evento EvtDeviceWdmIrpPreprocess e registra a função de retorno de chamada para lidar com IRP_MJ_QUERY_INFORMATION IRPs.
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;
}
...
}
Requisitos
Requisito | Valor |
---|---|
Plataforma de Destino | Universal |
Versão mínima do KMDF | 1.0 |
Cabeçalho | wdfdevice.h (inclua Wdf.h) |
Biblioteca | Wdf01000.sys (consulte Controle de versão da biblioteca de estrutura.) |
IRQL | <= DISPATCH_LEVEL |
Regras de conformidade de 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) |