0

I want to write a KMDF driver to receive the ACPI notify value, below is my Driver code

#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"));
    }
}

And below is my inf file

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

I use below command to install driver, it always failed at WdfFdoQueryForInterface, and return code is 0xc00000bb.

devcon.exe install VirtualTestDriver.inf ACPI\VirtualTestDriver

I don't how to install this driver to receive ACPI notifications. So I create a virtual device for it, but it seems not to work.

then, if anyone writes this driver before, how to solve this problem?

Thanks.

stackmetro
  • 11
  • 2
  • I referenced to [link](https://stackoverflow.com/questions/37565663/how-to-register-acpi-event-notifyacpiinterfaces-registerfordevicenotifications), but also can't work. this example code I use received "AcpiInterface.RegisterForDeviceNotifications Address == 0 ", it can't register the notifications. – stackmetro Sep 24 '19 at 08:19
  • do you have an ACPI Device in your DTDS that is "ACPI\VirtualTestDriver" ? – Baget Oct 04 '19 at 18:34

1 Answers1

0

As Baget said, it need a device in the ACPI device stack, so if ACPI\VirtualTestDriver is not exist, it can't register the notification.

stackmetro
  • 11
  • 2