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.

303 lines
5.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. kdlog.c
  5. Abstract:
  6. Kernel Debugger logging
  7. Author:
  8. Neil Sandlin
  9. Environment:
  10. Notes:
  11. Revision History:
  12. --*/
  13. #include "stdarg.h"
  14. #include "stdio.h"
  15. #define _NTDDK_
  16. #include "ntos.h" // *** USES INTERNAL DEFINES ***
  17. #include "hal.h"
  18. #include "kdlog.h"
  19. #include "kdlogctl.h"
  20. NTSTATUS
  21. DriverEntry(
  22. IN PDRIVER_OBJECT DriverObject,
  23. IN PUNICODE_STRING RegistryPath
  24. );
  25. NTSTATUS
  26. KdlogDeviceControl(
  27. IN PDEVICE_OBJECT DeviceObject,
  28. IN PIRP Irp
  29. );
  30. NTSTATUS
  31. KdlogOpen(
  32. IN PDEVICE_OBJECT DeviceObject,
  33. IN PIRP Irp
  34. );
  35. NTSTATUS
  36. KdlogClose(
  37. IN PDEVICE_OBJECT DeviceObject,
  38. IN PIRP Irp
  39. );
  40. VOID
  41. KdlogUnload (
  42. IN PDRIVER_OBJECT DriverObject
  43. );
  44. #ifdef ALLOC_PRAGMA
  45. #pragma alloc_text(INIT,DriverEntry)
  46. #pragma alloc_text(PAGE,KdlogDeviceControl)
  47. #pragma alloc_text(PAGE,KdlogOpen)
  48. #pragma alloc_text(PAGE,KdlogClose)
  49. #pragma alloc_text(PAGE,KdlogUnload)
  50. #endif
  51. NTSTATUS
  52. DriverEntry(
  53. IN PDRIVER_OBJECT DriverObject,
  54. IN PUNICODE_STRING RegistryPath
  55. )
  56. /*++
  57. Routine Description:
  58. This routine initializes the stat driver.
  59. Arguments:
  60. DriverObject - Pointer to driver object created by system.
  61. RegistryPath - Pointer to the Unicode name of the registry path
  62. for this driver.
  63. Return Value:
  64. The function value is the final status from the initialization operation.
  65. --*/
  66. {
  67. UNICODE_STRING unicodeString;
  68. PDEVICE_OBJECT deviceObject;
  69. NTSTATUS status;
  70. ULONG i;
  71. KdPrint(( "KDLOG: DriverEntry()\n" ));
  72. //
  73. // Create non-exclusive device object
  74. //
  75. RtlInitUnicodeString(&unicodeString, L"\\Device\\KdLog");
  76. status = IoCreateDevice(
  77. DriverObject,
  78. 0,
  79. &unicodeString,
  80. FILE_DEVICE_UNKNOWN, // DeviceType
  81. 0,
  82. FALSE,
  83. &deviceObject
  84. );
  85. if (status != STATUS_SUCCESS) {
  86. KdPrint(( "Kdlog - DriverEntry: unable to create device object: %X\n", status ));
  87. return(status);
  88. }
  89. deviceObject->Flags |= DO_BUFFERED_IO;
  90. //
  91. // Set up the device driver entry points.
  92. //
  93. DriverObject->MajorFunction[IRP_MJ_CREATE] = KdlogOpen;
  94. DriverObject->MajorFunction[IRP_MJ_CLOSE] = KdlogClose;
  95. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KdlogDeviceControl;
  96. DriverObject->DriverUnload = KdlogUnload;
  97. return(STATUS_SUCCESS);
  98. }
  99. NTSTATUS
  100. KdlogDeviceControl(
  101. IN PDEVICE_OBJECT DeviceObject,
  102. IN PIRP Irp
  103. )
  104. /*++
  105. Routine Description:
  106. This routine is the dispatch routine for device control requests.
  107. Arguments:
  108. DeviceObject - Pointer to class device object.
  109. Irp - Pointer to the request packet.
  110. Return Value:
  111. Kdlogus is returned.
  112. --*/
  113. {
  114. PIO_STACK_LOCATION irpSp;
  115. NTSTATUS status;
  116. ULONG BufferLength;
  117. PULONG Buffer;
  118. PKD_DBG_LOG_CONTEXT pContext;
  119. ULONG DataLength;
  120. PAGED_CODE();
  121. //
  122. // Get a pointer to the current parameters for this request. The
  123. // information is contained in the current stack location.
  124. //
  125. irpSp = IoGetCurrentIrpStackLocation(Irp);
  126. //
  127. // Case on the device control subfunction that is being performed by the
  128. // requestor.
  129. //
  130. status = STATUS_SUCCESS;
  131. try {
  132. Buffer = (PULONG) irpSp->Parameters.DeviceIoControl.Type3InputBuffer;
  133. BufferLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  134. switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
  135. case KDLOG_QUERY_LOG_CONTEXT:
  136. if (BufferLength < sizeof(KD_DBG_LOG_CONTEXT)) {
  137. status = STATUS_BUFFER_TOO_SMALL;
  138. break;
  139. }
  140. status = KdGetDebuggerLogContext(&pContext);
  141. if (NT_SUCCESS(status)) {
  142. RtlCopyMemory(Buffer, pContext, sizeof(KD_DBG_LOG_CONTEXT));
  143. }
  144. break;
  145. case KDLOG_GET_LOG_DATA:
  146. status = KdGetDebuggerLogContext(&pContext);
  147. if (!NT_SUCCESS(status)) {
  148. break;
  149. }
  150. DataLength = pContext->EntryLength * (pContext->LastIndex + 1);
  151. if (BufferLength < DataLength) {
  152. status = STATUS_BUFFER_TOO_SMALL;
  153. break;
  154. }
  155. RtlCopyMemory(Buffer, pContext->LogData, DataLength);
  156. break;
  157. default:
  158. status = STATUS_INVALID_PARAMETER;
  159. break;
  160. }
  161. } except(EXCEPTION_EXECUTE_HANDLER) {
  162. status = GetExceptionCode();
  163. }
  164. //
  165. // Request is done...
  166. //
  167. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  168. return(status);
  169. }
  170. NTSTATUS
  171. KdlogOpen(
  172. IN PDEVICE_OBJECT DeviceObject,
  173. IN PIRP Irp
  174. )
  175. {
  176. PAGED_CODE();
  177. //
  178. // Complete the request and return status.
  179. //
  180. Irp->IoStatus.Status = STATUS_SUCCESS;
  181. Irp->IoStatus.Information = 0;
  182. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  183. return(STATUS_SUCCESS);
  184. }
  185. NTSTATUS
  186. KdlogClose(
  187. IN PDEVICE_OBJECT DeviceObject,
  188. IN PIRP Irp
  189. )
  190. {
  191. PAGED_CODE();
  192. //
  193. // Complete the request and return status.
  194. //
  195. Irp->IoStatus.Status = STATUS_SUCCESS;
  196. Irp->IoStatus.Information = 0;
  197. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  198. return(STATUS_SUCCESS);
  199. }
  200. VOID
  201. KdlogUnload (
  202. IN PDRIVER_OBJECT DriverObject
  203. )
  204. {
  205. PAGED_CODE();
  206. //
  207. // Delete the device object.
  208. //
  209. IoDeleteDevice(DriverObject->DeviceObject);
  210. return;
  211. }