VOID YtLogError( IN PDEVICE_OBJECT DeviceObject, IN ULONG UniqueId, IN NTSTATUS ErrorCode, IN NTSTATUS Status ) { PIO_ERROR_LOG_PACKET errorLogEntry; errorLogEntry = (PIO_ERROR_LOG_PACKET) IoAllocateErrorLogEntry( DeviceObject, (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) + sizeof(DEVICE_OBJECT)) ); if (errorLogEntry != NULL) { errorLogEntry->ErrorCode = ErrorCode; errorLogEntry->UniqueErrorValue = UniqueId; errorLogEntry->FinalStatus = Status; /*The following is necessary because DumpData is of type ULONG and DeviceObject can be more than that.*/ RtlCopyMemory( &errorLogEntry->DumpData[0], &DeviceObject, sizeof(DEVICE_OBJECT)); errorLogEntry->DumpDataSize = sizeof(DEVICE_OBJECT); IoWriteErrorLogEntry(errorLogEntry); } }
void PPJoyBus_WriteEventLog (NTSTATUS ErrorMessageCode, PVOID DumpData, USHORT DumpSize, PCWSTR Message) { PIO_ERROR_LOG_PACKET LogPacket; PUCHAR StrPtr; USHORT MsgLen; PAGED_CODE(); if (!Message) Message= L""; MsgLen= (wcslen(Message)+1)*sizeof(WCHAR); DumpSize= (DumpSize+1) & 0xFC; if (!DumpData) DumpSize= 0; LogPacket= IoAllocateErrorLogEntry (Globals.DriverObject,(UCHAR)(sizeof(IO_ERROR_LOG_PACKET)+DumpSize+MsgLen)); if (!LogPacket) { PPJOY_DBGPRINT (FILE_EVENTLOG|PPJOY_ERROR, ("Cannot allocate LogEntry packet!!") ); return; } StrPtr= ((PUCHAR)LogPacket->DumpData)+DumpSize; LogPacket->MajorFunctionCode= 0; LogPacket->RetryCount= 0; LogPacket->DumpDataSize= DumpSize; LogPacket->NumberOfStrings= (*Message)?1:0; LogPacket->StringOffset= (USHORT) (StrPtr-(PUCHAR)LogPacket); // LogPacket->EventCategory= 0; LogPacket->ErrorCode= ErrorMessageCode; LogPacket->UniqueErrorValue= 0; LogPacket->FinalStatus= STATUS_SUCCESS; LogPacket->SequenceNumber= 0; if (DumpData) RtlCopyMemory(LogPacket->DumpData,DumpData,DumpSize); if (*Message) { RtlCopyMemory(StrPtr,Message,MsgLen); StrPtr+= MsgLen; } PPJOY_DBGPRINT (FILE_EVENTLOG|PPJOY_BABBLE, ("Writing EventLog entry 0x%p",LogPacket) ); IoWriteErrorLogEntry (LogPacket); }
VOID mvolLogError(PDEVICE_OBJECT DeviceObject, ULONG UniqID, NTSTATUS ErrorCode, NTSTATUS Status) { PIO_ERROR_LOG_PACKET pLogEntry; PROOT_EXTENSION RootExtension = NULL; PVOLUME_EXTENSION VolumeExtension = NULL; PWCHAR wp; USHORT len, deviceNameLength; if( mvolRootDeviceObject == DeviceObject ) { RootExtension = DeviceObject->DeviceExtension; deviceNameLength = RootExtension->PhysicalDeviceNameLength; } else { VolumeExtension = DeviceObject->DeviceExtension; deviceNameLength = VolumeExtension->PhysicalDeviceNameLength; } len = sizeof(IO_ERROR_LOG_PACKET) + deviceNameLength + 4; pLogEntry = (PIO_ERROR_LOG_PACKET) IoAllocateErrorLogEntry(mvolDriverObject, (UCHAR) len); if (pLogEntry == NULL) { WDRBD_ERROR("cannot alloc Log Entry\n"); return; } RtlZeroMemory(pLogEntry, len); pLogEntry->ErrorCode = ErrorCode; pLogEntry->UniqueErrorValue = UniqID; pLogEntry->FinalStatus = Status; pLogEntry->DumpDataSize = 0; pLogEntry->NumberOfStrings = 1; // -> 1 for %2, 2 for %3...! %1 is driver obkect! pLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET) +pLogEntry->DumpDataSize; wp = (PWCHAR) ((PCHAR) pLogEntry + pLogEntry->StringOffset); if( RootExtension != NULL ) wcscpy(wp, RootExtension->PhysicalDeviceName); else wcscpy(wp, VolumeExtension->PhysicalDeviceName); wp += deviceNameLength / sizeof(WCHAR); *wp = 0; IoWriteErrorLogEntry(pLogEntry); }
/* Really have no idea of the unicode string, so no insertion string input */ int write_event(NTSTATUS err_code, PVOID obj, void *dump_data, int dsize) { uint8_t dump_size = 0; PIO_ERROR_LOG_PACKET packet; if (dump_data) dump_size = (dsize + sizeof(ULONG) - 1) & ~(sizeof(ULONG) - 1); if ((dump_size + sizeof(IO_ERROR_LOG_PACKET)) > ERROR_LOG_MAXIMUM_SIZE) return -1; packet = IoAllocateErrorLogEntry(obj, sizeof(IO_ERROR_LOG_PACKET) + dump_size); if (packet == NULL) return -1; packet->ErrorCode = err_code; packet->DumpDataSize = dump_size; if (dump_data) { memcpy_s(&packet->DumpData[0], sizeof(IO_ERROR_LOG_PACKET) + dump_size, dump_data, dump_size); } /* DumpData should be multiple of sizeof(ulong) */ IoWriteErrorLogEntry(packet); return 0; }
VOID ImScsiLogDbgError(IN PVOID Object, IN UCHAR MajorFunctionCode, IN UCHAR RetryCount, IN PULONG DumpData, IN USHORT DumpDataSize, IN USHORT EventCategory, IN NTSTATUS ErrorCode, IN ULONG UniqueErrorValue, IN NTSTATUS FinalStatus, IN ULONG SequenceNumber, IN ULONG IoControlCode, IN PLARGE_INTEGER DeviceOffset, IN PWCHAR Message) { ULONG_PTR string_byte_size; ULONG_PTR packet_size; PIO_ERROR_LOG_PACKET error_log_packet; if (KeGetCurrentIrql() > DISPATCH_LEVEL) return; string_byte_size = (wcslen(Message) + 1) << 1; packet_size = sizeof(IO_ERROR_LOG_PACKET) + DumpDataSize + string_byte_size; if (packet_size > ERROR_LOG_MAXIMUM_SIZE) { KdPrint(("ImDisk: Warning: Too large error log packet.\n")); return; } error_log_packet = (PIO_ERROR_LOG_PACKET) IoAllocateErrorLogEntry(Object, (UCHAR) packet_size); if (error_log_packet == NULL) { KdPrint(("ImDisk: Warning: IoAllocateErrorLogEntry() returned NULL.\n")); return; } error_log_packet->MajorFunctionCode = MajorFunctionCode; error_log_packet->RetryCount = RetryCount; error_log_packet->StringOffset = sizeof(IO_ERROR_LOG_PACKET) + DumpDataSize; error_log_packet->EventCategory = EventCategory; error_log_packet->ErrorCode = ErrorCode; error_log_packet->UniqueErrorValue = UniqueErrorValue; error_log_packet->FinalStatus = FinalStatus; error_log_packet->SequenceNumber = SequenceNumber; error_log_packet->IoControlCode = IoControlCode; if (DeviceOffset != NULL) error_log_packet->DeviceOffset = *DeviceOffset; error_log_packet->DumpDataSize = DumpDataSize; if (DumpDataSize != 0) memcpy(error_log_packet->DumpData, DumpData, DumpDataSize); if (Message == NULL) error_log_packet->NumberOfStrings = 0; else { error_log_packet->NumberOfStrings = 1; memcpy((PUCHAR)error_log_packet + error_log_packet->StringOffset, Message, string_byte_size); } IoWriteErrorLogEntry(error_log_packet); }
////////////////////////////////////////////////////////////////////////// // // Event log // static VOID _WriteLogErrorEntry( IN PDEVICE_OBJECT DeviceObject, IN PLSU_ERROR_LOG_ENTRY LogEntry ){ PIO_ERROR_LOG_PACKET errorLogEntry; WCHAR strBuff[16]; NTSTATUS status; ULONG stringOffset; ULONG_PTR stringLen; ULONG idx_dump; // // Parameter to unicode string // ASSERT(LogEntry->DumpDataEntry <= LSU_MAX_ERRLOG_DATA_ENTRIES); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); status = RtlStringCchPrintfW(strBuff, 16, L"%u", LogEntry->Parameter2); if(!NT_SUCCESS(status)) { KDPrint(1, ("RtlStringCchVPrintfW() failed.\n")); return; } status = RtlStringCchLengthW(strBuff, 16, &stringLen); if(!NT_SUCCESS(status)) { KDPrint(1, ("RtlStringCchLengthW() failed.\n")); return; } // // Translate unicode length into byte length including NULL termination. // stringLen = ( stringLen + 1 ) * sizeof(WCHAR); stringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) + LogEntry->DumpDataEntry * sizeof(ULONG); errorLogEntry = (PIO_ERROR_LOG_PACKET) IoAllocateErrorLogEntry( DeviceObject, (sizeof(IO_ERROR_LOG_PACKET) + (LogEntry->DumpDataEntry * sizeof(ULONG)) + (UCHAR)stringLen)); if(errorLogEntry == NULL) { KDPrint(1, ("Could not allocate error log entry.\n")); ASSERT(FALSE); return ; } errorLogEntry->ErrorCode = LogEntry->ErrorCode; errorLogEntry->MajorFunctionCode = LogEntry->MajorFunctionCode; errorLogEntry->IoControlCode = LogEntry->IoctlCode; errorLogEntry->EventCategory; errorLogEntry->SequenceNumber = LogEntry->SequenceNumber; errorLogEntry->RetryCount = (UCHAR) LogEntry->ErrorLogRetryCount; errorLogEntry->UniqueErrorValue = LogEntry->UniqueId; errorLogEntry->FinalStatus = STATUS_SUCCESS; errorLogEntry->DumpDataSize = LogEntry->DumpDataEntry * sizeof(ULONG); for(idx_dump=0; idx_dump < LogEntry->DumpDataEntry; idx_dump++) { errorLogEntry->DumpData[idx_dump] = LogEntry->DumpData[idx_dump]; } errorLogEntry->NumberOfStrings = 1; errorLogEntry->StringOffset = (USHORT)stringOffset; RtlCopyMemory((PUCHAR)errorLogEntry + stringOffset, strBuff, stringLen); IoWriteErrorLogEntry(errorLogEntry); return; }
VOID BusErrorLogDpc( IN PKDPC Dpc, IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++ Routine Description: This routine runs at DISPATCH_LEVEL IRQL to log errors that are discovered at IRQL > DISPATCH_LEVEL (e.g., in the ISR routine or in a routine that is executed via KeSynchronizeExecution). There is not necessarily a current request associated with this condition. Arguments: Dpc - Pointer to the DPC object. DeviceObject - Pointer to the device object. Irp - Not used. Context - Indicates type of error to log. Return Value: None. --*/ { PDEVICE_EXTENSION deviceExtension; PIO_ERROR_LOG_PACKET errorLogEntry; UNREFERENCED_PARAMETER(Dpc); UNREFERENCED_PARAMETER(Irp); BusPrint((2, "BusErrorLogDpc: enter\n")); deviceExtension = DeviceObject->DeviceExtension; // // Log an error packet. // errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( DeviceObject, sizeof(IO_ERROR_LOG_PACKET) + (2 * sizeof(ULONG)) ); if (errorLogEntry != NULL) { errorLogEntry->DumpDataSize = 2 * sizeof(ULONG); if ((ULONG) Context == BUSMOUSE_MOU_BUFFER_OVERFLOW) { errorLogEntry->UniqueErrorValue = BUSMOUSE_ERROR_VALUE_BASE + 210; errorLogEntry->DumpData[0] = sizeof(MOUSE_INPUT_DATA); errorLogEntry->DumpData[1] = deviceExtension->Configuration.MouseAttributes.InputDataQueueLength; } else { errorLogEntry->UniqueErrorValue = BUSMOUSE_ERROR_VALUE_BASE + 220; errorLogEntry->DumpData[0] = 0; errorLogEntry->DumpData[1] = 0; } errorLogEntry->ErrorCode = (ULONG) Context; errorLogEntry->SequenceNumber = 0; errorLogEntry->MajorFunctionCode = 0; errorLogEntry->IoControlCode = 0; errorLogEntry->RetryCount = 0; errorLogEntry->FinalStatus = 0; IoWriteErrorLogEntry(errorLogEntry); } BusPrint((2, "BusErrorLogDpc: exit\n")); }
VOID LogError( IN NTSTATUS ErrorCode, IN NTSTATUS NTStatus, IN ULONG UniqueID OPTIONAL, IN PCWSTR String1 OPTIONAL, IN PCWSTR String2 OPTIONAL ) { TEnter(Func, ("(ErrorCode=%x,NTStatus=%x,UniqueID=%x,Str1=%S,Str2=%S)", ErrorCode, NTStatus, UniqueID, String1? String1: L"", String2? String2: L"")); TAssert(gDriverObj != NULL); if (gDriverObj != NULL) { ULONG_PTR len1, len2, len; PIO_ERROR_LOG_PACKET ErrEntry; len1 = String1? (wcslen(String1) + 1)*sizeof(WCHAR): 0; len2 = String2? (wcslen(String2) + 1)*sizeof(WCHAR): 0; len = len1 + len2 + FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData); len = max(len, sizeof(IO_ERROR_LOG_PACKET)); // Thoroughly check the value of len to prevent buffer underflows/overflows if ((len > 0) && (len <= 255) && (len1 <= len) && (len2 <= len)) { ErrEntry = IoAllocateErrorLogEntry(gDriverObj, (UCHAR)len); if (ErrEntry) { PUCHAR pbBuff = (PUCHAR)ErrEntry + FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData); ErrEntry->NumberOfStrings = 0; if (len1 > 0) { ErrEntry->NumberOfStrings++; RtlCopyMemory(pbBuff, String1, len1); pbBuff += len1; } if (len2 > 0) { ErrEntry->NumberOfStrings++; RtlCopyMemory(pbBuff, String2, len2); pbBuff += len2; } ErrEntry->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData); ErrEntry->ErrorCode = ErrorCode; ErrEntry->FinalStatus = NTStatus; ErrEntry->UniqueErrorValue = UniqueID; IoWriteErrorLogEntry(ErrEntry); } else { TWarn(("Failed to allocate error log entry (len=%d).", (int)len)); } } else { TWarn(("Error log entry too big (len=%d).", (int)len)); } } TExit(Func, ("!")); return; } //LogError
VOID __cdecl LogDbgMsg( IN NTSTATUS ErrorCode, IN NTSTATUS NTStatus OPTIONAL, _In_z_ LPCSTR pszFormat, ... ) { #define MAX_ERRMSG_LEN ((ERROR_LOG_MAXIMUM_SIZE - \ FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData)) \ /sizeof(WCHAR)) static char szErrMsg[MAX_ERRMSG_LEN] = {0}; TEnter(Func, ("(ErrorCode=%x,NTStatus=%x,Format=%s)", ErrorCode, NTStatus, pszFormat)); TAssert(gDriverObj != NULL); if (gDriverObj != NULL) { va_list arglist; NTSTATUS status; size_t iLen = 0; ULONG_PTR iTotalLen; PIO_ERROR_LOG_PACKET ErrEntry; va_start(arglist, pszFormat); status = RtlStringCchVPrintfA(szErrMsg, ARRAYSIZE(szErrMsg), pszFormat, arglist); va_end(arglist); if (NT_SUCCESS(status)) { status = RtlStringCchLengthA(szErrMsg, ARRAYSIZE(szErrMsg), &iLen); } if (NT_SUCCESS(status)) { iTotalLen = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) + (iLen + 1)*sizeof(WCHAR); iTotalLen = max(iTotalLen, sizeof(IO_ERROR_LOG_PACKET)); ErrEntry = IoAllocateErrorLogEntry(gDriverObj, (UCHAR)iTotalLen); if (ErrEntry) { ErrEntry->NumberOfStrings = 1; ErrEntry->ErrorCode = ErrorCode; ErrEntry->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData); mbstowcs((WCHAR *)ErrEntry->DumpData, szErrMsg, iLen); ErrEntry->FinalStatus = NTStatus; IoWriteErrorLogEntry(ErrEntry); } else { TWarn(("Failed to allocate error log entry (len=%d).", (int)iTotalLen)); } if (ErrorCode == ERRLOG_DEBUG_INFORMATION) { TInfo(("%s", szErrMsg)); } else if (ErrorCode == ERRLOG_DEBUG_WARNING) { TWarn(("%s", szErrMsg)); } else if (ErrorCode == ERRLOG_DEBUG_ERROR) { TErr(("%s", szErrMsg)); } } } TExit(Func, ("!")); return; } //LogDbgMsg
VOID Ik220LogError( 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(); if (Insert1 == NULL) { LengthOfInsert1 = 0; } if (Insert2 == NULL) { LengthOfInsert2 = 0; } if (ARGUMENT_PRESENT(DeviceObject)) { objectToUse = DeviceObject; } else { objectToUse = DriverObject; } if (Ik220MemCompare( P1, (ULONG)1, Ik220PhysicalZero, (ULONG)1 ) != AddressesAreEqual) { dumpToAllocate = (SHORT)sizeof(PHYSICAL_ADDRESS); } if (Ik220MemCompare( P2, (ULONG)1, Ik220PhysicalZero, (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); } }
/*! \brief Log an error entry in the system log Log an error entry in the system log. \param Fdo Pointer to a DEVICE_OBJECT structure. This is the device object for the target device, previously created by the driver's AddDevice routine. \param ErrorCode The NTSTATUS code which should be reported on behalf of this error log entry \param String1 Pointer to the 1st (WCHAR) string which has to be included into the error log entry. This can be NULL if no string is to be inserted. \param String2 Pointer to the 2nd (WCHAR) string which has to be included into the error log entry. This can be NULL if no string is to be inserted. */ VOID LogError(IN PDEVICE_OBJECT Fdo, IN NTSTATUS ErrorCode, const WCHAR *String1, const WCHAR *String2) { USHORT stringSize; USHORT stringOffset; USHORT stringSize1; USHORT stringSize2; USHORT size; USHORT numberOfStrings; FUNC_ENTER(); // IoAllocateErrorLogEntry() and IoWriteErrorLogEntry() require this DBG_IRQL( <= DISPATCH_LEVEL); // calculate the size of the strings numberOfStrings = 0; // Check if there is a string 1, and calculate its size // (including the trailing zero) stringSize1 = String1 ? (++numberOfStrings, sizeof(WCHAR) * (wcslen(String1) + 1)) : 0; // Check if there is a string 2, and calculate its size // (including the trailing zero) stringSize2 = String2 ? (++numberOfStrings, sizeof(WCHAR) * (wcslen(String2) + 1)) : 0; // Add the sizes of both strings // This is the size of what has to be added to the error log entry stringSize = stringSize1 + stringSize2; // Offset where the string(s) will be written into the error log entry stringOffset = sizeof(IO_ERROR_LOG_PACKET); // The complete size of the event log entry size = stringOffset + stringSize; // Make sure we don't need more space than needed. // For debugging purposes, have an DBG_ASSERT(). Anyway, // in the wild, don't do anything if the size is too big. // Remember: Not being able to write a log is not an error! /*! \todo Would it make sense to short the strings if the * error log entry would be too big? */ DBG_ASSERT(size <= ERROR_LOG_MAXIMUM_SIZE); if (size <= ERROR_LOG_MAXIMUM_SIZE) { PIO_ERROR_LOG_PACKET pentry; // allocate the entry for the error log DBG_IRQL( <= DISPATCH_LEVEL); pentry = IoAllocateErrorLogEntry(Fdo, (UCHAR) size); DBG_ASSERT(pentry); if (pentry) { // clear the complete entry (to be sure) RtlZeroMemory(pentry, sizeof(*pentry)); // Write the relevant entries pentry->NumberOfStrings = numberOfStrings; pentry->StringOffset = stringOffset; pentry->ErrorCode = ErrorCode; // If there was a string1, write that into the entry if (String1) { wcscpy((wchar_t*)&((UCHAR*)pentry)[stringOffset], String1); } // If there was a string2, write that into the entry if (String2) { wcscpy((wchar_t*)&((UCHAR*)pentry)[stringOffset + stringSize1], String2); } // Now, give that entry to the system DBG_IRQL( <= DISPATCH_LEVEL); IoWriteErrorLogEntry(pentry); } }
static VOID ssh_event_log_cb(SshLogFacility facility, SshLogSeverity severity, const char *msg, PDRIVER_OBJECT driver) { PIO_ERROR_LOG_PACKET pkt; UNICODE_STRING uc; ANSI_STRING ansi; size_t pkt_size; if (msg == NULL) return; if ((SSH_GET_IRQL() > SSH_PASSIVE_LEVEL) && (the_interceptor != NULL)) { /* Event logging can't be performed at a raised IRQL, so we have to schedule a work item to complete the operation */ SshEventLogRequest request = ssh_calloc(1, sizeof(*request)); if (request == NULL) return; request->msg = ssh_strdup(msg); if (request->msg == NULL) { ssh_free(request); return; } request->facility = facility; request->severity = severity; request->driver = driver; if (ssh_ndis_wrkqueue_queue_item(the_interceptor->work_queue, ssh_event_log_work_queue_cb, request) == FALSE) { ssh_free(request->msg); ssh_free(request); } return; } /* Compose unicode error message string */ RtlInitAnsiString(&ansi, msg); /* Calculate the maximum length a error log entry can contain */ uc.Length = 0; uc.MaximumLength = ansi.MaximumLength * sizeof(WCHAR); if ((sizeof(IO_ERROR_LOG_PACKET) + uc.MaximumLength) > ERROR_LOG_MAXIMUM_SIZE) { char *msg_copy; /* The message must be splitted into several fragments */ uc.MaximumLength = ERROR_LOG_MAXIMUM_SIZE - sizeof(IO_ERROR_LOG_PACKET); ansi.MaximumLength = uc.MaximumLength / sizeof(WCHAR); ansi.Length = ansi.MaximumLength-1; /* Remember to copy the original message before truncating. Otherwice we _could_ cause some ugly side effects in the calling code. */ msg_copy = ssh_strdup(msg); if (msg_copy != NULL) { /* We write the tail of the message first, so the fractions are displayed in sensible order (with the default setup of the Windows' Event Viever) */ ssh_event_log_cb(facility, severity, &(msg_copy[ansi.Length]), driver); msg_copy[ansi.Length] = 0x00; ssh_event_log_cb(facility, severity, msg_copy, driver); ssh_free(msg_copy); } return; } /* Calc error log packet size */ pkt_size = sizeof(IO_ERROR_LOG_PACKET) + uc.MaximumLength; SSH_ASSERT(pkt_size <= ERROR_LOG_MAXIMUM_SIZE); /* Allocate error log entry */ pkt = IoAllocateErrorLogEntry(driver, (UCHAR)pkt_size); if (pkt != NULL) { switch (severity) { case SSH_LOG_INFORMATIONAL: pkt->ErrorCode = SSH_MSG_INFORMATIONAL; break; case SSH_LOG_NOTICE: pkt->ErrorCode = SSH_MSG_NOTICE; break; case SSH_LOG_WARNING: pkt->ErrorCode = SSH_MSG_WARNING; break; case SSH_LOG_ERROR: pkt->ErrorCode = SSH_MSG_ERROR; break; case SSH_LOG_CRITICAL: pkt->ErrorCode = SSH_MSG_CRITICAL; break; default: SSH_NOTREACHED; break; } /* Init the attributes of error log entry */ pkt->MajorFunctionCode = 0; pkt->RetryCount = 0; pkt->DumpDataSize = 0; pkt->NumberOfStrings = 1; pkt->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData); pkt->EventCategory = 0; pkt->UniqueErrorValue = pkt->ErrorCode; pkt->FinalStatus = STATUS_SUCCESS; pkt->SequenceNumber = 0; pkt->IoControlCode = 0; /* Perform ANSI -> UNICODE conversion */ uc.Buffer = (PUSHORT)&(pkt->DumpData[0]); if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&uc, &ansi, FALSE))) IoWriteErrorLogEntry(pkt); else IoFreeErrorLogEntry(pkt); } }
VOID TiWriteErrorLog( PDRIVER_OBJECT DriverContext, NTSTATUS ErrorCode, ULONG UniqueErrorValue, NTSTATUS FinalStatus, PWSTR String, ULONG DumpDataCount, PULONG DumpData) /* * FUNCTION: Writes an error log entry * ARGUMENTS: * DriverContext = Pointer to the driver or device object * ErrorCode = An error code to put in the log entry * UniqueErrorValue = UniqueErrorValue in the error log packet * FinalStatus = FinalStatus in the error log packet * String = If not NULL, a pointer to a string to put in log * entry * DumpDataCount = Number of ULONGs of dump data * DumpData = Pointer to dump data for the log entry */ { #if 0 PIO_ERROR_LOG_PACKET LogEntry; UCHAR EntrySize; ULONG StringSize; PUCHAR pString; static WCHAR DriverName[] = L"TCP/IP"; EntrySize = sizeof(IO_ERROR_LOG_PACKET) + (DumpDataCount * sizeof(ULONG)) + sizeof(DriverName); if (String) { StringSize = (wcslen(String) * sizeof(WCHAR)) + sizeof(UNICODE_NULL); EntrySize += (UCHAR)StringSize; } LogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( DriverContext, EntrySize); if (LogEntry) { LogEntry->MajorFunctionCode = -1; LogEntry->RetryCount = -1; LogEntry->DumpDataSize = (USHORT)(DumpDataCount * sizeof(ULONG)); LogEntry->NumberOfStrings = (String == NULL) ? 1 : 2; LogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET) + (DumpDataCount-1) * sizeof(ULONG); LogEntry->EventCategory = 0; LogEntry->ErrorCode = ErrorCode; LogEntry->UniqueErrorValue = UniqueErrorValue; LogEntry->FinalStatus = FinalStatus; LogEntry->SequenceNumber = -1; LogEntry->IoControlCode = 0; if (DumpDataCount) RtlCopyMemory(LogEntry->DumpData, DumpData, DumpDataCount * sizeof(ULONG)); pString = ((PUCHAR)LogEntry) + LogEntry->StringOffset; RtlCopyMemory(pString, DriverName, sizeof(DriverName)); pString += sizeof(DriverName); if (String) RtlCopyMemory(pString, String, StringSize); IoWriteErrorLogEntry(LogEntry); } #endif }
VOID DokanPrintToSysLog(__in PDRIVER_OBJECT DriverObject, __in UCHAR MajorFunctionCode, __in NTSTATUS MessageId, __in NTSTATUS Status, __in LPCTSTR Format, __in va_list Args) { NTSTATUS status = STATUS_SUCCESS; PIO_ERROR_LOG_PACKET packet = NULL; WCHAR *message = NULL; size_t messageCapacity = DOKAN_LOG_MAX_CHAR_COUNT; size_t messageCharCount = 0; size_t messageCharsWritten = 0; size_t packetCount = 0; size_t i = 0; UCHAR packetCharCount = 0; UCHAR packetSize = 0; __try { message = ExAllocatePool(sizeof(WCHAR) * messageCapacity); if (message == NULL) { DDbgPrint("Failed to allocate message of capacity %d\n", messageCapacity); __leave; } status = RtlStringCchVPrintfW(message, messageCapacity, Format, Args); if (status == STATUS_BUFFER_OVERFLOW) { // In this case we want to at least log what we can fit. DDbgPrint("Log message was larger than DOKAN_LOG_MAX_CHAR_COUNT." " Format: %S\n", Format); } else if (status != STATUS_SUCCESS) { DDbgPrint("Failed to generate log message with format: %S; status: %x\n", Format, status); __leave; } status = RtlStringCchLengthW(message, messageCapacity, &messageCharCount); if (status != STATUS_SUCCESS) { DDbgPrint("Failed to determine message length, status: %x\n", status); __leave; } packetCount = messageCharCount / DOKAN_LOG_MAX_PACKET_NONNULL_CHARS; if (messageCharCount % DOKAN_LOG_MAX_PACKET_NONNULL_CHARS != 0) { ++packetCount; } for (i = 0; i < packetCount; i++) { packetCharCount = (UCHAR)min(messageCharCount - messageCharsWritten, DOKAN_LOG_MAX_PACKET_NONNULL_CHARS); packetSize = sizeof(IO_ERROR_LOG_PACKET) + sizeof(WCHAR) * (packetCharCount + 1); packet = IoAllocateErrorLogEntry(DriverObject, packetSize); if (packet == NULL) { DDbgPrint("Failed to allocate packet of size %d\n", packetSize); __leave; } RtlZeroMemory(packet, packetSize); packet->MajorFunctionCode = MajorFunctionCode; packet->NumberOfStrings = 1; packet->StringOffset = (USHORT)((char *)&packet->DumpData[0] - (char *)packet); packet->ErrorCode = MessageId; packet->FinalStatus = Status; RtlCopyMemory(&packet->DumpData[0], message + messageCharsWritten, sizeof(WCHAR) * packetCharCount); IoWriteErrorLogEntry(packet); // Destroys packet. packet = NULL; messageCharsWritten += packetCharCount; } } __finally { if (message != NULL) { ExFreePool(message); } } }
VOID ParLogError( 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 ) /*++ 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 - Supplies a pointer to the driver object for the device. DeviceObject - Supplies a pointer to the device object associated with the device that had the error, early in initialization, one may not yet exist. P1,P2 - Supplies the physical addresses for the controller ports involved with the error if they are available and puts them through as dump data. SequenceNumber - Supplies 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 - Supplies the major function code of the irp if there is an error associated with it. RetryCount - Supplies the number of times a particular operation has been retried. UniqueErrorValue - Supplies a unique long word that identifies the particular call to this function. FinalStatus - Supplies 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 - Supplies the IO status for this particular error. Return Value: None. --*/ { PIO_ERROR_LOG_PACKET errorLogEntry; PVOID objectToUse; SHORT dumpToAllocate; if (ARGUMENT_PRESENT(DeviceObject)) { objectToUse = DeviceObject; } else { objectToUse = DriverObject; } dumpToAllocate = 0; if (P1.LowPart != 0 || P1.HighPart != 0) { dumpToAllocate = (SHORT) sizeof(PHYSICAL_ADDRESS); } if (P2.LowPart != 0 || P2.HighPart != 0) { dumpToAllocate += (SHORT) sizeof(PHYSICAL_ADDRESS); } errorLogEntry = IoAllocateErrorLogEntry(objectToUse, (UCHAR) (sizeof(IO_ERROR_LOG_PACKET) + dumpToAllocate)); if (!errorLogEntry) { return; } 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, &P1, sizeof(PHYSICAL_ADDRESS)); if (dumpToAllocate > sizeof(PHYSICAL_ADDRESS)) { RtlCopyMemory(((PUCHAR) errorLogEntry->DumpData) + sizeof(PHYSICAL_ADDRESS), &P2, sizeof(PHYSICAL_ADDRESS)); } } IoWriteErrorLogEntry(errorLogEntry); }