|
|
/*--------------------------------------------------------------------------
* * Copyright (C) Cyclades Corporation, 1999-2001. * All rights reserved. * * Cyclades-Z Enumerator Driver * * This file: log.c * * Description: This module contains contains the entry points * for a standard bus PNP / WDM driver. * * Notes: This code supports Windows 2000 and Windows XP, * x86 and ia64 processors. * * Complies with Cyclades SW Coding Standard rev 1.3. * *-------------------------------------------------------------------------- */
/*-------------------------------------------------------------------------
* * Change History * *-------------------------------------------------------------------------- * * *-------------------------------------------------------------------------- */
#include "pch.h"
typedef enum _CYZ_MEM_COMPARES { AddressesAreEqual, AddressesOverlap, AddressesAreDisjoint } CYZ_MEM_COMPARES,*PCYZ_MEM_COMPARES;
static const PHYSICAL_ADDRESS CyzPhysicalZero = {0};
CYZ_MEM_COMPARES CyzMemCompare( IN PHYSICAL_ADDRESS A, IN ULONG SpanOfA, IN PHYSICAL_ADDRESS B, IN ULONG SpanOfB )
/*++
Routine Description:
Compare two phsical address.
Arguments:
A - One half of the comparison.
SpanOfA - In units of bytes, the span of A.
B - One half of the comparison.
SpanOfB - In units of bytes, the span of B.
Return Value:
The result of the comparison.
--*/
{
LARGE_INTEGER a; LARGE_INTEGER b;
LARGE_INTEGER lower; ULONG lowerSpan; LARGE_INTEGER higher;
//PAGED_CODE(); Non paged because it can be called during CyzLogError, which is no paged now.
a = A; b = B;
if (a.QuadPart == b.QuadPart) {
return AddressesAreEqual;
}
if (a.QuadPart > b.QuadPart) {
higher = a; lower = b; lowerSpan = SpanOfB;
} else {
higher = b; lower = a; lowerSpan = SpanOfA;
}
if ((higher.QuadPart - lower.QuadPart) >= lowerSpan) {
return AddressesAreDisjoint;
}
return AddressesOverlap;
}
VOID CyzLogError( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PHYSICAL_ADDRESS P1, IN PHYSICAL_ADDRESS P2, IN ULONG SequenceNumber, IN UCHAR MajorFunctionCode, IN UCHAR RetryCount, IN ULONG UniqueErrorValue, IN NTSTATUS FinalStatus, IN NTSTATUS SpecificIOStatus, IN ULONG LengthOfInsert1, IN PWCHAR Insert1, IN ULONG LengthOfInsert2, IN PWCHAR Insert2 )
/*++
Routine Description:
This routine allocates an error log entry, copies the supplied data to it, and requests that it be written to the error log file.
Arguments:
DriverObject - A pointer to the driver object for the device.
DeviceObject - A pointer to the device object associated with the device that had the error, early in initialization, one may not yet exist.
P1,P2 - If phyical addresses for the controller ports involved with the error are available, put them through as dump data.
SequenceNumber - A ulong value that is unique to an IRP over the life of the irp in this driver - 0 generally means an error not associated with an irp.
MajorFunctionCode - If there is an error associated with the irp, this is the major function code of that irp.
RetryCount - The number of times a particular operation has been retried.
UniqueErrorValue - A unique long word that identifies the particular call to this function.
FinalStatus - The final status given to the irp that was associated with this error. If this log entry is being made during one of the retries this value will be STATUS_SUCCESS.
SpecificIOStatus - The IO status for a particular error.
LengthOfInsert1 - The length in bytes (including the terminating NULL) of the first insertion string.
Insert1 - The first insertion string.
LengthOfInsert2 - The length in bytes (including the terminating NULL) of the second insertion string. NOTE, there must be a first insertion string for their to be a second insertion string.
Insert2 - The second insertion string.
Return Value:
None.
--*/
{ PIO_ERROR_LOG_PACKET errorLogEntry;
PVOID objectToUse; SHORT dumpToAllocate = 0; PUCHAR ptrToFirstInsert; PUCHAR ptrToSecondInsert;
//PAGED_CODE(); It can be called at raised IRQL.
if (Insert1 == NULL) { LengthOfInsert1 = 0; }
if (Insert2 == NULL) { LengthOfInsert2 = 0; }
if (ARGUMENT_PRESENT(DeviceObject)) {
objectToUse = DeviceObject;
} else {
objectToUse = DriverObject;
}
if (CyzMemCompare( P1, (ULONG)1, CyzPhysicalZero, (ULONG)1 ) != AddressesAreEqual) {
dumpToAllocate = (SHORT)sizeof(PHYSICAL_ADDRESS);
}
if (CyzMemCompare( P2, (ULONG)1, CyzPhysicalZero, (ULONG)1 ) != AddressesAreEqual) {
dumpToAllocate += (SHORT)sizeof(PHYSICAL_ADDRESS);
}
errorLogEntry = IoAllocateErrorLogEntry( objectToUse, (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) + dumpToAllocate + LengthOfInsert1 + LengthOfInsert2) );
if ( errorLogEntry != NULL ) {
errorLogEntry->ErrorCode = SpecificIOStatus; errorLogEntry->SequenceNumber = SequenceNumber; errorLogEntry->MajorFunctionCode = MajorFunctionCode; errorLogEntry->RetryCount = RetryCount; errorLogEntry->UniqueErrorValue = UniqueErrorValue; errorLogEntry->FinalStatus = FinalStatus; errorLogEntry->DumpDataSize = dumpToAllocate;
if (dumpToAllocate) {
RtlCopyMemory( &errorLogEntry->DumpData[0], &P1, sizeof(PHYSICAL_ADDRESS) );
if (dumpToAllocate > sizeof(PHYSICAL_ADDRESS)) {
RtlCopyMemory( ((PUCHAR)&errorLogEntry->DumpData[0]) +sizeof(PHYSICAL_ADDRESS), &P2, sizeof(PHYSICAL_ADDRESS) );
ptrToFirstInsert = ((PUCHAR)&errorLogEntry->DumpData[0])+(2*sizeof(PHYSICAL_ADDRESS));
} else {
ptrToFirstInsert = ((PUCHAR)&errorLogEntry->DumpData[0])+sizeof(PHYSICAL_ADDRESS);
}
} else {
ptrToFirstInsert = (PUCHAR)&errorLogEntry->DumpData[0];
}
ptrToSecondInsert = ptrToFirstInsert + LengthOfInsert1;
if (LengthOfInsert1) {
errorLogEntry->NumberOfStrings = 1; errorLogEntry->StringOffset = (USHORT)(ptrToFirstInsert - (PUCHAR)errorLogEntry); RtlCopyMemory( ptrToFirstInsert, Insert1, LengthOfInsert1 );
if (LengthOfInsert2) {
errorLogEntry->NumberOfStrings = 2; RtlCopyMemory( ptrToSecondInsert, Insert2, LengthOfInsert2 );
}
}
IoWriteErrorLogEntry(errorLogEntry);
}
}
|