Leaked source code of windows server 2003
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.

200 lines
5.1 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 server.
  7. !!! This module must be nonpageable.
  8. Author:
  9. Manny Weiser (mannyw) 11-Feb-92
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include <windef.h>
  15. #include <align.h>
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text(PAGE, CnWriteErrorLogEntry)
  18. #endif
  19. ULONG CnSequenceNumber = 0;
  20. //#pragma optimize("",off)
  21. VOID
  22. _cdecl
  23. CnWriteErrorLogEntry(
  24. IN ULONG UniqueErrorCode,
  25. IN NTSTATUS NtStatusCode,
  26. IN PVOID ExtraInformationBuffer,
  27. IN USHORT ExtraInformationLength,
  28. IN USHORT NumberOfInsertionStrings,
  29. ...
  30. )
  31. #define LAST_NAMED_ARGUMENT NumberOfInsertionStrings
  32. /*++
  33. Routine Description:
  34. This function allocates an I/O error log record, fills it in and writes it
  35. to the I/O error log.
  36. Arguments:
  37. Return Value:
  38. None.
  39. --*/
  40. {
  41. PIO_ERROR_LOG_PACKET ErrorLogEntry;
  42. int TotalErrorLogEntryLength;
  43. ULONG SizeOfStringData = 0;
  44. va_list ParmPtr; // Pointer to stack parms.
  45. ULONG Length;
  46. PAGED_CODE();
  47. if (NumberOfInsertionStrings != 0) {
  48. ULONG i;
  49. va_start(ParmPtr, LAST_NAMED_ARGUMENT);
  50. for (i = 0; i < NumberOfInsertionStrings; i += 1) {
  51. PWSTR String = va_arg(ParmPtr, PWSTR);
  52. Length = wcslen(String);
  53. while ( (Length > 0) && (String[Length-1] == L' ') ) {
  54. Length--;
  55. }
  56. SizeOfStringData += (Length + 1) * sizeof(WCHAR);
  57. }
  58. }
  59. //
  60. // Ideally we want the packet to hold the servername and ExtraInformation.
  61. // Usually the ExtraInformation gets truncated.
  62. //
  63. TotalErrorLogEntryLength =
  64. min( ExtraInformationLength + sizeof(IO_ERROR_LOG_PACKET) + 1 + SizeOfStringData,
  65. ERROR_LOG_MAXIMUM_SIZE );
  66. ErrorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
  67. (PDEVICE_OBJECT)CnDeviceObject,
  68. (UCHAR)TotalErrorLogEntryLength
  69. );
  70. if (ErrorLogEntry != NULL) {
  71. PCHAR DumpData;
  72. ULONG RemainingSpace = TotalErrorLogEntryLength -
  73. FIELD_OFFSET( IO_ERROR_LOG_PACKET, DumpData );
  74. ULONG i;
  75. ULONG SizeOfRawData;
  76. if (RemainingSpace > SizeOfStringData) {
  77. SizeOfRawData = RemainingSpace - SizeOfStringData;
  78. } else {
  79. SizeOfStringData = RemainingSpace;
  80. SizeOfRawData = 0;
  81. }
  82. //
  83. // Fill in the error log entry
  84. //
  85. ErrorLogEntry->ErrorCode = UniqueErrorCode;
  86. ErrorLogEntry->MajorFunctionCode = 0;
  87. ErrorLogEntry->RetryCount = 0;
  88. ErrorLogEntry->UniqueErrorValue = 0;
  89. ErrorLogEntry->FinalStatus = NtStatusCode;
  90. ErrorLogEntry->IoControlCode = 0;
  91. ErrorLogEntry->DeviceOffset.LowPart = 0;
  92. ErrorLogEntry->DeviceOffset.HighPart = 0;
  93. ErrorLogEntry->SequenceNumber = (ULONG)CnSequenceNumber ++;
  94. ErrorLogEntry->StringOffset = (USHORT)(ROUND_UP_COUNT(
  95. FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) + SizeOfRawData,
  96. ALIGN_WORD));
  97. DumpData = (PCHAR)ErrorLogEntry->DumpData;
  98. //
  99. // Append the extra information. This information is typically
  100. // an SMB header.
  101. //
  102. if (( ARGUMENT_PRESENT( ExtraInformationBuffer )) &&
  103. ( SizeOfRawData != 0 )) {
  104. Length = min(ExtraInformationLength, (USHORT)SizeOfRawData);
  105. RtlCopyMemory(
  106. DumpData,
  107. ExtraInformationBuffer,
  108. Length);
  109. ErrorLogEntry->DumpDataSize = (USHORT)Length;
  110. } else {
  111. ErrorLogEntry->DumpDataSize = 0;
  112. }
  113. ErrorLogEntry->NumberOfStrings = 0;
  114. if (NumberOfInsertionStrings != 0) {
  115. PWSTR StringOffset = (PWSTR)((PCHAR)ErrorLogEntry + ErrorLogEntry->StringOffset);
  116. PWSTR InsertionString;
  117. //
  118. // Set up ParmPtr to point to first of the caller's parameters.
  119. //
  120. va_start(ParmPtr, LAST_NAMED_ARGUMENT);
  121. for (i = 0 ; i < NumberOfInsertionStrings ; i+= 1) {
  122. InsertionString = va_arg(ParmPtr, PWSTR);
  123. Length = wcslen(InsertionString);
  124. while ( (Length > 0) && (InsertionString[Length-1] == L' ') ) {
  125. Length--;
  126. }
  127. if ( ((Length + 1) * sizeof(WCHAR)) > SizeOfStringData ) {
  128. Length = ( SizeOfStringData / sizeof( WCHAR )) - 1;
  129. }
  130. if ( Length > 0 ) {
  131. RtlCopyMemory(StringOffset, InsertionString, Length*sizeof(WCHAR));
  132. StringOffset += Length;
  133. *StringOffset++ = L'\0';
  134. SizeOfStringData -= (Length + 1) * sizeof(WCHAR);
  135. ErrorLogEntry->NumberOfStrings += 1;
  136. }
  137. }
  138. }
  139. IoWriteErrorLogEntry(ErrorLogEntry);
  140. }
  141. }