void Wdm3FireEvent(IN PDEVICE_OBJECT fdo, wchar_t* Msg) {

 DebugPrint('Wdm3FireEvent: Msg %S', Msg);

 PWDM3_DEVICE_EXTENSION dx = (PWDM3_DEVICE_EXTENSION)fdo->DeviceExtension;

 if (!dx->WMIEventEnabled) return;

 // Get MsgLen in bytes

 int MsgLen = 0;

 wchar_t* Msg2 = Msg;

 while (*Msg2++!=0) MsgLen += sizeof(wchar_t);

 // Allocate event memory

 PUSHORT pData = (PUSHORT)ExAllocatePool(NonPagedPool, MsgLen+2);

 if (pData==NULL) return;

 PUSHORT pData2 = pData;

 *pData2++ = MsgLen;

 RtlMoveMemory(pData2, Msg, MsgLen);

 WmiFireEvent(fdo, (LPGUID)&WDM3_WMI_EVENT_GUID, 0, MsgLen+2, pData);

}

NTSTATUS WmiFunctionControl(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN ULONG GuidIndex, IN WMIENABLEDISABLECONTROL Function, IN BOOLEAN Enable) {

 DebugPrint('WmiFunctionControl: GuidIndex %d, Function %d, Enable %d',

  GuidIndex, Function, Enable);

 PWDM3_DEVICE_EXTENSION dx = (PWDM3_DEVICE_EXTENSION)fdo->DeviceExtension;

 if (GuidIndex==WDM3_WMI_EVENT_GUID_INDEX && Function==WmiEventControl) {

  DebugPrint('WmiFunctionControl: Event enable %d', Enable);

  dx->WMIEventEnabled = Enable;

  return WmiCompleteRequest(fdo, Irp, STATUS_SUCCESS, 0, IO_NO_INCREMENT);

 }

 return FailWMIRequest(fdo, Irp, GuidIndex);

}

WMI in Action

The WMl features of the Wdm3 driver can be tested in three ways. In all cases, the DebugPrint output of the checked build gives copious trace information about the requests as they happen.

The first thing I must say is that I could not get the driver to compile or run in Windows 98. I am sure that I could have got the Wdm3 driver to compile if I had copied the correct headers and libraries into the W98 DDK, but that did not seem appropriate. It is possible that the one test Windows 98 computer available had its WBEM/WMI runtime corrupted. In the Windows 2000 beta 2, I obtained an update to the WBEM/WMI SDK. Perhaps this update was not meant for Windows 98 and therefore messed up the runtime environment. Anyway, I was able to do the rest of my testing only in Windows 2000.

The MSPower_DeviceEnable WMI data block is used by the Device Manager to display the Power Management tab in the device properties box, as shown in Figure 10.3 in Chapter 10. It retrieves the Enable property, eventually in a call to QueryWmiDataBlock. If the user changes the setting, it is changed in SetWmiDataBlock when the device properties box is closed.

Alternatively, the standard WBEM Object Browser can be used to inspect the MSPower_ DeviceEnable or Wdm3Information WMI data blocks. Logon to the RootWMI namespace as the current user, select the Wdm3Information class, for instance, and select one of the Wdm3 device instances.

Figure 12.1 shows the Wdm3Information display for the Wdm3 device that has an instance name of Root\Unknown\0004_0 as its key property. The Wdm3Test application has been run, so the current buffer length is 4. The BufferFirstWord property has a decimal value of 2882400001, which is hex 0xabcdef01.

W2000 Beta 3 includes the WBEMTest tool (System32WBEMwbemtest.exe) that can also be used to inspect WBEM classes and instances.

By the way, I found that the WBEM Object Browser seemed a bit sluggish. This is possibly because it is using WQL to query the database. In contrast, the Device Manager's use of WMI when dealing with a device's Power Management tab seems to run quickly.

Figure 12.1 WBEM Object Browser inspecting a Wdm3Information instance

You can use the WBEM CIM Studio to look at the class definitions. If you change a WMI data block, use WBEM CIM Studio to delete the old class definition. A reboot of the computer seems to be necessary to reregister the class correctly.

I could not work out how to use the WBEM Event Registration utility to enable events in the Wdm3 driver.

Conclusion

This chapter has shown that it is reasonably straightforward to add administrative control facilities to a driver using the Windows Management Instrumentation extensions for WDM. Despite claims to the contrary, I could not get WMI to run in Windows 98, reducing its usefulness. I also could not get WMI events and methods to work in the Windows 2000 beta 2.

The next chapter looks at NT events, another way of reporting important events to NT 3.51, NT 4, and Windows 2000 administrators. It also concludes my look at the features of the Wdm3 example driver.

Chapter 13

Event Reporting

This chapter looks at the second method of reporting information to system administrators, NT events. The last chapter looked at the first method, Windows Management Instrumentation (WMI), which ought to work in Windows 98, as well as the NT and Windows 2000 platforms.

Drivers can generate NT events in NT 3.51, NT 4, and Windows 2000. Events are stored in a system event log that can be viewed by a user mode Event Viewer.

The Wdm3 driver generates NT events in a few places. Although the Wdm3 example is a WDM device driver, NT events can and should be generated by NT style NT 3.51 and NT 4 drivers.

Overview

In NT 3.51, NT 4, and Windows 2000, drivers should report any problems to the system event log. Windows 98 WDM device drivers can make the relevant kernel calls, but they do nothing.

Once events are firmly in the event log, they are preserved even if a system crashes. Events can, therefore, be useful in some debugging circumstances (e.g., where DebugPrint information is lost as a driver crashes).

In NT 3.51 and NT 4, use the EventVwr tool to view events. In Windows 2000 use the Event Viewer System Log portion of the Computer Management Console. In both cases, you must double-click on a record to bring up the full details of the event, as shown in Figure 13.1.

The Event Detail tab shows most of the event information. Events are categorized as either Informational, Warning, or Error. The message text is taken from a resource in the driver's executable. A driver can specify some small extra strings that are inserted into the message text.

The Record Data tab shows (in hex) any additional data bytes that were passed by the driver. In Windows 2000, most drivers always seem to show at least 0x28 bytes of record data. Any data that your driver provides starts at offset 0x28.

Do not swamp the event log with superfluous information. Obviously, try to report errors in a meaningful way. Remember that the event log will only be useful when a problem arises. Some informational messages may be useful for displaying status information, such as network addresses.

If you are being clever, you could dynamically adjust the amount of information that you produce. You might start off by reporting transactions that need to be retried as warning messages. If these keep occurring, you could stop reporting these retry messages.

Other drivers inspect a registry value when they start up to determine the level of reporting. During debugging or diagnostic testing, the registry value could be set in such as way as to generate lots of useful reports. This may be the only way to obtain debugging information in the field.

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

0

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

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