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.

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