0

我想编写一个 KMDF 驱动程序来接收 ACPI 通知值,下面是我的驱动程序代码

#include <initguid.h>
#include <ntddk.h>
#include <wdf.h>
#include <wdmguid.h>

DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;
VOID AcpiNotifyCallback(PVOID Context, ULONG NotifyCode);

typedef struct _ACPI_CONTEXT
{
    BOOLEAN Initialized;
    ACPI_INTERFACE_STANDARD2 AcpiInterface;
    BOOLEAN RegisteredForNotifications;
} ACPI_CONTEXT, *PACPI_CONTEXT;

typedef struct _FDO_CONTEXT
{
    WDFDEVICE WdfDevice;
    ACPI_CONTEXT AcpiCtx;
    WDFWORKITEM ConnectorAndNotificationWorkItem;
} FDO_CONTEXT, *PFDO_CONTEXT;

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_CONTEXT, Fdo_GetContext)

PFDO_CONTEXT
FORCEINLINE
Context_GetFdoContext(
    _In_ PACPI_CONTEXT AcpiCtx
)
{
    return CONTAINING_RECORD(AcpiCtx, FDO_CONTEXT, AcpiCtx);
}

NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT     DriverObject,
    _In_ PUNICODE_STRING    RegistryPath
)
{
    // NTSTATUS variable to record success or failure
    NTSTATUS status = STATUS_SUCCESS;

    // Allocate the driver configuration object
    WDF_DRIVER_CONFIG config;

    // Print "Hello World" for DriverEntry
    KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n"));

    // Initialize the driver configuration object to register the
    // entry point for the EvtDeviceAdd callback, KmdfHelloWorldEvtDeviceAdd
    WDF_DRIVER_CONFIG_INIT(&config,
        KmdfHelloWorldEvtDeviceAdd
    );

    // Finally, create the driver object
    status = WdfDriverCreate(DriverObject,
        RegistryPath,
        WDF_NO_OBJECT_ATTRIBUTES,
        &config,
        WDF_NO_HANDLE
    );


    return status;
}

NTSTATUS
KmdfHelloWorldEvtDeviceAdd(
    _In_    WDFDRIVER       Driver,
    _Inout_ PWDFDEVICE_INIT DeviceInit
)
{
    // We're not using the driver object,
    // so we need to mark it as unreferenced
    UNREFERENCED_PARAMETER(Driver);

    NTSTATUS status;

    // Allocate the device object
    WDFDEVICE hDevice;




    // Print "Hello World"
    KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: KmdfHelloWorldEvtDeviceAdd\n"));

    // Create the device object
    status = WdfDeviceCreate(&DeviceInit,
        WDF_NO_OBJECT_ATTRIBUTES,
        &hDevice
    );

    if (!NT_SUCCESS(status)) {
        return status;
    }
    // Context
    PACPI_CONTEXT AcpiCtx;
    PFDO_CONTEXT fdoCtx;
    fdoCtx = Fdo_GetContext(hDevice);


    status = WdfFdoQueryForInterface(
        hDevice,
        &GUID_ACPI_INTERFACE_STANDARD2,
        (PINTERFACE)&fdoCtx->AcpiCtx.AcpiInterface,
        sizeof(ACPI_INTERFACE_STANDARD2),
        1,
        NULL
    );

    if (!NT_SUCCESS(status))
    {
        KdPrint(("WdfFdoQueryForInterface failed, status = %x\n", status));
        return status;
    }

    status = fdoCtx->AcpiCtx.AcpiInterface.RegisterForDeviceNotifications(
        fdoCtx->AcpiCtx.AcpiInterface.Context,
        AcpiNotifyCallback,
        hDevice
    );

    if (!NT_SUCCESS(status)) {
        KdPrint(("RegisterForDeviceNotifications Failed\n"));
    }

    return status;
}

VOID AcpiNotifyCallback(PVOID Context, ULONG NotifyCode) {
    KdPrint(("Hello Man, NotifyValue = %x\n", NotifyCode));
    if (NotifyCode == 0x80) {
        KdPrint(("Got 0x80"));
    }
}

下面是我的inf文件

;
; VirtualTestDriver.inf
;

[Version]
Signature="$WINDOWS NT$"
Class=Sample ; TODO: edit Class
ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid
Provider=%ManufacturerName%
CatalogFile=VirtualTestDriver.cat
DriverVer= ; TODO: set DriverVer in stampinf property pages

[DestinationDirs]
DefaultDestDir = 12
VirtualTestDriver_Device_CoInstaller_CopyFiles = 11

; ================= Class section =====================

[ClassInstall32]
Addreg=SampleClassReg

[SampleClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-5

[SourceDisksNames]
1 = %DiskName%,,,""

[SourceDisksFiles]
VirtualTestDriver.sys  = 1,,
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames

;*****************************************
; Install Section
;*****************************************

[Manufacturer]
%ManufacturerName%=Standard,NT$ARCH$

[Standard.NT$ARCH$]
%VirtualTestDriver.DeviceDesc%=VirtualTestDriver_Device, ACPI\VirtualTestDriver ; TODO: edit hw-id

[VirtualTestDriver_Device.NT]
CopyFiles=Drivers_Dir

[Drivers_Dir]
VirtualTestDriver.sys

;-------------- Service installation
[VirtualTestDriver_Device.NT.Services]
AddService = VirtualTestDriver,%SPSVCINST_ASSOCSERVICE%, VirtualTestDriver_Service_Inst

; -------------- VirtualTestDriver driver install sections
[VirtualTestDriver_Service_Inst]
DisplayName    = %VirtualTestDriver.SVCDESC%
ServiceType    = 1               ; SERVICE_KERNEL_DRIVER
StartType      = 3               ; SERVICE_DEMAND_START
ErrorControl   = 1               ; SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\VirtualTestDriver.sys

;
;--- VirtualTestDriver_Device Coinstaller installation ------
;

[VirtualTestDriver_Device.NT.CoInstallers]
AddReg=VirtualTestDriver_Device_CoInstaller_AddReg
CopyFiles=VirtualTestDriver_Device_CoInstaller_CopyFiles

[VirtualTestDriver_Device_CoInstaller_AddReg]
HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"

[VirtualTestDriver_Device_CoInstaller_CopyFiles]
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll

[VirtualTestDriver_Device.NT.Wdf]
KmdfService =  VirtualTestDriver, VirtualTestDriver_wdfsect
[VirtualTestDriver_wdfsect]
KmdfLibraryVersion = $KMDFVERSION$

[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
ClassName="Samples" ; TODO: edit ClassName
DiskName = "VirtualTestDriver Installation Disk"
VirtualTestDriver.DeviceDesc = "VirtualTestDriver Device"
VirtualTestDriver.SVCDESC = "VirtualTestDriver Service"

我使用下面的命令安装驱动程序,它总是在 WdfFdoQueryForInterface 失败,返回码是 0xc00000bb。

devcon.exe install VirtualTestDriver.inf ACPI\VirtualTestDriver

我不知道如何安装此驱动程序来接收 ACPI 通知。所以我为它创建了一个虚拟设备,但它似乎不起作用。

那么,如果有人以前写过这个驱动程序,如何解决这个问题?

谢谢。

4

1 回答 1

0

正如Baget所说,它需要ACPI设备堆栈中的设备,因此如果ACPI\VirtualTestDriver不存在,则无法注册通知。

于 2019-11-11T02:46:09.897 回答