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.

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