Как зарегистрировать уведомление о событии acpi? (AcpiInterfaces.RegisterForDeviceNotifications)

теперь я хочу добавить эту функцию в свой драйвер acpi. Функция: получить уведомление BIOS. Я ищу документ и пишу код

NTSTATUS
XxxAddDevice(
    __in struct _DRIVER_OBJECT *DriverObject,
    __in struct _DEVICE_OBJECT *PhysicalDeviceObject
    )
{
.
.
.

    status = STATUS_SUCCESS;

    DebugPrint(("AddDevice: %p to %p->%p \n",fdo,fdoData->NextLowerDO,PhysicalDeviceObject));
    DebugPrint(("DeviceObject Flag = 0x%08x\n",fdo->Flags));
    DebugPrint(("DevicePnPState = %d\n", fdoData->DevicePnPState));
    {
        //PACPI_INTERFACE_STANDARD2 pInterface = 
        //  ExAllocatePool(PagedPool, sizeof(ACPI_INTERFACE_STANDARD2));
        ACPI_INTERFACE_STANDARD Interfaces = {0};
        if (&Interfaces == NULL)
        {
            goto FuncEnd;
        }
        //RtlFillMemory(pInterface, sizeof(ACPI_INTERFACE_STANDARD2), 0x00);
        status = GetAcpiInterfaces(fdo, &Interfaces);
        if (!NT_SUCCESS(status))
        {
            DebugPrint(("GetAcpiInterfaces Failed\n"));
        }
        else
        {
            DebugPrint(("******GetAcpiInterfaces Succeed\n"));
            DebugPrint(("******ACPI_INTERFACE_STANDARD2 Version == %d\n", Interfaces.Version));
            DebugPrint(("******AcpiInterface.RegisterForDeviceNotifications Address == %x\n",
                Interfaces.RegisterForDeviceNotifications));
            //Interfaces.InterfaceReference(Interfaces.Context);
        }

        if (Interfaces.RegisterForDeviceNotifications != NULL)
        {
            status = Interfaces.RegisterForDeviceNotifications(
                Interfaces.Context,
                ACPIDeviceNotifyHandler,
                fdoData);
            if (!NT_SUCCESS(status))
            {
                DebugPrint(("RegisterForDeviceNotifications Failed\n"));
            }
            else
            {
                DebugPrint(("RegisterForDeviceNotifications Succeed\n"));
            }
        }
        //Free Memory
        //ExFreePool(pInterface);

//      PDEVICE_OBJECT target = fdoData->NextLowerDO;
//      RegisterACPINotifyEvent(target, fdoData);
        status = STATUS_SUCCESS;
    }

FuncEnd:

    return status;
}

NTSTATUS
GetAcpiInterfaces(
IN PDEVICE_OBJECT   Pdo,
OUT PACPI_INTERFACE_STANDARD AcpiInterfaces
)
{
    NTSTATUS                Status = STATUS_NOT_SUPPORTED;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IrpSp;
    PDEVICE_OBJECT          LowerPdo = NULL;

    KEVENT event;
    DebugPrint(("Enter GetAcpiInterfaces...\n"));
    KeInitializeEvent(&event, NotificationEvent, FALSE);
    // Only need to do this once
    if (!LowerPdo) 
    {
        LowerPdo = IoGetAttachedDeviceReference(Pdo);

        // Allocate an IRP for below Irp = IoAllocateIrp
        // (LowerPdo->StackSize, FALSE);    // Get stack size from
        // PDO
        Irp = IoAllocateIrp(LowerPdo->StackSize, FALSE);
        if (Irp == NULL)
        {
            DebugPrint(("IoAllocateIrp Failed...\n"));
            Status = STATUS_UNSUCCESSFUL;
            return Status;
        }
        IrpSp = IoGetNextIrpStackLocation(Irp);
        //
        // Use QUERY_INTERFACE to get the address of the direct-
        // call ACPI interfaces.
        //
        IrpSp->MajorFunction = IRP_MJ_PNP;
        IrpSp->MinorFunction = IRP_MN_QUERY_INTERFACE;
        IrpSp->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_ACPI_INTERFACE_STANDARD;
        IrpSp->Parameters.QueryInterface.Version = 1;
        IrpSp->Parameters.QueryInterface.Size = sizeof(ACPI_INTERFACE_STANDARD);
        IrpSp->Parameters.QueryInterface.Interface = (PINTERFACE)AcpiInterfaces;
        IrpSp->Parameters.QueryInterface.InterfaceSpecificData = NULL;
        IoSetCompletionRoutine(Irp, ACPIDriverSynchronousRequest, &event, TRUE, TRUE, TRUE);
        DebugPrint(("******Before IoCallDriver.Status == %08X\n", Status));
        Status = IoCallDriver(LowerPdo, Irp);
        DebugPrint(("******IoCallDriver.Status == %08X\n",Status));
        //Wait for complete
        if (Status == STATUS_PENDING)
        {
            DebugPrint(("KeWaitForSingleObject QueryInterface...\n"));
            Status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
            DebugPrint(("KeWaitForSingleObject.Status == %08X\n", Status));
            DebugPrint(("pNewIrp->IoStatus.Status == %08X\n", Irp->IoStatus.Status));
        }

        //IoFreeIrp(Irp);
    }
    return Status;
}

CompletionRoutine возвращает STATUS_SUCCESS, но интерфейс по-прежнему пуст...

Parameters.QueryInterface.Interface не заполняется... может мне кто-нибудь помочь??? MSDN о IRP_MN_QUERY_INTERFACE введите здесь описание ссылки введите здесь описание изображения


person LeenLi    schedule 01.06.2016    source источник


Ответы (1)


Хорошо, теперь я сам отвечу на свой вопрос. драйвер должен быть установлен на \Driver\Acpi, он будет работать. поэтому устанавливайте с dpinst.exe и параметром "/f"

person LeenLi    schedule 14.07.2016