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 mofcomp. You can include the binary MOF data either in your driver's resource or in a separate DLL. You must write a separate class for each WMI data block and WMI event block.

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, MSSerial_CommInfo, MSSerial_CommProperties, MSSerialHardwareConfiguration, MSSerial_PerformanceInformation and MSSerial_PortName. In each case the InstanceName property is the key, named after the PnP driver instance, not the serial port name. However, the MSSerial_PortName data object lets you retrieve the real port name in its PortName property. As another example, the MSSerial_CommInfo BaudRate property has the serial port's baud rate.

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 MSPower_DeviceEnable WMI data block. As described in Chapter 10, this is used by the Device Manager to let users stop a device from powering down. This means that the Wdm3 must be able to accept a changed value for the Enable property, as well as reporting the current setting.

Listing 12.1 shows the source for the MSPower_DeviceEnable WMI data block, taken from WMICORE.MOF. A GUID is used to identify the block. This is {827c0a6f-feb0 -11d0-bd26-00aa00b7b32a}, which is defined as GUID_POWER_DEVICE_ENABLE in the standard header WDMGUID.H.

All WMI classes have a key string property called InstanceName and Boolean property called Active. The MSPower_DeviceEnable class has only one 'real' property, called Enable, that can be read and written and is identified as the first WmiDataId.

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 WmiDataProvider BOOLEAN in the PORT_CONFIGURATION_INFORMATION structure and handle SRB_FUNCTION_WMI requests.

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 Wdm3Information data block contains two 32-bit unsigned properties followed by a counted wide string property. The first real property, BufferLen, is the length of the shared memory buffer. BufferFirstWord is the first 32 bits of the shared memory buffer, or zero if the buffer is not long enough. Finally, SymbolicLinkName is the symbolic link name of the Wdm3 device interface.

The Wdm3Inforination data block has a definition for a PowerDown function. I found that this did not compile, so I commented it out.

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.

WMI Build Environment

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 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.

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 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.

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.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×