SendDownStreamIrp 함수

이 항목에 제공된 함수에 SendDownStreamIrp 대한 코드 예제에서는 동기 IOCTL 요청을 ACPI 드라이버로 보내는 드라이버 제공 함수를 구현하는 방법을 보여 줍니다. 함수를 SendDownStreamIrp 사용하여 IOCTL_ACPI_EVAL_METHOD 요청, IOCTL_ACPI_EVAL_METHOD_EX 요청 또는 IOCTL_ACPI_ENUM_CHILDREN 요청을 보낼 수 있습니다.

이 섹션에 포함된 함수의 SendDownStreamIrp 예제 코드는 다음 연산 시퀀스를 수행합니다.

  • 이벤트 개체를 만듭니다.

  • IoBuildDeviceIoControlRequest를 호출하여 IOCTL 요청을 만듭니다.

  • IoCallDriver를 호출하여 IOCTL 요청을 보냅니다.

  • ACPI 드라이버가 요청이 완료되었음을 나타내는 이벤트 개체에 신호를 보낼 때까지 기다립니다.

  • 호출자에게 요청의 상태 반환합니다.

NTSTATUS
SendDownStreamIrp(
    IN PDEVICE_OBJECT   Pdo,
    IN ULONG            Ioctl,
    IN PVOID            InputBuffer,
    IN ULONG            InputSize,
    IN PVOID            OutputBuffer,
    IN ULONG            OutputSize
)
/*
Routine Description:
    General-purpose function called to send a request to the PDO. 
    The IOCTL argument accepts the control method being passed down
    by the calling function

    This subroutine is only valid for the IOCTLS other than ASYNC EVAL. 

Parameters:
    Pdo             - the request is sent to this device object
    Ioctl           - the request - specified by the calling function
    InputBuffer     - incoming request
    InputSize       - size of the incoming request
    OutputBuffer    - the answer
    OutputSize      - size of the answer buffer

Return Value:
    NT Status of the operation
*/
{
    IO_STATUS_BLOCK     ioBlock;
    KEVENT              myIoctlEvent;
    NTSTATUS            status;
    PIRP                irp;

    // Initialize an event to wait on
    KeInitializeEvent(&myIoctlEvent, SynchronizationEvent, FALSE);

    // Build the request
    irp = IoBuildDeviceIoControlRequest(
        Ioctl, 
        Pdo,
        InputBuffer,
        InputSize,
        OutputBuffer,
        OutputSize,
        FALSE,
        &myIoctlEvent,
        &ioBlock);

    if (!irp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    // Pass request to Pdo, always wait for completion routine
    status = IoCallDriver(Pdo, irp);

    if (status == STATUS_PENDING) {
        // Wait for the IRP to be completed, and then return the status code
        KeWaitForSingleObject(
            &myIoctlEvent,
            Executive,
            KernelMode,
            FALSE,
            NULL);

        status = ioBlock.Status;
    }

    return status;
}