The final hurdle to overcome is registering your driver as an event source so that the event viewer knows where to find your message text resource. Two registry changes must be made.

First, the HKLMSystemCurrentControlSetServicesEventLogSystem key has an existing REG_MULTI_SZ value called Sources. Add the name of your driver's executable (without the extension) as a line in Sources.

In this same registry key, make a new subkey with this same driver name. In this subkey, add a REG_EXPAND_SZ value called EventMessageFile and set a REG_DWORD called TypesSupported with a value of 0x7. For Wdm3, set EventMessageFile to the following value.

%SystemRoot%System32IoLogMsg.dll;%SystemRoot%System32DriversWdm3.sys

The Wdm3 installation INF file supposedly has the correct information to make these registry changes when a Wdm3 device is installed. Listing 13.4 shows the amendments made to the standard installation file. The AddService directive's last field specifies the name of the section containing the error logging registry values. There are optional fields to specify the log type (System, Security, or Application) and a log name.

The Wdm3.Service.EventLog section specifies the values for the EventMessageFile and TypesSupported values. The EventMessageFile entry is on one long line.

However, I found that this did not work completely in Windows 2000 Beta 3. 'Wdm3' was correctly added to the Sources value and the HKLMSystemCurrentControlSetServicesEventLog SystemWdm3 key was correctly made, but no values were placed in the key.

It is simplest just to add these registry entries by hand. You will have to use RegEdt32 to use the required registry types.

Note: A revised version of installation file Wdm3sysWdm3free.inf is available on the book's web site, www.phdcc.com/wdmbook. This updated version fixes the EventLog section problem. 

For NT 3.51 and NT 4 drivers, you cannot use an INF installation file. Instead, you will have to amend your installation program to set up the registry entries. The example installation code, install.cpp (on the book's CD-ROM) shows how to do this job.

Listing 13.4 Wdm3free.inf installation file event logging sections

[Wdm3.Install.NT.Services]

AddService =

 Wdm3, %SPSVCINST_ASSOCSERVICE%, Wdm3.Service, Wdm3.Service.EventLog

; …

[Wdm3.Service.EventLog]

HKR,,EventMessageFile,%FLG_ADDREG_TYPE_EXPAND_SZ%,

 '%%SystemRoot%%System32IoLogMsg.dll;

  %%SystemRoot%%System32driversWdm3.sys'

HKR,,TypesSupported,%FLG_ADDREG_TYPE_DW0RD%,7

Generating Events

Listing 13.5 shows the routines that provide the event logging, InitializeEventLog, and LogEvent. Later, I shall describe the Wdm3EventMessage function that provides a simpler interface.

InitializeEventLog is simply used to store a pointer to the main DriverObject. It then calls LogEvent to send a WDM3_MSG_LOGGING_STARTED event. If all's well, this should be displayed in the Event Viewer with the corresponding description, 'Event logging enabled for Wdm3 Driver'.

LogEvent does the bulk of the work in logging an NT event. It may be called at DISPATCH_ LEVEL or lower. Its first task is to decide the size of the error log packet. It then calls IoAllocateErrorLogEntry to obtain a suitably sized packet. It then fills the packet and sends it off using IoWriteErrorLogEntry.

LogEvent has parameters for the message ID (from the list in Wdm3Msg.h) and optionally an IRP pointer. If the IRP pointer is given, various fields in the packet are filled in with details of the IRP. LogEvent can also accept DumpData and Strings as parameters, for insertion into the event packet.

The basic IO_ERR0R_L0G_PACKET structure contains one dump data ULONG, but no insertion strings. It is an extendible structure. Zero or more dump data ULONGs can be provided, followed immediately by any NULL terminated wide strings. This makes calculating and filling the packet size slightly involved. LogEvent saves each string length in a temporary array of integers called StringSizes. Note that the maximum packet size, ERROR_LOG_MAXIMUM_SIZE, is only 0x98 bytes, so do not try to pass large insertion strings.

Listing 13.5 InitializeEventLog and LogEvent routines

void InitializeEventLog(IN PDRIVER_OBJECT DriverObject) {

 SavedDriverObject = DriverObject;

 // Log a message saying that logging is started.

 LogEvent(WDM3_MSG_LOGGING_STARTED, NULL, // IRP

  NULL, 0, // dump data

  NULL, 0); // strings

}

bool LogEvent(IN NTSTATUS ErrorCode, IN PIRP Irp, IN ULONG DumpData[], IN int DumpDataCount, IN PWSTR Strings[], IN int StringCount) {

 if (SavedDriverObject==NULL) return false;

 // Start working out size of complete event packet

 int size = sizeof(IO_ERROR_LOG_PACKET);

 // Add in dump data size.

 // Less one as DumpData already has 1 ULONG in IO_ERROR_LOG_PACKET

 if (DumpDataCount>0) size += sizeof(ULONG) * (DumpDataCount-1);

 // Add in space needed for insertion strings (inc terminating NULLs)

 int* StringSizes = NULL;

 if (StringCount>0) {

  StringSizes = (int*)ExAllocatePool(NonPagedPool, StringCount*sizeof(int));

  if (StringSizes==NULL) return false;

  // Remember each string size

  for (int i=0; i<StringCount; i++) {

   StringSizes[i] = (int)GetWideStringSize(Strings[i]);

   size += StringSizes[i ];

  }

 }

 if (size>ERROR_LOG_MAXIMUM_SIZE) // 0x98!

 {

  if (StringSizes!=NULL) ExFreePool(StringSizes);

  return false;

 }

 // Try to allocate the packet

 PIO_ERROR_LOG_PACKET Packet = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(SavedDriverObject, size);

 if (Packet==NULL) {

  if (StringSizes!=NULL) ExFreePool(StringSizes);

  return false;

 }

 // Fill in standard parts of the packet

 Packet->ErrorCode = ErrorCode;

 Packet->UniqueErrorValue = 0;

 // Fill in IRP related fields

 Packet->MajorFunctionCode = 0;

 Packet->RetryCount = 0;

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

0

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

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