Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
4.8 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. errorlog.c
  5. Abstract:
  6. This module implements the error logging in the netware redirector.
  7. Author:
  8. Manny Weiser (mannyw) 11-Feb-92
  9. Revision History:
  10. --*/
  11. #include <procs.h>
  12. #include <align.h>
  13. #include <stdarg.h>
  14. ULONG
  15. SequenceNumber = 0;
  16. #ifdef ALLOC_PRAGMA
  17. #ifndef QFE_BUILD
  18. #pragma alloc_text( PAGE1, Error )
  19. #endif
  20. #endif
  21. #if 0 // Not pageable
  22. // see ifndef QFE_BUILD above
  23. #endif
  24. VOID
  25. _cdecl
  26. Error(
  27. IN ULONG UniqueErrorCode,
  28. IN NTSTATUS NtStatusCode,
  29. IN PVOID ExtraInformationBuffer,
  30. IN USHORT ExtraInformationLength,
  31. IN USHORT NumberOfInsertionStrings,
  32. ...
  33. )
  34. #define LAST_NAMED_ARGUMENT NumberOfInsertionStrings
  35. /*++
  36. Routine Description:
  37. This function allocates an I/O error log record, fills it in and writes it
  38. to the I/O error log.
  39. Arguments:
  40. UniqueErrorCode - The event code
  41. NtStatusCode - The NT status of the failure
  42. ExtraInformationBuffer - Raw data for the event
  43. ExtraInformationLength - The length of the raw data
  44. NumberOfInsertionString - The number of insertion strings that follow
  45. InsertionString - 0 or more insertion strings.
  46. Return Value:
  47. None.
  48. --*/
  49. {
  50. PIO_ERROR_LOG_PACKET ErrorLogEntry;
  51. int TotalErrorLogEntryLength;
  52. ULONG SizeOfStringData = 0;
  53. va_list ParmPtr; // Pointer to stack parms.
  54. if (NumberOfInsertionStrings != 0) {
  55. USHORT i;
  56. va_start(ParmPtr, LAST_NAMED_ARGUMENT);
  57. for (i = 0; i < NumberOfInsertionStrings; i += 1) {
  58. PWSTR String = va_arg(ParmPtr, PWSTR);
  59. SizeOfStringData += (wcslen(String) + 1) * sizeof(WCHAR);
  60. }
  61. }
  62. //
  63. // Ideally we want the packet to hold the servername and ExtraInformation.
  64. // Usually the ExtraInformation gets truncated.
  65. //
  66. TotalErrorLogEntryLength =
  67. min( ExtraInformationLength + sizeof(IO_ERROR_LOG_MESSAGE) + 1 + SizeOfStringData,
  68. ERROR_LOG_MAXIMUM_SIZE );
  69. ErrorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
  70. FileSystemDeviceObject,
  71. (UCHAR)TotalErrorLogEntryLength
  72. );
  73. if (ErrorLogEntry != NULL) {
  74. PCHAR DumpData;
  75. ULONG RemainingSpace = TotalErrorLogEntryLength - sizeof( IO_ERROR_LOG_MESSAGE );
  76. USHORT i;
  77. ULONG SizeOfRawData;
  78. if (RemainingSpace > SizeOfStringData) {
  79. SizeOfRawData = RemainingSpace - SizeOfStringData;
  80. } else {
  81. SizeOfStringData = RemainingSpace;
  82. SizeOfRawData = 0;
  83. }
  84. //
  85. // Fill in the error log entry
  86. //
  87. ErrorLogEntry->ErrorCode = UniqueErrorCode;
  88. ErrorLogEntry->MajorFunctionCode = 0;
  89. ErrorLogEntry->RetryCount = 0;
  90. ErrorLogEntry->UniqueErrorValue = 0;
  91. ErrorLogEntry->FinalStatus = NtStatusCode;
  92. ErrorLogEntry->IoControlCode = 0;
  93. ErrorLogEntry->DeviceOffset.LowPart = 0;
  94. ErrorLogEntry->DeviceOffset.HighPart = 0;
  95. ErrorLogEntry->SequenceNumber = (ULONG)SequenceNumber ++;
  96. ErrorLogEntry->StringOffset =
  97. (USHORT)ROUND_UP_COUNT(
  98. FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) + SizeOfRawData,
  99. ALIGN_WORD);
  100. DumpData = (PCHAR)ErrorLogEntry->DumpData;
  101. //
  102. // Append the extra information. This information is typically
  103. // an SMB header.
  104. //
  105. if (( ARGUMENT_PRESENT( ExtraInformationBuffer )) &&
  106. ( SizeOfRawData != 0 )) {
  107. ULONG Length;
  108. Length = min(ExtraInformationLength, (USHORT)SizeOfRawData);
  109. RtlCopyMemory(
  110. DumpData,
  111. ExtraInformationBuffer,
  112. Length);
  113. ErrorLogEntry->DumpDataSize = (USHORT)Length;
  114. } else {
  115. ErrorLogEntry->DumpDataSize = 0;
  116. }
  117. ErrorLogEntry->NumberOfStrings = 0;
  118. if (NumberOfInsertionStrings != 0) {
  119. PWSTR StringOffset = (PWSTR)((PCHAR)ErrorLogEntry + ErrorLogEntry->StringOffset);
  120. PWSTR InsertionString;
  121. //
  122. // Set up ParmPtr to point to first of the caller's parameters.
  123. //
  124. va_start(ParmPtr, LAST_NAMED_ARGUMENT);
  125. for (i = 0 ; i < NumberOfInsertionStrings ; i+= 1) {
  126. InsertionString = va_arg(ParmPtr, PWSTR);
  127. if (((wcslen(InsertionString) + 1) * sizeof(WCHAR)) <= SizeOfStringData ) {
  128. wcscpy(StringOffset, InsertionString);
  129. StringOffset += wcslen(InsertionString) + 1;
  130. SizeOfStringData -= (wcslen(InsertionString) + 1) * sizeof(WCHAR);
  131. ErrorLogEntry->NumberOfStrings += 1;
  132. }
  133. }
  134. }
  135. IoWriteErrorLogEntry(ErrorLogEntry);
  136. }
  137. }