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.

328 lines
9.5 KiB

  1. /*++
  2. Copyright (c) 1989-1993 Microsoft Corporation
  3. Module Name:
  4. spxerror.c
  5. Abstract:
  6. This module contains code which provides error logging support.
  7. Author:
  8. Nikhil Kamkolkar (nikhilk) 11-November-1993
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #ifndef __PREFAST__
  16. #pragma warning(disable:4068)
  17. #endif
  18. #pragma prefast(disable:276, "The assignments are harmless")
  19. // Define module number for event logging entries
  20. #define FILENUM SPXERROR
  21. LONG SpxLastRawDataLen = 0;
  22. NTSTATUS SpxLastUniqueErrorCode = STATUS_SUCCESS;
  23. NTSTATUS SpxLastNtStatusCode = STATUS_SUCCESS;
  24. ULONG SpxLastErrorCount = 0;
  25. LONG SpxLastErrorTime = 0;
  26. BYTE SpxLastRawData[PORT_MAXIMUM_MESSAGE_LENGTH - \
  27. sizeof(IO_ERROR_LOG_PACKET)] = {0};
  28. BOOLEAN
  29. SpxFilterErrorLogEntry(
  30. IN NTSTATUS UniqueErrorCode,
  31. IN NTSTATUS NtStatusCode,
  32. IN PVOID RawDataBuf OPTIONAL,
  33. IN LONG RawDataLen
  34. )
  35. /*++
  36. Routine Description:
  37. Arguments:
  38. Return Value:
  39. --*/
  40. {
  41. int insertionStringLength = 0;
  42. // Filter out events such that the same event recurring close together does not
  43. // cause errorlog clogging. The scheme is - if the event is same as the last event
  44. // and the elapsed time is > THRESHOLD and ERROR_CONSEQ_FREQ simulataneous errors
  45. // have happened, then log it else skip
  46. if ((UniqueErrorCode == SpxLastUniqueErrorCode) &&
  47. (NtStatusCode == SpxLastNtStatusCode))
  48. {
  49. SpxLastErrorCount++;
  50. if ((SpxLastRawDataLen == RawDataLen) &&
  51. (RtlEqualMemory(SpxLastRawData, RawDataBuf, RawDataLen)) &&
  52. ((SpxLastErrorCount % ERROR_CONSEQ_FREQ) != 0) &&
  53. ((SpxGetCurrentTime() - SpxLastErrorTime) < ERROR_CONSEQ_TIME))
  54. {
  55. return(FALSE);
  56. }
  57. }
  58. SpxLastUniqueErrorCode = UniqueErrorCode;
  59. SpxLastNtStatusCode = NtStatusCode;
  60. SpxLastErrorCount = 0;
  61. SpxLastErrorTime = SpxGetCurrentTime();
  62. if (RawDataLen != 0)
  63. {
  64. SpxLastRawDataLen = RawDataLen;
  65. RtlCopyMemory(
  66. SpxLastRawData,
  67. RawDataBuf,
  68. RawDataLen);
  69. }
  70. return(TRUE);
  71. }
  72. VOID
  73. SpxWriteResourceErrorLog(
  74. IN PDEVICE Device,
  75. IN ULONG BytesNeeded,
  76. IN ULONG UniqueErrorValue
  77. )
  78. /*++
  79. Routine Description:
  80. This routine allocates and writes an error log entry indicating
  81. an out of resources condition.
  82. Arguments:
  83. Device - Pointer to the device context.
  84. BytesNeeded - If applicable, the number of bytes that could not
  85. be allocated.
  86. UniqueErrorValue - Used as the UniqueErrorValue in the error log
  87. packet.
  88. Return Value:
  89. None.
  90. --*/
  91. {
  92. PIO_ERROR_LOG_PACKET errorLogEntry;
  93. UCHAR EntrySize;
  94. PUCHAR StringLoc;
  95. ULONG TempUniqueError;
  96. static WCHAR UniqueErrorBuffer[4] = L"000";
  97. INT i;
  98. if (!SpxFilterErrorLogEntry(
  99. EVENT_TRANSPORT_RESOURCE_POOL,
  100. STATUS_INSUFFICIENT_RESOURCES,
  101. (PVOID)&BytesNeeded,
  102. sizeof(BytesNeeded)))
  103. {
  104. return;
  105. }
  106. EntrySize = sizeof(IO_ERROR_LOG_PACKET) +
  107. Device->dev_DeviceNameLen +
  108. sizeof(UniqueErrorBuffer);
  109. errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
  110. (PDEVICE_OBJECT)Device,
  111. EntrySize);
  112. // Convert the error value into a buffer.
  113. TempUniqueError = UniqueErrorValue;
  114. for (i=1; i>=0; i--)
  115. {
  116. UniqueErrorBuffer[i] = (WCHAR)((TempUniqueError % 10) + L'0');
  117. TempUniqueError /= 10;
  118. }
  119. if (errorLogEntry != NULL)
  120. {
  121. errorLogEntry->MajorFunctionCode = (UCHAR)-1;
  122. errorLogEntry->RetryCount = (UCHAR)-1;
  123. errorLogEntry->DumpDataSize = sizeof(ULONG);
  124. errorLogEntry->NumberOfStrings = 2;
  125. errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET);
  126. errorLogEntry->EventCategory = 0;
  127. errorLogEntry->ErrorCode = EVENT_TRANSPORT_RESOURCE_POOL;
  128. errorLogEntry->UniqueErrorValue = UniqueErrorValue;
  129. errorLogEntry->FinalStatus = STATUS_INSUFFICIENT_RESOURCES;
  130. errorLogEntry->SequenceNumber = (ULONG)-1;
  131. errorLogEntry->IoControlCode = 0;
  132. errorLogEntry->DumpData[0] = BytesNeeded;
  133. StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset;
  134. RtlCopyMemory(
  135. StringLoc, Device->dev_DeviceName, Device->dev_DeviceNameLen);
  136. StringLoc += Device->dev_DeviceNameLen;
  137. RtlCopyMemory(
  138. StringLoc, UniqueErrorBuffer, sizeof(UniqueErrorBuffer));
  139. IoWriteErrorLogEntry(errorLogEntry);
  140. }
  141. }
  142. VOID
  143. SpxWriteGeneralErrorLog(
  144. IN PDEVICE Device,
  145. IN NTSTATUS ErrorCode,
  146. IN ULONG UniqueErrorValue,
  147. IN NTSTATUS FinalStatus,
  148. IN PWSTR SecondString,
  149. IN PVOID RawDataBuf OPTIONAL,
  150. IN LONG RawDataLen
  151. )
  152. /*++
  153. Routine Description:
  154. This routine allocates and writes an error log entry indicating
  155. a general problem as indicated by the parameters. It handles
  156. event codes REGISTER_FAILED, BINDING_FAILED, ADAPTER_NOT_FOUND,
  157. TRANSFER_DATA, TOO_MANY_LINKS, and BAD_PROTOCOL. All these
  158. events have messages with one or two strings in them.
  159. Arguments:
  160. Device - Pointer to the device context, or this may be
  161. a driver object instead.
  162. ErrorCode - The transport event code.
  163. UniqueErrorValue - Used as the UniqueErrorValue in the error log
  164. packet.
  165. FinalStatus - Used as the FinalStatus in the error log packet.
  166. SecondString - If not NULL, the string to use as the %3
  167. value in the error log packet.
  168. RawDataBuf - The number of ULONGs of dump data.
  169. RawDataLen - Dump data for the packet.
  170. Return Value:
  171. None.
  172. --*/
  173. {
  174. PIO_ERROR_LOG_PACKET errorLogEntry;
  175. UCHAR EntrySize;
  176. ULONG SecondStringSize;
  177. PUCHAR StringLoc;
  178. static WCHAR DriverName[4] = L"Spx";
  179. if (!SpxFilterErrorLogEntry(
  180. ErrorCode,
  181. FinalStatus,
  182. RawDataBuf,
  183. RawDataLen))
  184. {
  185. return;
  186. }
  187. #ifdef DBG
  188. if ( sizeof(IO_ERROR_LOG_PACKET) + RawDataLen > 255) {
  189. DbgPrint("Size greater than maximum entry size 255.\n");
  190. }
  191. #endif
  192. EntrySize = (UCHAR) (sizeof(IO_ERROR_LOG_PACKET) + RawDataLen);
  193. if (Device->dev_Type == SPX_DEVICE_SIGNATURE)
  194. {
  195. EntrySize += (UCHAR)Device->dev_DeviceNameLen;
  196. }
  197. else
  198. {
  199. EntrySize += sizeof(DriverName);
  200. }
  201. if (SecondString)
  202. {
  203. SecondStringSize = (wcslen(SecondString)*sizeof(WCHAR)) + sizeof(UNICODE_NULL);
  204. EntrySize += (UCHAR)SecondStringSize;
  205. }
  206. errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
  207. (PDEVICE_OBJECT)Device,
  208. EntrySize);
  209. if (errorLogEntry != NULL)
  210. {
  211. errorLogEntry->MajorFunctionCode = (UCHAR)-1;
  212. errorLogEntry->RetryCount = (UCHAR)-1;
  213. errorLogEntry->DumpDataSize = (USHORT)RawDataLen;
  214. errorLogEntry->NumberOfStrings = (SecondString == NULL) ? 1 : 2;
  215. errorLogEntry->StringOffset = (USHORT)
  216. (sizeof(IO_ERROR_LOG_PACKET) + RawDataLen);
  217. errorLogEntry->EventCategory = 0;
  218. errorLogEntry->ErrorCode = ErrorCode;
  219. errorLogEntry->UniqueErrorValue = UniqueErrorValue;
  220. errorLogEntry->FinalStatus = FinalStatus;
  221. errorLogEntry->SequenceNumber = (ULONG)-1;
  222. errorLogEntry->IoControlCode = 0;
  223. if (RawDataLen != 0)
  224. {
  225. RtlCopyMemory(errorLogEntry->DumpData, RawDataBuf, RawDataLen);
  226. }
  227. StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset;
  228. if (Device->dev_Type == SPX_DEVICE_SIGNATURE)
  229. {
  230. RtlCopyMemory(
  231. StringLoc, Device->dev_DeviceName, Device->dev_DeviceNameLen);
  232. StringLoc += Device->dev_DeviceNameLen;
  233. }
  234. else
  235. {
  236. RtlCopyMemory (StringLoc, DriverName, sizeof(DriverName));
  237. StringLoc += sizeof(DriverName);
  238. }
  239. if (SecondString)
  240. {
  241. RtlCopyMemory (StringLoc, SecondString, SecondStringSize);
  242. }
  243. IoWriteErrorLogEntry(errorLogEntry);
  244. }
  245. return;
  246. }