다음을 통해 공유


WdfDeviceInitAssignWdmIrpPreprocessCallback 함수(wdfdevice.h)

[KMDF에만 적용]

WdfDeviceInitAssignWdmIrpPreprocessCallback 메서드는 IRP 주 함수 코드를 처리하는 콜백 함수를 등록하고 필요에 따라 주 함수 코드와 연결된 하나 이상의 부 함수 코드를 등록합니다.

구문

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

매개 변수

[in] DeviceInit

WDFDEVICE_INIT 구조체에 대한 포인터입니다.

[in] EvtDeviceWdmIrpPreprocess

드라이버의 EvtDeviceWdmIrpPreprocess 콜백 함수에 대한 포인터입니다.

[in] MajorFunction

wdm.h에 정의된 IRP 주요 함수 코드 중 하나입니다.

[in, optional] MinorFunctions

지정된 주 함수 코드와 연결된 하나 이상의 IRP 부 함수 코드 배열에 대한 포인터입니다. 이 매개 변수는 선택 사항이며 NULL일 수 있습니다. 자세한 내용은 아래 설명 부분을 참조하십시오.

[in] NumMinorFunctions

MinorFunctions 배열에 포함된 부 함수 코드의 수입니다.

반환 값

작업이 성공하면 메서드는 STATUS_SUCCESS 반환합니다. 추가 반환 값은 다음과 같습니다.

반환 코드 설명
STATUS_INVALID_PARAMETER
MajorFunction 값이 잘못되었습니다.
STATUS_INSUFFICIENT_RESOURCES
메모리가 부족합니다.
STATUS_INVALID_DEVICE_REQUEST
드라이버는 이전에 이 주 함수에 대한 MinorFunctions 배열을 등록했으며 지정된 MajorFunction 코드에 대해 부 함수를 다시 지정하려고 합니다.
 

메서드는 다른 NTSTATUS 값을 반환할 수 있습니다.

설명

드라이버는 두 가지 이유 중 하나로 WdfDeviceInitAssignWdmIrpPreprocessCallback 메서드를 호출할 수 있습니다.

  • 프레임워크에서 지원하지 않는 IRP 주 함수 또는 부 함수 코드를 처리합니다.

    예를 들어 프레임워크는 IRP_MJ_FLUSH_BUFFERS 지원하지 않습니다. 드라이버가 이 IRP를 지원해야 하는 경우 IRP 를 처리하는 EvtDeviceWdmIrpPreprocess 콜백 함수를 등록해야 합니다. 드라이버는 IRP 처리를 위해 WDM 규칙을 따라야 합니다.

  • 프레임워크에서 IRP를 처리하기 전에 전처리합니다.

    드문 경우이지만 프레임워크에서 IRP를 처리하기 전에 드라이버가 IRP를 처리해야 할 수 있습니다. 이러한 경우 드라이버의 EvtDeviceWdmIrpPreprocess 콜백 함수는 IRP를 처리한 다음 WdfDeviceWdmDispatchPreprocessedIrp 를 호출하여 IRP를 프레임워크로 반환할 수 있습니다. IRP의 함수 코드에 따라 프레임워크는 IRP 자체를 처리하거나 프레임워크 요청 개체에서 드라이버에 IRP를 다시 제공할 수 있습니다.

프레임워크는 MajorFunction 매개 변수와 일치하는 IRP 주 함수 코드와 MinorFunctions 배열에 있는 부 함수 코드 중 하나와 일치하는 부 함수 코드가 포함된 IRP(I/O 요청 패킷)를 받을 때마다 EvtDeviceWdmIrpPreprocess 콜백 함수를 호출합니다.

MinorFunctions 배열 포인터가 NULL이면 프레임워크는 지정된 주 함수 코드와 연결된 모든 부 함수 코드에 대한 콜백 함수를 호출합니다. MinorFunctions 배열 포인터가 NULL이 아닌 경우 프레임워크는 드라이버가 해당 배열을 영구적으로 유지할 필요가 없도록 배열의 복사본을 만듭니다.

드라이버가 WdfPdoInitAllocate 또는 EvtChildListCreateDevice 이벤트 콜백 함수에서 DeviceInit 포인터를 받은 경우 드라이버의 EvtDeviceWdmIrpPreprocess 콜백 함수는 IRP_MJ_PNP 주요 함수 코드가 포함된 IRP에 대한 완료 루틴을 설정할 수 없습니다. 그렇지 않으면 드라이버 검증 도구 가 오류를 보고합니다.

드라이버가 WdfDeviceInitAssignWdmIrpPreprocessCallback을 한 번 이상 호출하는 경우 프레임워크는 드라이버의 WDM DEVICE_OBJECT 구조체의 StackSize 멤버를 한 번 증가합니다. 따라서 I/O 관리자는 모든 IRP에 추가 I/O 스택 위치를 추가하여 EvtDeviceWdmIrpPreprocess 콜백 함수가 IoCompletion 루틴을 설정할 수 있도록 합니다. 이 추가 I/O 스택 위치는 WdfDeviceInitAssignWdmIrpPreprocessCallback 호출에서 지정한 IRP 주 함수 코드가 포함된 IRP뿐만 아니라 모든 IRP에 추가됩니다. 따라서 드라이버의 비페이지 메모리 풀 사용을 불필요하게 늘리지 않도록 하려면 대안이 없는 한 WdfDeviceInitAssignWdmIrpPreprocessCallback 을 사용하지 않아야 합니다.

드라이버가 동일한 주 코드에 대해 WdfDeviceInitAssignWdmIrpPreprocessCallback 을 두 번 이상 호출하는 경우 프레임워크는 이 주 코드에 대해 가장 최근에 설정된 EvtDeviceWdmIrpPreprocess 콜백 함수만 유지합니다. (드라이버는 단일 주 코드에 대해 여러 전처리 콜백을 등록할 수 없습니다.)

WdfDeviceInitAssignWdmIrpPreprocessCallback 메서드에 대한 자세한 내용은 프레임워크 외부에서 WDM IRP 처리를 참조하세요.

예제

다음 코드 예제에서는 EvtDeviceWdmIrpPreprocess 이벤트 콜백 함수를 정의한 다음 콜백 함수를 등록하여 IRP_MJ_QUERY_INFORMATION IRP를 처리합니다.

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

요구 사항

요구 사항
대상 플랫폼 유니버설
최소 KMDF 버전 1.0
머리글 wdfdevice.h(Wdf.h 포함)
라이브러리 Wdf01000.sys(프레임워크 라이브러리 버전 관리 참조)
IRQL <= DISPATCH_LEVEL
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)

추가 정보

WdfDeviceWdmDispatchPreprocessedIrp