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.

453 lines
11 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. #include "precomp.h"
  10. #pragma hdrstop
  11. #include <ntverp.h>
  12. #include <string.h>
  13. //
  14. // globals
  15. //
  16. WINDBG_EXTENSION_APIS ExtensionApis;
  17. ULONG64 STeip;
  18. ULONG64 STebp;
  19. ULONG64 STesp;
  20. DBGKD_GET_VERSION64 KernelVersionPacket;
  21. KDDEBUGGER_DATA64 KdDebuggerData;
  22. ULONG64 EXPRLastDump = 0;
  23. //
  24. // Valid for the lifetime of the debug session.
  25. //
  26. ULONG PageSize;
  27. ULONG64 PaeEnabled;
  28. ULONG TargetMachine;
  29. BOOL Connected;
  30. ULONG BuildNo;
  31. ULONG PoolBlockShift;
  32. ULONG TargetIsDump;
  33. //
  34. // this string is for supporting both the old and the new way of getting
  35. // data from the kernel. Maybe it will go away soon.
  36. //
  37. char ___SillyString[200];
  38. PDEBUG_ADVANCED g_ExtAdvanced;
  39. PDEBUG_CLIENT g_ExtClient;
  40. PDEBUG_CONTROL2 g_ExtControl;
  41. PDEBUG_DATA_SPACES g_ExtData;
  42. PDEBUG_REGISTERS g_ExtRegisters;
  43. PDEBUG_SYMBOLS2 g_ExtSymbols;
  44. PDEBUG_SYSTEM_OBJECTS g_ExtSystem;
  45. // Queries for all debugger interfaces.
  46. extern "C" HRESULT
  47. ExtQuery(PDEBUG_CLIENT Client)
  48. {
  49. HRESULT Status;
  50. if ((Status = Client->QueryInterface(__uuidof(IDebugAdvanced),
  51. (void **)&g_ExtAdvanced)) != S_OK)
  52. {
  53. goto Fail;
  54. }
  55. if ((Status = Client->QueryInterface(__uuidof(IDebugControl2),
  56. (void **)&g_ExtControl)) != S_OK)
  57. {
  58. goto Fail;
  59. }
  60. if ((Status = Client->QueryInterface(__uuidof(IDebugDataSpaces),
  61. (void **)&g_ExtData)) != S_OK)
  62. {
  63. goto Fail;
  64. }
  65. if ((Status = Client->QueryInterface(__uuidof(IDebugRegisters),
  66. (void **)&g_ExtRegisters)) != S_OK)
  67. {
  68. goto Fail;
  69. }
  70. if ((Status = Client->QueryInterface(__uuidof(IDebugSymbols2),
  71. (void **)&g_ExtSymbols)) != S_OK)
  72. {
  73. goto Fail;
  74. }
  75. if ((Status = Client->QueryInterface(__uuidof(IDebugSystemObjects),
  76. (void **)&g_ExtSystem)) != S_OK)
  77. {
  78. goto Fail;
  79. }
  80. g_ExtClient = Client;
  81. return S_OK;
  82. Fail:
  83. ExtRelease();
  84. return Status;
  85. }
  86. // Cleans up all debugger interfaces.
  87. void
  88. ExtRelease(void)
  89. {
  90. g_ExtClient = NULL;
  91. EXT_RELEASE(g_ExtAdvanced);
  92. EXT_RELEASE(g_ExtControl);
  93. EXT_RELEASE(g_ExtData);
  94. EXT_RELEASE(g_ExtRegisters);
  95. EXT_RELEASE(g_ExtSymbols);
  96. EXT_RELEASE(g_ExtSystem);
  97. }
  98. // Normal output.
  99. void __cdecl
  100. ExtOut(PCSTR Format, ...)
  101. {
  102. va_list Args;
  103. va_start(Args, Format);
  104. g_ExtControl->OutputVaList(DEBUG_OUTPUT_NORMAL, Format, Args);
  105. va_end(Args);
  106. }
  107. // Error output.
  108. void __cdecl
  109. ExtErr(PCSTR Format, ...)
  110. {
  111. va_list Args;
  112. va_start(Args, Format);
  113. g_ExtControl->OutputVaList(DEBUG_OUTPUT_ERROR, Format, Args);
  114. va_end(Args);
  115. }
  116. // Warning output.
  117. void __cdecl
  118. ExtWarn(PCSTR Format, ...)
  119. {
  120. va_list Args;
  121. va_start(Args, Format);
  122. g_ExtControl->OutputVaList(DEBUG_OUTPUT_WARNING, Format, Args);
  123. va_end(Args);
  124. }
  125. // Verbose output.
  126. void __cdecl
  127. ExtVerb(PCSTR Format, ...)
  128. {
  129. va_list Args;
  130. va_start(Args, Format);
  131. g_ExtControl->OutputVaList(DEBUG_OUTPUT_VERBOSE, Format, Args);
  132. va_end(Args);
  133. }
  134. void
  135. GetLabIdFromBuildString(
  136. PSTR BuildString,
  137. PULONG pLabId
  138. )
  139. {
  140. PCHAR pstr;
  141. *pLabId = 0;
  142. _strlwr(BuildString);
  143. pstr = strstr(BuildString, "lab");
  144. if (pstr) {
  145. sscanf(pstr+3, "%ld", pLabId);
  146. }
  147. }
  148. extern "C"
  149. HRESULT
  150. CALLBACK
  151. DebugExtensionInitialize(PULONG Version, PULONG Flags)
  152. {
  153. IDebugClient *DebugClient;
  154. PDEBUG_CONTROL2 DebugControl;
  155. HRESULT Hr;
  156. *Version = DEBUG_EXTENSION_VERSION(1, 0);
  157. *Flags = 0;
  158. if ((Hr = DebugCreate(__uuidof(IDebugClient),
  159. (void **)&DebugClient)) != S_OK)
  160. {
  161. return Hr;
  162. }
  163. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
  164. (void **)&DebugControl)) != S_OK)
  165. {
  166. return Hr;
  167. }
  168. ExtensionApis.nSize = sizeof (ExtensionApis);
  169. if ((Hr = DebugControl->GetWindbgExtensionApis64(&ExtensionApis)) != S_OK) {
  170. return Hr;
  171. }
  172. DebugControl->Release();
  173. DebugClient->Release();
  174. return S_OK;
  175. }
  176. extern "C"
  177. void
  178. CALLBACK
  179. DebugExtensionNotify(ULONG Notify, ULONG64 Argument)
  180. {
  181. //
  182. // The first time we actually connect to a target, get the page size
  183. //
  184. if ((Notify == DEBUG_NOTIFY_SESSION_ACCESSIBLE) && (!Connected))
  185. {
  186. IDebugClient *DebugClient;
  187. PDEBUG_DATA_SPACES DebugDataSpaces;
  188. PDEBUG_CONTROL2 DebugControl;
  189. HRESULT Hr;
  190. ULONG64 Page;
  191. if ((Hr = DebugCreate(__uuidof(IDebugClient),
  192. (void **)&DebugClient)) == S_OK)
  193. {
  194. //
  195. // Get the page size and PAE enable flag
  196. //
  197. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugDataSpaces),
  198. (void **)&DebugDataSpaces)) == S_OK)
  199. {
  200. if ((Hr = DebugDataSpaces->ReadDebuggerData(
  201. DEBUG_DATA_PaeEnabled, &PaeEnabled,
  202. sizeof(PaeEnabled), NULL)) == S_OK)
  203. {
  204. if ((Hr = DebugDataSpaces->ReadDebuggerData(
  205. DEBUG_DATA_MmPageSize, &Page,
  206. sizeof(Page), NULL)) == S_OK)
  207. {
  208. PageSize = (ULONG)(ULONG_PTR)Page;
  209. }
  210. }
  211. DebugDataSpaces->Release();
  212. }
  213. //
  214. // Get the architecture type.
  215. //
  216. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
  217. (void **)&DebugControl)) == S_OK)
  218. {
  219. if (PageSize)
  220. {
  221. ULONG Platform, MajorVer, MinorVer, SrvPack, StringUsed;
  222. CHAR BuildString[100];
  223. if ((Hr = DebugControl->GetActualProcessorType(
  224. &TargetMachine)) == S_OK)
  225. {
  226. Connected = TRUE;
  227. }
  228. if ((Hr = DebugControl->GetSystemVersion(&Platform, &MajorVer,
  229. &MinorVer, NULL,
  230. 0, NULL,
  231. &SrvPack, &BuildString[0],
  232. sizeof(BuildString), &StringUsed)) == S_OK)
  233. {
  234. ULONG LabId;
  235. BuildNo = MinorVer;
  236. GetLabIdFromBuildString(BuildString, &LabId);
  237. NewPool = ((BuildNo > 2407) || (LabId == 1 && BuildNo >= 2402));
  238. PoolBlockShift = NewPool ?
  239. POOL_BLOCK_SHIFT_LAB1_2402 : POOL_BLOCK_SHIFT_OLD;
  240. }
  241. }
  242. ULONG Class, Qual;
  243. if ((Hr = DebugControl->GetDebuggeeType(&Class, &Qual)) != S_OK) {
  244. Class = Qual = 0;
  245. }
  246. if (Qual == DEBUG_DUMP_SMALL || Qual == DEBUG_DUMP_DEFAULT || Qual == DEBUG_DUMP_FULL) {
  247. TargetIsDump = TRUE;
  248. }
  249. if (Class == DEBUG_CLASS_USER_WINDOWS) {
  250. dprintf("\n**** WARNING loaded *kernel* extension dll for usermode\n\n");
  251. }
  252. DebugControl->Release();
  253. }
  254. DebugClient->Release();
  255. }
  256. }
  257. if (Notify == DEBUG_NOTIFY_SESSION_INACTIVE)
  258. {
  259. Connected = FALSE;
  260. PageSize = 0;
  261. PaeEnabled = 0;
  262. TargetMachine = 0;
  263. }
  264. return;
  265. }
  266. extern "C"
  267. void
  268. CALLBACK
  269. DebugExtensionUninitialize(void)
  270. {
  271. return;
  272. }
  273. BOOL
  274. HaveDebuggerData(
  275. VOID
  276. )
  277. {
  278. static int havedata = 0;
  279. if (havedata == 0) {
  280. if (!Ioctl( IG_GET_KERNEL_VERSION, &KernelVersionPacket, sizeof(KernelVersionPacket))) {
  281. havedata = 2;
  282. } else if (KernelVersionPacket.MajorVersion == 0) {
  283. havedata = 2;
  284. } else {
  285. havedata = 1;
  286. }
  287. }
  288. return (havedata == 1) &&
  289. ((KernelVersionPacket.Flags & DBGKD_VERS_FLAG_DATA) != 0);
  290. }
  291. BOOL
  292. GetCurrentProcessor(
  293. IN PDEBUG_CLIENT Client,
  294. OPTIONAL OUT PULONG pProcessor,
  295. OPTIONAL OUT PHANDLE phCurrentThread
  296. )
  297. {
  298. PDEBUG_SYSTEM_OBJECTS DebugSystem;
  299. ULONG64 hCurrentThread;
  300. if (Client) {
  301. if (Client->QueryInterface(__uuidof(IDebugSystemObjects),
  302. (void **)&DebugSystem) != S_OK) {
  303. return 0;
  304. }
  305. DebugSystem->GetCurrentThreadHandle(&hCurrentThread);
  306. if (phCurrentThread) {
  307. *phCurrentThread = (HANDLE) hCurrentThread;
  308. }
  309. if (pProcessor) {
  310. *pProcessor = (ULONG) hCurrentThread - 1;
  311. }
  312. DebugSystem->Release();
  313. return TRUE;
  314. }
  315. if (phCurrentThread) {
  316. *phCurrentThread = NULL;
  317. }
  318. if (pProcessor) {
  319. *pProcessor = 0;
  320. }
  321. return FALSE;
  322. }
  323. HRESULT
  324. ExecuteCommand(
  325. IN PDEBUG_CLIENT Client,
  326. IN PSTR Cmd
  327. )
  328. {
  329. if (Client &&
  330. (ExtQuery(Client) == S_OK)) {
  331. g_ExtControl->Execute(DEBUG_OUTCTL_AMBIENT,
  332. Cmd, DEBUG_EXECUTE_DEFAULT );
  333. ExtRelease();
  334. return S_OK;
  335. }
  336. return E_INVALIDARG;
  337. }
  338. HRESULT
  339. GetExtensionFunction(
  340. IN PCSTR FunctionName,
  341. IN FARPROC *Function
  342. )
  343. {
  344. if (g_ExtControl) {
  345. g_ExtControl->GetExtensionFunction(0, FunctionName, Function );
  346. return S_OK;
  347. }
  348. return E_INVALIDARG;
  349. }
  350. BOOLEAN
  351. ReadMemoryUncached (
  352. ULONG64 Offset,
  353. PVOID Buffer,
  354. ULONG BufferSize,
  355. PULONG BytesRead
  356. )
  357. {
  358. HRESULT result;
  359. result = g_ExtData->ReadVirtualUncached(Offset,
  360. Buffer,
  361. BufferSize,
  362. BytesRead);
  363. return (result == S_OK);
  364. }
  365. BOOLEAN
  366. WriteMemoryUncached (
  367. ULONG64 Offset,
  368. PVOID Buffer,
  369. ULONG BufferSize,
  370. PULONG BytesWritten
  371. )
  372. {
  373. HRESULT result;
  374. result = g_ExtData->WriteVirtualUncached(Offset,
  375. Buffer,
  376. BufferSize,
  377. BytesWritten);
  378. return (result == S_OK);
  379. }