如何注册acpi事件通知?(AcpiInterfaces.RegisterForDeviceNotifications)

时间:2016-06-01 10:09:53

标签: windows pdo driver wdm acpi

现在我想在我的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 enter link description here enter image description here

1 个答案:

答案 0 :(得分:1)

好的,现在我自己回答我的问题。 驱动程序必须安装在\ Driver \ Acpi上,它才能正常工作。 所以请使用dpinst.exe和参数“/ f”安装