|
|
/*++
Copyright (c) 1989-1993 Microsoft Corporation
Module Name:
spxerror.c
Abstract:
This module contains code which provides error logging support.
Author:
Nikhil Kamkolkar (nikhilk) 11-November-1993
Environment:
Kernel mode
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#ifndef __PREFAST__
#pragma warning(disable:4068)
#endif
#pragma prefast(disable:276, "The assignments are harmless")
// Define module number for event logging entries
#define FILENUM SPXERROR
LONG SpxLastRawDataLen = 0; NTSTATUS SpxLastUniqueErrorCode = STATUS_SUCCESS; NTSTATUS SpxLastNtStatusCode = STATUS_SUCCESS; ULONG SpxLastErrorCount = 0; LONG SpxLastErrorTime = 0; BYTE SpxLastRawData[PORT_MAXIMUM_MESSAGE_LENGTH - \ sizeof(IO_ERROR_LOG_PACKET)] = {0};
BOOLEAN SpxFilterErrorLogEntry( IN NTSTATUS UniqueErrorCode, IN NTSTATUS NtStatusCode, IN PVOID RawDataBuf OPTIONAL, IN LONG RawDataLen ) /*++
Routine Description:
Arguments:
Return Value:
--*/ {
int insertionStringLength = 0;
// Filter out events such that the same event recurring close together does not
// cause errorlog clogging. The scheme is - if the event is same as the last event
// and the elapsed time is > THRESHOLD and ERROR_CONSEQ_FREQ simulataneous errors
// have happened, then log it else skip
if ((UniqueErrorCode == SpxLastUniqueErrorCode) && (NtStatusCode == SpxLastNtStatusCode)) { SpxLastErrorCount++; if ((SpxLastRawDataLen == RawDataLen) && (RtlEqualMemory(SpxLastRawData, RawDataBuf, RawDataLen)) && ((SpxLastErrorCount % ERROR_CONSEQ_FREQ) != 0) && ((SpxGetCurrentTime() - SpxLastErrorTime) < ERROR_CONSEQ_TIME)) { return(FALSE); } }
SpxLastUniqueErrorCode = UniqueErrorCode; SpxLastNtStatusCode = NtStatusCode; SpxLastErrorCount = 0; SpxLastErrorTime = SpxGetCurrentTime(); if (RawDataLen != 0) { SpxLastRawDataLen = RawDataLen; RtlCopyMemory( SpxLastRawData, RawDataBuf, RawDataLen); }
return(TRUE); }
VOID SpxWriteResourceErrorLog( IN PDEVICE Device, IN ULONG BytesNeeded, IN ULONG UniqueErrorValue )
/*++
Routine Description:
This routine allocates and writes an error log entry indicating an out of resources condition.
Arguments:
Device - Pointer to the device context.
BytesNeeded - If applicable, the number of bytes that could not be allocated.
UniqueErrorValue - Used as the UniqueErrorValue in the error log packet.
Return Value:
None.
--*/
{ PIO_ERROR_LOG_PACKET errorLogEntry; UCHAR EntrySize; PUCHAR StringLoc; ULONG TempUniqueError; static WCHAR UniqueErrorBuffer[4] = L"000"; INT i;
if (!SpxFilterErrorLogEntry( EVENT_TRANSPORT_RESOURCE_POOL, STATUS_INSUFFICIENT_RESOURCES, (PVOID)&BytesNeeded, sizeof(BytesNeeded))) { return; }
EntrySize = sizeof(IO_ERROR_LOG_PACKET) + Device->dev_DeviceNameLen + sizeof(UniqueErrorBuffer);
errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( (PDEVICE_OBJECT)Device, EntrySize);
// Convert the error value into a buffer.
TempUniqueError = UniqueErrorValue; for (i=1; i>=0; i--) { UniqueErrorBuffer[i] = (WCHAR)((TempUniqueError % 10) + L'0'); TempUniqueError /= 10; }
if (errorLogEntry != NULL) { errorLogEntry->MajorFunctionCode = (UCHAR)-1; errorLogEntry->RetryCount = (UCHAR)-1; errorLogEntry->DumpDataSize = sizeof(ULONG); errorLogEntry->NumberOfStrings = 2; errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET); errorLogEntry->EventCategory = 0; errorLogEntry->ErrorCode = EVENT_TRANSPORT_RESOURCE_POOL; errorLogEntry->UniqueErrorValue = UniqueErrorValue; errorLogEntry->FinalStatus = STATUS_INSUFFICIENT_RESOURCES; errorLogEntry->SequenceNumber = (ULONG)-1; errorLogEntry->IoControlCode = 0; errorLogEntry->DumpData[0] = BytesNeeded;
StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset; RtlCopyMemory( StringLoc, Device->dev_DeviceName, Device->dev_DeviceNameLen);
StringLoc += Device->dev_DeviceNameLen; RtlCopyMemory( StringLoc, UniqueErrorBuffer, sizeof(UniqueErrorBuffer));
IoWriteErrorLogEntry(errorLogEntry); } }
VOID SpxWriteGeneralErrorLog( IN PDEVICE Device, IN NTSTATUS ErrorCode, IN ULONG UniqueErrorValue, IN NTSTATUS FinalStatus, IN PWSTR SecondString, IN PVOID RawDataBuf OPTIONAL, IN LONG RawDataLen )
/*++
Routine Description:
This routine allocates and writes an error log entry indicating a general problem as indicated by the parameters. It handles event codes REGISTER_FAILED, BINDING_FAILED, ADAPTER_NOT_FOUND, TRANSFER_DATA, TOO_MANY_LINKS, and BAD_PROTOCOL. All these events have messages with one or two strings in them.
Arguments:
Device - Pointer to the device context, or this may be a driver object instead.
ErrorCode - The transport event code.
UniqueErrorValue - Used as the UniqueErrorValue in the error log packet.
FinalStatus - Used as the FinalStatus in the error log packet.
SecondString - If not NULL, the string to use as the %3 value in the error log packet.
RawDataBuf - The number of ULONGs of dump data.
RawDataLen - Dump data for the packet.
Return Value:
None.
--*/
{ PIO_ERROR_LOG_PACKET errorLogEntry; UCHAR EntrySize; ULONG SecondStringSize; PUCHAR StringLoc; static WCHAR DriverName[4] = L"Spx";
if (!SpxFilterErrorLogEntry( ErrorCode, FinalStatus, RawDataBuf, RawDataLen)) { return; }
#ifdef DBG
if ( sizeof(IO_ERROR_LOG_PACKET) + RawDataLen > 255) { DbgPrint("Size greater than maximum entry size 255.\n"); } #endif
EntrySize = (UCHAR) (sizeof(IO_ERROR_LOG_PACKET) + RawDataLen); if (Device->dev_Type == SPX_DEVICE_SIGNATURE) { EntrySize += (UCHAR)Device->dev_DeviceNameLen; } else { EntrySize += sizeof(DriverName); }
if (SecondString) { SecondStringSize = (wcslen(SecondString)*sizeof(WCHAR)) + sizeof(UNICODE_NULL); EntrySize += (UCHAR)SecondStringSize; }
errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( (PDEVICE_OBJECT)Device, EntrySize);
if (errorLogEntry != NULL) { errorLogEntry->MajorFunctionCode = (UCHAR)-1; errorLogEntry->RetryCount = (UCHAR)-1; errorLogEntry->DumpDataSize = (USHORT)RawDataLen; errorLogEntry->NumberOfStrings = (SecondString == NULL) ? 1 : 2; errorLogEntry->StringOffset = (USHORT) (sizeof(IO_ERROR_LOG_PACKET) + RawDataLen); errorLogEntry->EventCategory = 0; errorLogEntry->ErrorCode = ErrorCode; errorLogEntry->UniqueErrorValue = UniqueErrorValue; errorLogEntry->FinalStatus = FinalStatus; errorLogEntry->SequenceNumber = (ULONG)-1; errorLogEntry->IoControlCode = 0;
if (RawDataLen != 0) { RtlCopyMemory(errorLogEntry->DumpData, RawDataBuf, RawDataLen); }
StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset; if (Device->dev_Type == SPX_DEVICE_SIGNATURE) { RtlCopyMemory( StringLoc, Device->dev_DeviceName, Device->dev_DeviceNameLen);
StringLoc += Device->dev_DeviceNameLen; } else { RtlCopyMemory (StringLoc, DriverName, sizeof(DriverName)); StringLoc += sizeof(DriverName); }
if (SecondString) { RtlCopyMemory (StringLoc, SecondString, SecondStringSize); }
IoWriteErrorLogEntry(errorLogEntry); }
return; }
|