Windows NT 4.0 source code leak
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.

199 lines
4.8 KiB

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