Quite a few changes must be made to a project to support WMI. 1. All the WMI functions, including support for the Wdm3SystemControl WMI IRP, are in Wmi.cpp. Include this file in the SOURCES list of files to compile in the SOURCES file. 2. I found that this line had to be included in SOURCES to ensure that the WMI library file was found. 3. The prebuild steps had to be altered to persuade build to run the mofcomp tool to compile Wdm3.mof. The SOURCES file NTTARGETFILE0 macro is changed to ensure that makefile.inc runs the following command. The complete makefile.inc is given in the next chapter. This command line compiles MOF source file Wdm3.mof into the binary MOF Wdm3.bmf file. The options to mofcomp ensure that the source code is checked for WMI compatibility and that the output goes in the correct file. 4. The main resource file Wdm3.rc must now include the binary MOF file Wdm3.bmf. The following line in the resource script identifies the data using the name MofResource. 5. The main header in Wdm3.h had to use standard headers wmilib.h and wmistr.h. It also included wdmguid.h to get the definition of the standard GUID, GUID_POWER_DEVICE_ENABLE. 6. The device extension has these extra fields added. WmiLibInfo is used to pass the Wdm3 WMI GUIDs and various callbacks, as described later. IdlePowerDownEnable implements the MSPower_DeviceEnable WMI data block. If IdlePowerDownEnable is TRUE, the driver can power down when it is idle. Finally, WMIEventEnabled is used to enable WMI event reporting. 7. The main WMI code needs to refer to the driver registry path that was passed to DriverEntry. Therefore, DriverEntry saves a copy in its Wdm3RegistryPath global variable. The driver unload routine Wdm3Unload deletes the Wdm3RegistryPath buffer.WMI Build Environment
TARGETLIBS=C:\NTDDK\LIBFRE\I386\WmiLib.Lib
mofcomp –B:Wdm3.bmf –WMI Wdm3.mof
MOFRESOURCE MOFDATA MOVEABLE PURE "Wdm3.bmf"
WMILIB_CONTEXT WmiLibInfo; // WMI Context
BOOLEAN IdlePowerDownEnable; // Enable power down option
BOOLEAN WMIEventEnabled; // Enable WMI events
// Save a copy of our RegistryPath for WMI
Wdm3RegistryPath.MaximumLength = RegistryPath->MaximumLength;
Wdm3RegistryPath.Length = 0;
Wdm3RegistryPath.Buffer = (PWSTR)ExAllocatePool(PagedPool, Wdm3RegistryPath.MaximumLength);
if (Wdm3RegistryPath.Buffer == NULL) return STATUS_INSUFFICIENT_RESOURCES;
RtlCopyUnicodeString(&Wdm3RegistryPath, RegistryPath);