class definitions in binary MOF format from drivers and sends them to CIMOM. It updates the definitions as driver changes occur.
The WDM instance provider is a dynamic provider, creating instances on demand. The WDM method provider lets applications invoke methods in a WMI driver. The WDM event provider receives events from WMI devices and translates them into an instance derived from WMI Event, itself a subclass of the CIM_ExtrinisicEvent system class.
There are standard WMI classes defined that you can and should use. However, you can define your own if need be, each identified by a new GUID. In this case, you write a MOF file and compile it using
An event block class must be derived from the WMIEvent class. All WMI blocks appear in the RootWMI CIMOM namespace.
Standard WMI Objects
The Windows WDM provider has several standard Win32 WMI blocks defined. You can find these using the WBEM Object Browser. The MOF definitions for most of the standard Win32 WMI blocks are in the W2000 DDK file srcstorageclassdiskWMICORE.MOF.
The W2000 DDK sources also have plenty of examples of how to implement WMI. For example, the standard Windows 2000 serial driver provides five WMI data blocks of information,
If you are writing a driver that is similar to a system driver, then consider reporting the standard system WMI blocks. The Wdm3 driver implements the standard
Listing 12.1 shows the source for the
All WMI classes have a key string property called
Listing 12.1 MSPower_DeviceEnable WMI data block
[Dynamic, Provider('WMIProv'), WMI,
Description('The buffer for this control is a BOOLEAN and indicates if the device should dynamically power on and off while the system is working. A driver would only support such a setting if there is a significant user noticeable effect for powering off the device. E.g., turning on the device may cause a user noticeable delay. Regardless of this setting, the driver is still required to support system sleeping states irps (which likely translates to powering off the device when a system sleep occurs).'),
guid('827c0a6f-feb0-11d0-bd26-00aa00b7b32a'), locale('MS\0x409')]
class MSPower_DeviceEnable {
[key, read]
string InstanceName;
[read]
boolean Active;
[WmiDataId(1), read, write]
boolean Enable;
};
A WMI Driver
A WDM driver can use WMI mechanisms to publish information, permit configuration of its device, and supply notifications of events. It should continue to report standard Windows 2000 events, as many system administrators will still be looking for this event information. However, WMI is the way forward, as it allows information to be made available on non-W2000 systems, and it allows remote inspection and control of the device.
WDM drivers, NT style drivers, and miniport drivers/minidriver can support WMI. In the latter case, you must fit in with the WMI reporting mechanism supported by the class driver. For example, a SCSI miniport must set the
The Wdm3 driver defines two custom WMI blocks. Listing 12.2 shows how the Wdm3Information data block and the Wdm3Event event block are defined in Wdm3.mof. The identifying GUID for each block is defined in the GUIDs.h header: WDM3_WMI_GUID and WDM3_WMI_EVENT_GUID.
The
The
The Wdm3Event WMI event block must be derived from the standard WMI Event class. It simply defines a Message property.
Listing 12.2 Wdm3Iinformation and Wdm3Event block
/* WMI data block: Information about Wdm3 device Wdm3Information, identified by WDM3_WMI_GUID */
[WMI, Dynamic, Provider('WMIProv'), Description('Wdm3 information'), guid('{C0CF0643-5F6E-11d2-B677-0OC0DFE4C1F3}'), locale('MS\0x409')]
class Wdm3Information {
[key, read]
string InstanceName;
[read]
boolean Active;
[WmiDataId(1), read, Description('Shared memory buffer length') ]
uint32 BufferLen;
[WmiDataId(2), read, Description('First ULONG of shared memory buffer') ]
uint32 BufferFirstWord;
[WmiDataId(3), read, Description('Symbolic link name') ]
string SymbolicLinkName;
/* Doesn't compile
[Implemented]
void PowerDown(); */
};
/* WMI event block: Wdm3 device event Wdm3Event, identified by WDM3_WMI_EVENT_GUID */
[WMI, Dynamic, Provider('WMIProv'), guid('{C0CF0644-5F6E-11d2-B677-00C0DFE4C1F3}'), locale('MS\0x409'), Description('Wdm3 event message')]
class Wdm3Event : WMIEvent {
[key, read]
string InstanceName;
[read]
boolean Active;
[WmiDataId(1), read, Description('Message')]
string Message;
};
This example MOF file shows how a driver defines static instance names when it registers a WMI block. Alternatively, if necessary, the driver can define dynamic instance names if the instances change frequently at run time. Handling dynamic instance names is harder and is not a common requirement, so it is not discussed here.
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.
TARGETLIBS=C:NTDDKLIBFREI386WmiLib.Lib
3. The prebuild steps had to be altered to persuade
mofcomp –B:Wdm3.bmf –WMI Wdm3.mof
This command line compiles MOF source file Wdm3.mof into the binary MOF Wdm3.bmf file. The options to
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.
MOFRESOURCE MOFDATA MOVEABLE PURE 'Wdm3.bmf'
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.