Windows-Server-2003/net/nwlink/spx/spxerror.c

329 lines
9.2 KiB
C

/*++
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;
}