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.

363 lines
7.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 server.
  7. Author:
  8. Manny Weiser (mannyw) 11-Feb-92
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #include "errorlog.tmh"
  13. #pragma hdrstop
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text( PAGE, SrvLogInvalidSmbDirect )
  16. #pragma alloc_text( PAGE, SrvLogServiceFailureDirect )
  17. #if DBG
  18. #pragma alloc_text( PAGE, SrvLogTableFullError )
  19. #endif
  20. #endif
  21. #if 0
  22. NOT PAGEABLE -- SrvLogError
  23. NOT PAGEABLE -- SrvCheckSendCompletionStatus
  24. NOT PAGEABLE -- SrvIsLoggableError
  25. #endif
  26. VOID
  27. SrvLogInvalidSmbDirect (
  28. IN PWORK_CONTEXT WorkContext,
  29. IN ULONG LineNumber
  30. )
  31. {
  32. UNICODE_STRING unknownClient;
  33. PUNICODE_STRING clientName;
  34. ULONG LocalBuffer[ 13 ];
  35. ULONG count;
  36. PAGED_CODE( );
  37. if( !SrvEnableInvalidSmbLogging )
  38. {
  39. return;
  40. }
  41. //
  42. // Let this client log at most one SMB error
  43. //
  44. if( ARGUMENT_PRESENT( WorkContext ) ) {
  45. if( WorkContext->Connection->PagedConnection->LoggedInvalidSmb ) {
  46. return;
  47. }
  48. WorkContext->Connection->PagedConnection->LoggedInvalidSmb = TRUE;
  49. }
  50. if ( ARGUMENT_PRESENT(WorkContext) &&
  51. (WorkContext->Connection->ClientMachineNameString.Length != 0) ) {
  52. clientName = &WorkContext->Connection->ClientMachineNameString;
  53. } else {
  54. RtlInitUnicodeString( &unknownClient, StrUnknownClient );
  55. clientName = &unknownClient;
  56. }
  57. if ( ARGUMENT_PRESENT(WorkContext) ) {
  58. LocalBuffer[0] = LineNumber;
  59. RtlCopyMemory(
  60. &LocalBuffer[1],
  61. WorkContext->RequestHeader,
  62. MIN( WorkContext->RequestBuffer->DataLength, sizeof( LocalBuffer ) - sizeof( LocalBuffer[0] ) )
  63. );
  64. SrvLogError(
  65. SrvDeviceObject,
  66. EVENT_SRV_INVALID_REQUEST,
  67. STATUS_INVALID_SMB,
  68. LocalBuffer,
  69. (USHORT)MIN( WorkContext->RequestBuffer->DataLength + sizeof( LocalBuffer[0] ), sizeof( LocalBuffer ) ),
  70. clientName,
  71. 1
  72. );
  73. } else {
  74. SrvLogError(
  75. SrvDeviceObject,
  76. EVENT_SRV_INVALID_REQUEST,
  77. STATUS_INVALID_SMB,
  78. &LineNumber,
  79. (USHORT)sizeof( LineNumber ),
  80. clientName,
  81. 1
  82. );
  83. }
  84. return;
  85. } // SrvLogInvalidSmb
  86. BOOLEAN
  87. SrvIsLoggableError( IN NTSTATUS Status )
  88. {
  89. NTSTATUS *pstatus;
  90. BOOLEAN ret = TRUE;
  91. for( pstatus = SrvErrorLogIgnore; *pstatus; pstatus++ ) {
  92. if( *pstatus == Status ) {
  93. ret = FALSE;
  94. break;
  95. }
  96. }
  97. return ret;
  98. }
  99. VOID
  100. SrvLogServiceFailureDirect (
  101. IN ULONG LineAndService,
  102. IN NTSTATUS Status
  103. )
  104. /*++
  105. Routine Description:
  106. This function logs a srv svc error. You should use the 'SrvLogServiceFailure'
  107. macro instead of calling this routine directly.
  108. Arguments:
  109. LineAndService consists of the line number of the original call in the highword, and
  110. the service code in the lowword
  111. Status is the status code of the called routine
  112. Return Value:
  113. None.
  114. --*/
  115. {
  116. PAGED_CODE( );
  117. //
  118. // Don't log certain errors that are expected to happen occasionally.
  119. //
  120. if( (LineAndService & 01) || SrvIsLoggableError( Status ) ) {
  121. SrvLogError(
  122. SrvDeviceObject,
  123. EVENT_SRV_SERVICE_FAILED,
  124. Status,
  125. &LineAndService,
  126. sizeof(LineAndService),
  127. NULL,
  128. 0
  129. );
  130. }
  131. return;
  132. } // SrvLogServiceFailure
  133. //
  134. // I have disabled this for retail builds because it is not a good idea to
  135. // allow an evil client to so easily fill the server's system log
  136. //
  137. VOID
  138. SrvLogTableFullError (
  139. IN ULONG Type
  140. )
  141. {
  142. #if DBG
  143. PAGED_CODE( );
  144. SrvLogError(
  145. SrvDeviceObject,
  146. EVENT_SRV_CANT_GROW_TABLE,
  147. STATUS_INSUFFICIENT_RESOURCES,
  148. &Type,
  149. sizeof(ULONG),
  150. NULL,
  151. 0
  152. );
  153. return;
  154. #endif
  155. } // SrvLogTableFullError
  156. VOID
  157. SrvLogError(
  158. IN PVOID DeviceOrDriverObject,
  159. IN ULONG UniqueErrorCode,
  160. IN NTSTATUS NtStatusCode,
  161. IN PVOID RawDataBuffer,
  162. IN USHORT RawDataLength,
  163. IN PUNICODE_STRING InsertionString OPTIONAL,
  164. IN ULONG InsertionStringCount
  165. )
  166. /*++
  167. Routine Description:
  168. This function allocates an I/O error log record, fills it in and writes it
  169. to the I/O error log.
  170. Arguments:
  171. Return Value:
  172. None.
  173. --*/
  174. {
  175. PIO_ERROR_LOG_PACKET errorLogEntry;
  176. ULONG insertionStringLength = 0;
  177. ULONG i;
  178. PWCHAR buffer;
  179. USHORT paddedRawDataLength = 0;
  180. //
  181. // Update the server error counts
  182. //
  183. if ( UniqueErrorCode == EVENT_SRV_NETWORK_ERROR ) {
  184. SrvUpdateErrorCount( &SrvNetworkErrorRecord, TRUE );
  185. } else {
  186. SrvUpdateErrorCount( &SrvErrorRecord, TRUE );
  187. }
  188. for ( i = 0; i < InsertionStringCount ; i++ ) {
  189. insertionStringLength += (InsertionString[i].Length + sizeof(WCHAR));
  190. }
  191. //
  192. // pad the raw data buffer so that the insertion string starts
  193. // on an even address.
  194. //
  195. if ( ARGUMENT_PRESENT( RawDataBuffer ) ) {
  196. paddedRawDataLength = (RawDataLength + 1) & ~1;
  197. }
  198. errorLogEntry = IoAllocateErrorLogEntry(
  199. DeviceOrDriverObject,
  200. (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) +
  201. paddedRawDataLength + insertionStringLength)
  202. );
  203. if (errorLogEntry != NULL) {
  204. //
  205. // Fill in the error log entry
  206. //
  207. errorLogEntry->ErrorCode = UniqueErrorCode;
  208. errorLogEntry->MajorFunctionCode = 0;
  209. errorLogEntry->RetryCount = 0;
  210. errorLogEntry->UniqueErrorValue = 0;
  211. errorLogEntry->FinalStatus = NtStatusCode;
  212. errorLogEntry->IoControlCode = 0;
  213. errorLogEntry->DeviceOffset.QuadPart = 0;
  214. errorLogEntry->DumpDataSize = RawDataLength;
  215. errorLogEntry->StringOffset =
  216. (USHORT)(FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) + paddedRawDataLength);
  217. errorLogEntry->NumberOfStrings = (USHORT)InsertionStringCount;
  218. errorLogEntry->SequenceNumber = 0;
  219. //
  220. // Append the extra information. This information is typically
  221. // an SMB header.
  222. //
  223. if ( ARGUMENT_PRESENT( RawDataBuffer ) ) {
  224. RtlCopyMemory(
  225. errorLogEntry->DumpData,
  226. RawDataBuffer,
  227. RawDataLength
  228. );
  229. }
  230. buffer = (PWCHAR)((PCHAR)errorLogEntry->DumpData + paddedRawDataLength);
  231. for ( i = 0; i < InsertionStringCount ; i++ ) {
  232. RtlCopyMemory(
  233. buffer,
  234. InsertionString[i].Buffer,
  235. InsertionString[i].Length
  236. );
  237. buffer += (InsertionString[i].Length/2);
  238. *buffer++ = L'\0';
  239. }
  240. //
  241. // Write the entry
  242. //
  243. IoWriteErrorLogEntry(errorLogEntry);
  244. }
  245. } // SrvLogError
  246. VOID
  247. SrvCheckSendCompletionStatus(
  248. IN NTSTATUS Status,
  249. IN ULONG LineNumber
  250. )
  251. /*++
  252. Routine Description:
  253. Routine to log send completion errors.
  254. Arguments:
  255. Return Value:
  256. None.
  257. --*/
  258. {
  259. if( SrvIsLoggableError( Status ) ) {
  260. SrvLogError( SrvDeviceObject,
  261. EVENT_SRV_NETWORK_ERROR,
  262. Status,
  263. &LineNumber, sizeof(LineNumber),
  264. NULL, 0 );
  265. }
  266. } // SrvCheckSendCompletionStatus