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.

305 lines
6.5 KiB

  1. /*++
  2. Copyright (c) 1990-2001 Microsoft Corporation
  3. Module Name:
  4. kddbgio.c
  5. Abstract:
  6. This module implements kernel debugger based Dbg I/O. This
  7. is the foundation for DbgPrint and DbgPrompt.
  8. Author:
  9. Mark Lucovsky (markl) 31-Aug-1990
  10. Revision History:
  11. --*/
  12. #include "kdp.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(PAGEKD, KdpPrintString)
  15. #pragma alloc_text(PAGEKD, KdpPromptString)
  16. #pragma alloc_text(PAGEKD, KdpAcquireBreakpoint)
  17. #endif
  18. BOOLEAN
  19. KdpPrintString (
  20. IN PSTRING Output
  21. )
  22. /*++
  23. Routine Description:
  24. This routine prints a string.
  25. Arguments:
  26. Output - Supplies a pointer to a string descriptor for the output string.
  27. Return Value:
  28. TRUE if Control-C present in input buffer after print is done.
  29. FALSE otherwise.
  30. --*/
  31. {
  32. ULONG Length;
  33. STRING MessageData;
  34. STRING MessageHeader;
  35. DBGKD_DEBUG_IO DebugIo;
  36. //
  37. // Move the output string to the message buffer.
  38. //
  39. KdpCopyFromPtr(KdpMessageBuffer,
  40. Output->Buffer,
  41. Output->Length,
  42. &Length);
  43. //
  44. // If the total message length is greater than the maximum packet size,
  45. // then truncate the output string.
  46. //
  47. if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) {
  48. Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);
  49. }
  50. //
  51. // Construct the print string message and message descriptor.
  52. //
  53. DebugIo.ApiNumber = DbgKdPrintStringApi;
  54. DebugIo.ProcessorLevel = KeProcessorLevel;
  55. DebugIo.Processor = (USHORT)KeGetCurrentPrcb()->Number;
  56. DebugIo.u.PrintString.LengthOfString = Length;
  57. MessageHeader.Length = sizeof(DBGKD_DEBUG_IO);
  58. MessageHeader.Buffer = (PCHAR)&DebugIo;
  59. //
  60. // Construct the print string data and data descriptor.
  61. //
  62. MessageData.Length = (USHORT)Length;
  63. MessageData.Buffer = KdpMessageBuffer;
  64. //
  65. // Send packet to the kernel debugger on the host machine.
  66. //
  67. KdSendPacket(
  68. PACKET_TYPE_KD_DEBUG_IO,
  69. &MessageHeader,
  70. &MessageData,
  71. &KdpContext
  72. );
  73. return KdpPollBreakInWithPortLock();
  74. }
  75. BOOLEAN
  76. KdpPromptString (
  77. IN PSTRING Output,
  78. IN OUT PSTRING Input
  79. )
  80. /*++
  81. Routine Description:
  82. This routine prints a string, then reads a reply string.
  83. Arguments:
  84. Output - Supplies a pointer to a string descriptor for the output string.
  85. Input - Supplies a pointer to a string descriptor for the input string.
  86. (Length stored/returned in Input->Length)
  87. Return Value:
  88. TRUE - A Breakin sequence was seen, caller should breakpoint and retry
  89. FALSE - No Breakin seen.
  90. --*/
  91. {
  92. ULONG Length;
  93. STRING MessageData;
  94. STRING MessageHeader;
  95. DBGKD_DEBUG_IO DebugIo;
  96. ULONG ReturnCode;
  97. //
  98. // Move the output string to the message buffer.
  99. //
  100. KdpCopyFromPtr(KdpMessageBuffer,
  101. Output->Buffer,
  102. Output->Length,
  103. &Length);
  104. //
  105. // If the total message length is greater than the maximum packet size,
  106. // then truncate the output string.
  107. //
  108. if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) {
  109. Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);
  110. }
  111. //
  112. // Construct the prompt string message and message descriptor.
  113. //
  114. DebugIo.ApiNumber = DbgKdGetStringApi;
  115. DebugIo.ProcessorLevel = KeProcessorLevel;
  116. DebugIo.Processor = (USHORT)KeGetCurrentPrcb()->Number;
  117. DebugIo.u.GetString.LengthOfPromptString = Length;
  118. DebugIo.u.GetString.LengthOfStringRead = Input->MaximumLength;
  119. MessageHeader.Length = sizeof(DBGKD_DEBUG_IO);
  120. MessageHeader.Buffer = (PCHAR)&DebugIo;
  121. //
  122. // Construct the prompt string data and data descriptor.
  123. //
  124. MessageData.Length = (USHORT)Length;
  125. MessageData.Buffer = KdpMessageBuffer;
  126. //
  127. // Send packet to the kernel debugger on the host machine.
  128. //
  129. KdSendPacket(
  130. PACKET_TYPE_KD_DEBUG_IO,
  131. &MessageHeader,
  132. &MessageData,
  133. &KdpContext
  134. );
  135. //
  136. // Receive packet from the kernel debugger on the host machine.
  137. //
  138. MessageHeader.MaximumLength = sizeof(DBGKD_DEBUG_IO);
  139. MessageData.MaximumLength = KDP_MESSAGE_BUFFER_SIZE;
  140. do {
  141. ReturnCode = KdReceivePacket(
  142. PACKET_TYPE_KD_DEBUG_IO,
  143. &MessageHeader,
  144. &MessageData,
  145. &Length,
  146. &KdpContext
  147. );
  148. if (ReturnCode == KDP_PACKET_RESEND) {
  149. return TRUE;
  150. }
  151. } while (ReturnCode != KDP_PACKET_RECEIVED);
  152. if (Length > Input->MaximumLength) {
  153. Length = Input->MaximumLength;
  154. }
  155. KdpCopyToPtr(Input->Buffer,
  156. KdpMessageBuffer,
  157. Length,
  158. &Length);
  159. Input->Length = (USHORT)Length;
  160. return FALSE;
  161. }
  162. BOOLEAN
  163. KdpAcquireBreakpoint(
  164. IN ULONG Number
  165. )
  166. /*++
  167. Routine Description:
  168. This routine prints a string, then reads a reply string.
  169. Arguments:
  170. Number - breakpoint register number being requested.
  171. Return Value:
  172. TRUE - Breakpoint now reserved for kernel use.
  173. FALSE - breakpoint not available.
  174. --*/
  175. {
  176. ULONG Length;
  177. STRING MessageData;
  178. STRING MessageHeader;
  179. DBGKD_CONTROL_REQUEST ControlRequest;
  180. ULONG ReturnCode;
  181. //
  182. // Construct the prompt string message and message descriptor.
  183. //
  184. ControlRequest.ApiNumber = DbgKdRequestHardwareBp;
  185. ControlRequest.u.RequestBreakpoint.HardwareBreakPointNumber = Number;
  186. ControlRequest.u.RequestBreakpoint.Available = FALSE;
  187. MessageHeader.Length = sizeof(ControlRequest);
  188. MessageHeader.Buffer = (PCHAR)&ControlRequest;
  189. //
  190. // Send packet to the kernel debugger on the host machine.
  191. //
  192. KdSendPacket(PACKET_TYPE_KD_CONTROL_REQUEST,
  193. &MessageHeader,
  194. NULL,
  195. &KdpContext);
  196. //
  197. // Receive packet from the kernel debugger on the host machine.
  198. //
  199. MessageHeader.MaximumLength = sizeof(PACKET_TYPE_KD_CONTROL_REQUEST);
  200. MessageData.Buffer = KdpMessageBuffer;
  201. MessageData.Length = 0;
  202. MessageData.MaximumLength = KDP_MESSAGE_BUFFER_SIZE;
  203. do
  204. {
  205. ReturnCode = KdReceivePacket(PACKET_TYPE_KD_CONTROL_REQUEST,
  206. &MessageHeader,
  207. &MessageData,
  208. &Length,
  209. &KdpContext);
  210. if (ReturnCode == KDP_PACKET_RESEND)
  211. {
  212. return FALSE;
  213. }
  214. } while (ReturnCode != KDP_PACKET_RECEIVED);
  215. return (ControlRequest.u.RequestBreakpoint.Available == 1);
  216. }