16.6.2  Filling in an Error Log Packet

The error log packet is defined as follows:

typedef struct _IO_ERROR_LOG_PACKET {

    UCHAR MajorFunctionCode;

    UCHAR RetryCount;

    USHORT DumpDataSize;

    USHORT NumberOfStrings;

    USHORT StringOffset;

    USHORT EventCategory;

    NTSTATUS ErrorCode;

    ULONG UniqueErrorValue;

    NTSTATUS FinalStatus;

    ULONG SequenceNumber;

    ULONG IoControlCode;

    LARGE_INTEGER DeviceOffset;

    ULONG DumpData[1];

} IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET;

 

The driver should fill in an error log packet with the following data:

MajorFunctionCode

Indicates the IRP_MJ_XXX from the driver’s I/O stack location in the current IRP.

RetryCount

Indicates how many times the driver has retried the operation and encountered this error.

RetryCount is a zero-based value. That is, the driver should set it to zero when an error is first encountered for the current IRP.

DumpDataSize

Indicates the size in bytes required for any DumpData the driver will set in the packet.

The specified value should be an integral multiple of sizeof(ULONG).

NumberOfStrings

Indicates how many insertion strings the driver will supply with this packet. NT drivers set this value to zero for errors that need no insertion strings.

The NT error-logging thread can use these driver-supplied, zero-terminated Unicode strings to fill in messages written into the Win32 event log, where it can be examined using the Win32 event viewer. The I/O Manager assumes that the initial insertion string, if any, is either the name of the driver or of the device on which the error occurred.

Insertion strings provided by a driver should be language independent.  Drivers that log errors and use insertion strings should use strings read from the registry or use names which are language independent or are the same in any language, for example, file names.

In most cases, NT device and intermediate drivers can simply log I/O errors without having to supply insertion strings for a higher-level event-logging component and/or without having to set up a driver-specific event-logging component. Of the system-supplied NT drivers, only network device drivers currently supply insertion strings in error log packets.

StringOffset

Indicates the offset, immediately following the DumpData, at which any driver-supplied insertion string data begins.

If a driver supplies this data, each string must be a zero-terminated Unicode string.

EventCategory

For drivers that install themselves in the registry as event-logging components, this is a driver-defined value that was specified in the driver’s message file for categories.

Most NT device and intermediate drivers set this value to zero. For more information about setting up an event-logging component, see Section 16.8.4.

ErrorCode

Indicates the type of error.

This is a system-defined or driver-defined constant, as described in Section 16.6.5.

UniqueErrorValue

Indicates where the error was detected in the driver.

FinalStatus

Indicates the value set in the I/O status block of the IRP when it was completed or the STATUS_XXX returned by a support routine the driver called.

SequenceNumber

Indicates a driver-assigned sequence number for the current IRP, which should be constant for the life of a given request.

IoControlCode

Indicates the I/O control code from the driver’s I/O stack location in the current IRP if the MajorFunctionCode is IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL. Otherwise, this value should be zero.

For more information about I/O control codes and device I/O control requests, see the Kernel-Mode Driver Reference.

DeviceOffset

Indicates the offset into the device where the error occurred.

DumpData

Can be used to store driver-specific data, such as register values or whatever else the driver writer decides would be useful for identifying the cause of the error.

Any driver-supplied insertion strings must be supplied immediately following the dump data, starting at StringOffset.