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.

345 lines
7.6 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. kdexts.c
  5. Abstract:
  6. This file contains the generic routines and initialization code
  7. for the kernel debugger extensions dll.
  8. --*/
  9. extern "C"
  10. void
  11. _disable (
  12. void
  13. );
  14. extern "C"
  15. void
  16. _enable (
  17. void
  18. );
  19. #include "precomp.h"
  20. #pragma hdrstop
  21. #include <ntverp.h>
  22. //
  23. // globals
  24. //
  25. WINDBG_EXTENSION_APIS ExtensionApis;
  26. ULONG64 STeip;
  27. ULONG64 STebp;
  28. ULONG64 STesp;
  29. DBGKD_GET_VERSION64 KernelVersionPacket;
  30. KDDEBUGGER_DATA64 KdDebuggerData;
  31. ULONG64 EXPRLastDump = 0;
  32. //
  33. // Valid for the lifetime of the debug session.
  34. //
  35. ULONG PageSize;
  36. ULONG64 PaeEnabled;
  37. ULONG TargetMachine;
  38. BOOL Connected;
  39. //
  40. // this string is for supporting both the old and the new way of getting
  41. // data from the kernel. Maybe it will go away soon.
  42. //
  43. char ___SillyString[200];
  44. PDEBUG_ADVANCED g_ExtAdvanced;
  45. PDEBUG_CLIENT g_ExtClient;
  46. PDEBUG_CONTROL g_ExtControl;
  47. PDEBUG_DATA_SPACES g_ExtData;
  48. PDEBUG_REGISTERS g_ExtRegisters;
  49. PDEBUG_SYMBOLS g_ExtSymbols;
  50. PDEBUG_SYSTEM_OBJECTS g_ExtSystem;
  51. // Queries for all debugger interfaces.
  52. extern "C" HRESULT
  53. ExtQuery(PDEBUG_CLIENT Client)
  54. {
  55. HRESULT Status;
  56. if ((Status = Client->QueryInterface(__uuidof(IDebugAdvanced),
  57. (void **)&g_ExtAdvanced)) != S_OK)
  58. {
  59. goto Fail;
  60. }
  61. if ((Status = Client->QueryInterface(__uuidof(IDebugControl),
  62. (void **)&g_ExtControl)) != S_OK)
  63. {
  64. goto Fail;
  65. }
  66. if ((Status = Client->QueryInterface(__uuidof(IDebugDataSpaces),
  67. (void **)&g_ExtData)) != S_OK)
  68. {
  69. goto Fail;
  70. }
  71. if ((Status = Client->QueryInterface(__uuidof(IDebugRegisters),
  72. (void **)&g_ExtRegisters)) != S_OK)
  73. {
  74. goto Fail;
  75. }
  76. if ((Status = Client->QueryInterface(__uuidof(IDebugSymbols),
  77. (void **)&g_ExtSymbols)) != S_OK)
  78. {
  79. goto Fail;
  80. }
  81. if ((Status = Client->QueryInterface(__uuidof(IDebugSystemObjects),
  82. (void **)&g_ExtSystem)) != S_OK)
  83. {
  84. goto Fail;
  85. }
  86. g_ExtClient = Client;
  87. return S_OK;
  88. Fail:
  89. ExtRelease();
  90. return Status;
  91. }
  92. // Cleans up all debugger interfaces.
  93. void
  94. ExtRelease(void)
  95. {
  96. g_ExtClient = NULL;
  97. EXT_RELEASE(g_ExtAdvanced);
  98. EXT_RELEASE(g_ExtControl);
  99. EXT_RELEASE(g_ExtData);
  100. EXT_RELEASE(g_ExtRegisters);
  101. EXT_RELEASE(g_ExtSymbols);
  102. EXT_RELEASE(g_ExtSystem);
  103. }
  104. // Normal output.
  105. void __cdecl
  106. ExtOut(PCSTR Format, ...)
  107. {
  108. va_list Args;
  109. va_start(Args, Format);
  110. g_ExtControl->OutputVaList(DEBUG_OUTPUT_NORMAL, Format, Args);
  111. va_end(Args);
  112. }
  113. // Error output.
  114. void __cdecl
  115. ExtErr(PCSTR Format, ...)
  116. {
  117. va_list Args;
  118. va_start(Args, Format);
  119. g_ExtControl->OutputVaList(DEBUG_OUTPUT_ERROR, Format, Args);
  120. va_end(Args);
  121. }
  122. // Warning output.
  123. void __cdecl
  124. ExtWarn(PCSTR Format, ...)
  125. {
  126. va_list Args;
  127. va_start(Args, Format);
  128. g_ExtControl->OutputVaList(DEBUG_OUTPUT_WARNING, Format, Args);
  129. va_end(Args);
  130. }
  131. // Verbose output.
  132. void __cdecl
  133. ExtVerb(PCSTR Format, ...)
  134. {
  135. va_list Args;
  136. va_start(Args, Format);
  137. g_ExtControl->OutputVaList(DEBUG_OUTPUT_VERBOSE, Format, Args);
  138. va_end(Args);
  139. }
  140. extern "C"
  141. HRESULT
  142. CALLBACK
  143. DebugExtensionInitialize(PULONG Version, PULONG Flags)
  144. {
  145. IDebugClient *DebugClient;
  146. PDEBUG_CONTROL DebugControl;
  147. HRESULT Hr;
  148. *Version = DEBUG_EXTENSION_VERSION(1, 0);
  149. *Flags = 0;
  150. if ((Hr = DebugCreate(__uuidof(IDebugClient),
  151. (void **)&DebugClient)) != S_OK)
  152. {
  153. return Hr;
  154. }
  155. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
  156. (void **)&DebugControl)) != S_OK)
  157. {
  158. return Hr;
  159. }
  160. ExtensionApis.nSize = sizeof (ExtensionApis);
  161. if ((Hr = DebugControl->GetWindbgExtensionApis64(&ExtensionApis)) != S_OK) {
  162. return Hr;
  163. }
  164. DebugControl->Release();
  165. DebugClient->Release();
  166. return S_OK;
  167. }
  168. extern "C"
  169. void
  170. CALLBACK
  171. DebugExtensionNotify(ULONG Notify, ULONG64 Argument)
  172. {
  173. //
  174. // The first time we actually connect to a target, get the page size
  175. //
  176. if ((Notify == DEBUG_NOTIFY_SESSION_ACCESSIBLE) && (!Connected))
  177. {
  178. IDebugClient *DebugClient;
  179. PDEBUG_DATA_SPACES DebugDataSpaces;
  180. PDEBUG_CONTROL DebugControl;
  181. HRESULT Hr;
  182. ULONG64 Page;
  183. if ((Hr = DebugCreate(__uuidof(IDebugClient),
  184. (void **)&DebugClient)) == S_OK)
  185. {
  186. //
  187. // Get the page size and PAE enable flag
  188. //
  189. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugDataSpaces),
  190. (void **)&DebugDataSpaces)) == S_OK)
  191. {
  192. if ((Hr = DebugDataSpaces->ReadDebuggerData(
  193. DEBUG_DATA_PaeEnabled, &PaeEnabled,
  194. sizeof(PaeEnabled), NULL)) == S_OK)
  195. {
  196. if ((Hr = DebugDataSpaces->ReadDebuggerData(
  197. DEBUG_DATA_MmPageSize, &Page,
  198. sizeof(Page), NULL)) == S_OK)
  199. {
  200. PageSize = (ULONG)(ULONG_PTR)Page;
  201. }
  202. }
  203. DebugDataSpaces->Release();
  204. }
  205. //
  206. // Get the architecture type.
  207. //
  208. if (PageSize)
  209. {
  210. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
  211. (void **)&DebugControl)) == S_OK)
  212. {
  213. if ((Hr = DebugControl->GetActualProcessorType(
  214. &TargetMachine)) == S_OK)
  215. {
  216. Connected = TRUE;
  217. }
  218. DebugControl->Release();
  219. }
  220. }
  221. DebugClient->Release();
  222. }
  223. }
  224. if (Notify == DEBUG_NOTIFY_SESSION_INACTIVE)
  225. {
  226. Connected = FALSE;
  227. PageSize = 0;
  228. PaeEnabled = 0;
  229. TargetMachine = 0;
  230. }
  231. return;
  232. }
  233. extern "C"
  234. void
  235. CALLBACK
  236. DebugExtensionUninitialize(void)
  237. {
  238. return;
  239. }
  240. BOOL
  241. HaveDebuggerData(
  242. VOID
  243. )
  244. {
  245. static int havedata = 0;
  246. if (havedata == 0) {
  247. if (!Ioctl( IG_GET_KERNEL_VERSION, &KernelVersionPacket, sizeof(KernelVersionPacket))) {
  248. havedata = 2;
  249. } else if (KernelVersionPacket.MajorVersion == 0) {
  250. havedata = 2;
  251. } else {
  252. havedata = 1;
  253. }
  254. }
  255. return (havedata == 1) &&
  256. ((KernelVersionPacket.Flags & DBGKD_VERS_FLAG_DATA) != 0);
  257. }
  258. BOOL
  259. GetCurrentProcessor(
  260. IN PDEBUG_CLIENT Client,
  261. OPTIONAL OUT PULONG pProcessor,
  262. OPTIONAL OUT PHANDLE phCurrentThread
  263. )
  264. {
  265. PDEBUG_SYSTEM_OBJECTS DebugSystem;
  266. ULONG64 hCurrentThread;
  267. if (Client) {
  268. if (Client->QueryInterface(__uuidof(IDebugSystemObjects),
  269. (void **)&DebugSystem) != S_OK) {
  270. return 0;
  271. }
  272. DebugSystem->GetCurrentThreadHandle(&hCurrentThread);
  273. if (phCurrentThread) {
  274. *phCurrentThread = (HANDLE) hCurrentThread;
  275. }
  276. if (pProcessor) {
  277. *pProcessor = (ULONG) hCurrentThread - 1;
  278. }
  279. DebugSystem->Release();
  280. return TRUE;
  281. }
  282. return FALSE;
  283. }