如何注册acpi事件通知?(AcpiInterfaces.RegisterForDeviceNotifications) [英] How to register acpi event notify?(AcpiInterfaces.RegisterForDeviceNotifications)

查看:301
本文介绍了如何注册acpi事件通知?(AcpiInterfaces.RegisterForDeviceNotifications)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我要在acpi驱动程序中添加该功能. 功能是:获取BIOS通知. 我搜索一些文档,然后编写代码

now I want to add the function in my acpi driver . the function is:get the BIOS Notify . I search some doc, And Write code

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,但是接口仍然为空...

the CompletionRoutine return STATUS_SUCCESS,but the interface is still Empty...

Parameters.QueryInterface.Interface未填充... 有人能帮我吗 ??? MSDN关于IRP_MN_QUERY_INTERFACE 在此处输入链接描述 在此处输入图像描述

Parameters.QueryInterface.Interface does not be filled ... can some one help me ??? MSDN About IRP_MN_QUERY_INTERFACE enter link description here enter image description here

推荐答案

好的,现在我自己回答我的问题. 该驱动程序必须安装在\ Driver \ Acpi上,它将起作用. 因此,请安装dpinst.exe和参数"/f"

OK,now I answer my question myself. the driver must install on \Driver\Acpi ,it will work. so please install with dpinst.exe and parameter "/f"

这篇关于如何注册acpi事件通知?(AcpiInterfaces.RegisterForDeviceNotifications)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆