Compartir a través de


Función SendDownStreamIrp

En el ejemplo de código de la SendDownStreamIrp función que se proporciona en este tema se muestra cómo implementar una función proporcionada por el controlador que envía solicitudes IOCTL sincrónicas al controlador ACPI. La SendDownStreamIrp función se puede usar para enviar una solicitud de IOCTL_ACPI_EVAL_METHOD , una solicitud de IOCTL_ACPI_EVAL_METHOD_EX o una solicitud de IOCTL_ACPI_ENUM_CHILDREN .

El código de ejemplo de la SendDownStreamIrp función que se incluye en esta sección realiza la siguiente secuencia de operaciones:

  • Crea un objeto de evento.

  • Llama a IoBuildDeviceIoControlRequest para crear la solicitud IOCTL.

  • Llama a IoCallDriver para enviar la solicitud IOCTL.

  • Espera hasta que el controlador ACPI señale el objeto de evento, que indica que la solicitud se ha completado.

  • Devuelve el estado de la solicitud al autor de la llamada.

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