我想编写一个 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 通知。所以我为它创建了一个虚拟设备,但它似乎不起作用。
那么,如果有人以前写过这个驱动程序,如何解决这个问题?
谢谢。