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.

605 lines
14 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. exts.c
  5. Abstract:
  6. This file contains the generic routines and initialization code
  7. for the kernel debugger extensions dll.
  8. Environment:
  9. User Mode
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <ntverp.h>
  14. //
  15. // Valid for the lifetime of the debug session.
  16. //
  17. WINDBG_EXTENSION_APIS ExtensionApis;
  18. ULONG TargetMachine;
  19. BOOL Connected;
  20. ULONG g_TargetClass, g_TargetQual;
  21. ULONG g_TargetBuild;
  22. //
  23. // Valid only during an extension API call
  24. //
  25. PDEBUG_ADVANCED g_ExtAdvanced;
  26. PDEBUG_CLIENT g_ExtClient;
  27. PDEBUG_CONTROL g_ExtControl;
  28. PDEBUG_DATA_SPACES g_ExtData;
  29. PDEBUG_REGISTERS g_ExtRegisters;
  30. PDEBUG_SYMBOLS2 g_ExtSymbols;
  31. PDEBUG_SYSTEM_OBJECTS g_ExtSystem;
  32. // Queries for all debugger interfaces.
  33. extern "C" HRESULT
  34. ExtQuery(PDEBUG_CLIENT Client)
  35. {
  36. HRESULT Status;
  37. if ((Status = Client->QueryInterface(__uuidof(IDebugAdvanced),
  38. (void **)&g_ExtAdvanced)) != S_OK)
  39. {
  40. goto Fail;
  41. }
  42. if ((Status = Client->QueryInterface(__uuidof(IDebugControl),
  43. (void **)&g_ExtControl)) != S_OK)
  44. {
  45. goto Fail;
  46. }
  47. if ((Status = Client->QueryInterface(__uuidof(IDebugDataSpaces),
  48. (void **)&g_ExtData)) != S_OK)
  49. {
  50. goto Fail;
  51. }
  52. if ((Status = Client->QueryInterface(__uuidof(IDebugRegisters),
  53. (void **)&g_ExtRegisters)) != S_OK)
  54. {
  55. goto Fail;
  56. }
  57. if ((Status = Client->QueryInterface(__uuidof(IDebugSymbols),
  58. (void **)&g_ExtSymbols)) != S_OK)
  59. {
  60. goto Fail;
  61. }
  62. if ((Status = Client->QueryInterface(__uuidof(IDebugSystemObjects),
  63. (void **)&g_ExtSystem)) != S_OK)
  64. {
  65. goto Fail;
  66. }
  67. g_ExtClient = Client;
  68. return S_OK;
  69. Fail:
  70. ExtRelease();
  71. return Status;
  72. }
  73. // Cleans up all debugger interfaces.
  74. void
  75. ExtRelease(void)
  76. {
  77. g_ExtClient = NULL;
  78. EXT_RELEASE(g_ExtAdvanced);
  79. EXT_RELEASE(g_ExtControl);
  80. EXT_RELEASE(g_ExtData);
  81. EXT_RELEASE(g_ExtRegisters);
  82. EXT_RELEASE(g_ExtSymbols);
  83. EXT_RELEASE(g_ExtSystem);
  84. }
  85. // Normal output.
  86. void __cdecl
  87. ExtOut(PCSTR Format, ...)
  88. {
  89. va_list Args;
  90. va_start(Args, Format);
  91. g_ExtControl->OutputVaList(DEBUG_OUTPUT_NORMAL, Format, Args);
  92. va_end(Args);
  93. }
  94. // Error output.
  95. void __cdecl
  96. ExtErr(PCSTR Format, ...)
  97. {
  98. va_list Args;
  99. va_start(Args, Format);
  100. g_ExtControl->OutputVaList(DEBUG_OUTPUT_ERROR, Format, Args);
  101. va_end(Args);
  102. }
  103. // Warning output.
  104. void __cdecl
  105. ExtWarn(PCSTR Format, ...)
  106. {
  107. va_list Args;
  108. va_start(Args, Format);
  109. g_ExtControl->OutputVaList(DEBUG_OUTPUT_WARNING, Format, Args);
  110. va_end(Args);
  111. }
  112. // Verbose output.
  113. void __cdecl
  114. ExtVerb(PCSTR Format, ...)
  115. {
  116. va_list Args;
  117. va_start(Args, Format);
  118. g_ExtControl->OutputVaList(DEBUG_OUTPUT_VERBOSE, Format, Args);
  119. va_end(Args);
  120. }
  121. extern "C"
  122. HRESULT
  123. CALLBACK
  124. DebugExtensionInitialize(PULONG Version, PULONG Flags)
  125. {
  126. IDebugClient *DebugClient;
  127. PDEBUG_CONTROL DebugControl;
  128. HRESULT Hr;
  129. *Version = DEBUG_EXTENSION_VERSION(1, 0);
  130. *Flags = 0;
  131. if ((Hr = DebugCreate(__uuidof(IDebugClient),
  132. (void **)&DebugClient)) != S_OK)
  133. {
  134. return Hr;
  135. }
  136. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
  137. (void **)&DebugControl)) != S_OK)
  138. {
  139. return Hr;
  140. }
  141. ExtensionApis.nSize = sizeof (ExtensionApis);
  142. if ((Hr = DebugControl->GetWindbgExtensionApis64(&ExtensionApis)) != S_OK) {
  143. return Hr;
  144. }
  145. DebugControl->Release();
  146. DebugClient->Release();
  147. return S_OK;
  148. }
  149. extern "C"
  150. void
  151. CALLBACK
  152. DebugExtensionNotify(ULONG Notify, ULONG64 Argument)
  153. {
  154. //
  155. // The first time we actually connect to a target, get the page size
  156. //
  157. if ((Notify == DEBUG_NOTIFY_SESSION_ACCESSIBLE) && (!Connected))
  158. {
  159. IDebugClient *DebugClient;
  160. PDEBUG_DATA_SPACES DebugDataSpaces;
  161. PDEBUG_CONTROL DebugControl;
  162. HRESULT Hr;
  163. ULONG64 Page;
  164. if ((Hr = DebugCreate(__uuidof(IDebugClient),
  165. (void **)&DebugClient)) == S_OK)
  166. {
  167. //
  168. // Get the architecture type.
  169. //
  170. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
  171. (void **)&DebugControl)) == S_OK)
  172. {
  173. if ((Hr = DebugControl->GetActualProcessorType(
  174. &TargetMachine)) == S_OK)
  175. {
  176. Connected = TRUE;
  177. }
  178. ULONG MajorVer, Platform, MinorVer, SrvPack;
  179. if ((Hr = DebugControl->GetSystemVersion(&Platform, &MajorVer,
  180. &MinorVer, NULL,
  181. 0, NULL,
  182. &SrvPack, NULL,
  183. 0, NULL)) == S_OK) {
  184. g_TargetBuild = MinorVer;
  185. }
  186. ULONG Qualifier;
  187. if ((Hr = DebugControl->GetDebuggeeType(&g_TargetClass, &g_TargetQual)) == S_OK)
  188. {
  189. }
  190. DebugControl->Release();
  191. }
  192. DebugClient->Release();
  193. }
  194. }
  195. if (Notify == DEBUG_NOTIFY_SESSION_INACTIVE)
  196. {
  197. Connected = FALSE;
  198. TargetMachine = 0;
  199. }
  200. return;
  201. }
  202. extern "C"
  203. void
  204. CALLBACK
  205. DebugExtensionUninitialize(void)
  206. {
  207. return;
  208. }
  209. DllInit(
  210. HANDLE hModule,
  211. DWORD dwReason,
  212. DWORD dwReserved
  213. )
  214. {
  215. switch (dwReason) {
  216. case DLL_THREAD_ATTACH:
  217. break;
  218. case DLL_THREAD_DETACH:
  219. break;
  220. case DLL_PROCESS_DETACH:
  221. break;
  222. case DLL_PROCESS_ATTACH:
  223. break;
  224. }
  225. return TRUE;
  226. }
  227. DECLARE_API ( time )
  228. {
  229. dprintf("*** !time is obsolete: Use '.time'\n");
  230. return S_OK;
  231. }
  232. HRESULT
  233. PrintString(
  234. BOOL Unicode,
  235. PDEBUG_CLIENT Client,
  236. LPCSTR args
  237. )
  238. {
  239. ULONG64 AddrString;
  240. ULONG64 Displacement;
  241. STRING32 String;
  242. UNICODE_STRING UnicodeString;
  243. ULONG64 AddrBuffer;
  244. CHAR Symbol[1024];
  245. LPSTR StringData;
  246. HRESULT hResult;
  247. BOOL b;
  248. AddrString = GetExpression(args);
  249. if (!AddrString)
  250. {
  251. return E_FAIL;
  252. }
  253. //
  254. // Get the symbolic name of the string
  255. //
  256. GetSymbol(AddrString, Symbol, &Displacement);
  257. //
  258. // Read the string from the debuggees address space into our
  259. // own.
  260. b = ReadMemory(AddrString, &String, sizeof(String), NULL);
  261. if ( !b )
  262. {
  263. return E_FAIL;
  264. }
  265. INIT_API();
  266. if (IsPtr64())
  267. {
  268. hResult = g_ExtData->ReadPointersVirtual(1,
  269. AddrString + FIELD_OFFSET(STRING64, Buffer),
  270. &AddrBuffer);
  271. }
  272. else
  273. {
  274. hResult = g_ExtData->ReadPointersVirtual(1,
  275. AddrString + FIELD_OFFSET(STRING32, Buffer),
  276. &AddrBuffer);
  277. }
  278. EXIT_API();
  279. if (hResult != S_OK)
  280. {
  281. return E_FAIL;
  282. }
  283. StringData = (LPSTR) LocalAlloc(LMEM_ZEROINIT,
  284. String.Length + sizeof(UNICODE_NULL));
  285. if (!StringData)
  286. {
  287. return E_FAIL;
  288. }
  289. dprintf("String(%d,%d)", String.Length, String.MaximumLength);
  290. if (Symbol[0])
  291. {
  292. dprintf(" %s+%p", Symbol, Displacement);
  293. }
  294. b = ReadMemory(AddrBuffer, StringData, String.Length, NULL);
  295. if ( b )
  296. {
  297. if (Unicode)
  298. {
  299. ANSI_STRING AnsiString;
  300. UnicodeString.Buffer = (PWSTR)StringData;
  301. UnicodeString.Length = String.Length;
  302. UnicodeString.MaximumLength = String.Length+sizeof(UNICODE_NULL);
  303. RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString,TRUE);
  304. dprintf(" at %p: %s\n", AddrString, AnsiString.Buffer);
  305. RtlFreeAnsiString(&AnsiString);
  306. }
  307. else
  308. {
  309. dprintf(" at %p: %s\n", AddrString, StringData);
  310. }
  311. LocalFree(StringData);
  312. return S_OK;
  313. }
  314. else
  315. {
  316. LocalFree(StringData);
  317. return E_FAIL;
  318. }
  319. }
  320. DECLARE_API( str )
  321. /*++
  322. Routine Description:
  323. This function is called to format and dump counted (ansi) string.
  324. Arguments:
  325. args - Address
  326. Return Value:
  327. None.
  328. --*/
  329. {
  330. return PrintString(FALSE, Client, args);
  331. }
  332. DECLARE_API( ustr )
  333. /*++
  334. Routine Description:
  335. This function is called to format and dump counted (unicode) string.
  336. Arguments:
  337. args - Address
  338. Return Value:
  339. None.
  340. --*/
  341. {
  342. return PrintString(TRUE, Client, args);
  343. }
  344. DECLARE_API( obja )
  345. /*++
  346. Routine Description:
  347. This function is called to format and dump an object attributes structure.
  348. Arguments:
  349. args - Address
  350. Return Value:
  351. None.
  352. --*/
  353. {
  354. ULONG64 AddrObja;
  355. ULONG64 Displacement;
  356. ULONG64 AddrString;
  357. STRING32 String;
  358. ULONG64 StrAddr = NULL;
  359. CHAR Symbol[1024];
  360. LPSTR StringData;
  361. BOOL b;
  362. ULONG Attr;
  363. HRESULT hResult;
  364. ULONG ObjectNameOffset;
  365. ULONG AttrOffset;
  366. ULONG StringOffset;
  367. if (IsPtr64())
  368. {
  369. ObjectNameOffset = FIELD_OFFSET(OBJECT_ATTRIBUTES64, ObjectName);
  370. AttrOffset = FIELD_OFFSET(OBJECT_ATTRIBUTES64, Attributes);
  371. StringOffset = FIELD_OFFSET(STRING64, Buffer);
  372. }
  373. else
  374. {
  375. ObjectNameOffset = FIELD_OFFSET(OBJECT_ATTRIBUTES32, ObjectName);
  376. AttrOffset = FIELD_OFFSET(OBJECT_ATTRIBUTES32, Attributes);
  377. StringOffset = FIELD_OFFSET(STRING32, Buffer);
  378. }
  379. AddrObja = GetExpression(args);
  380. if (!AddrObja)
  381. {
  382. return E_FAIL;
  383. }
  384. //
  385. // Get the symbolic name of the Obja
  386. //
  387. GetSymbol(AddrObja, Symbol, &Displacement);
  388. dprintf("Obja %s+%p at %p:\n", Symbol, Displacement, AddrObja);
  389. INIT_API();
  390. hResult = g_ExtData->ReadPointersVirtual(1,
  391. AddrObja + ObjectNameOffset,
  392. &AddrString);
  393. if (hResult != S_OK)
  394. {
  395. return E_FAIL;
  396. }
  397. if (AddrString)
  398. {
  399. b = ReadMemory(AddrString, &String, sizeof(String), NULL);
  400. hResult = g_ExtData->ReadPointersVirtual(1,
  401. AddrString + StringOffset,
  402. &StrAddr);
  403. }
  404. EXIT_API();
  405. if (StrAddr)
  406. {
  407. StringData = (LPSTR)LocalAlloc(LMEM_ZEROINIT,
  408. String.Length+sizeof(UNICODE_NULL));
  409. if (StringData)
  410. {
  411. b = ReadMemory(StrAddr, StringData, String.Length, NULL);
  412. if (b)
  413. {
  414. dprintf("\tName is %s\n", StringData);
  415. }
  416. LocalFree(StringData);
  417. }
  418. }
  419. b = ReadMemory(AddrObja + AttrOffset, &Attr, sizeof(Attr), NULL);
  420. if (!b)
  421. {
  422. return E_FAIL;
  423. }
  424. if (Attr & OBJ_INHERIT )
  425. {
  426. dprintf("\tOBJ_INHERIT\n");
  427. }
  428. if (Attr & OBJ_PERMANENT )
  429. {
  430. dprintf("\tOBJ_PERMANENT\n");
  431. }
  432. if (Attr & OBJ_EXCLUSIVE )
  433. {
  434. dprintf("\tOBJ_EXCLUSIVE\n");
  435. }
  436. if (Attr & OBJ_CASE_INSENSITIVE )
  437. {
  438. dprintf("\tOBJ_CASE_INSENSITIVE\n");
  439. }
  440. if (Attr & OBJ_OPENIF )
  441. {
  442. dprintf("\tOBJ_OPENIF\n");
  443. }
  444. return S_OK;
  445. }
  446. DECLARE_API( help )
  447. {
  448. dprintf("cbreg [%%%%]<RegBaseAddress> - Displays CardBus and ExCA registers\n");
  449. dprintf("db [Flag] [Address [L <Range>]] - Displays memory in bytes and ANSI chars\n");
  450. dprintf("dc [Flag] [Address [L <Range>]] - Displays memory in ULONGs and ANSI chars\n");
  451. dprintf("dd [Flag] [Address [L <Range>]] - Displays memory in ULONGs\n");
  452. dprintf("diskspace <DriveLetter>[:] - Displays free disk space for volume\n");
  453. dprintf("dp [Flag] [Address [L <Range>]] - Displays memory in ULONG_PTR\n");
  454. dprintf("du [Flag] [Address [L <Range>]] - Displays memory in wide chars\n");
  455. dprintf("dw [Flag] [Address [L <Range>]] - Displays memory in USHORTs\n");
  456. dprintf("eb [Flag] <Address> [[Value1] [[Value2]...]]] - Write bytes into memory\n");
  457. dprintf("ed [Flag] <Address> [[Value1] [[Value2]...]]] - Write ULONGs into memory\n");
  458. dprintf("ecb <Bus>.<Dev>.<Func> <Offset> <Data> - Edit PCI ConfigSpace byte\n");
  459. dprintf("ecd <Bus>.<Dev>.<Func> <Offset> <Data> - Edit PCI ConfigSpace ULONG\n");
  460. dprintf("ecs - Edit PCI ConfigSpace help\n");
  461. dprintf("ecw <Bus>.<Dev>.<Func> <Offset> <Data> - Edit PCI ConfigSpace WORD\n");
  462. dprintf("exca <BasePort>.<SocketNum> - Displays CardBus ExCA registers only\n");
  463. dprintf("help - Show this help\n");
  464. dprintf("pci [Flag] [Bus] [Device] [Function] [MinAddr] [MaxAddr]\n");
  465. dprintf(" - Displays PCI type1 config\n");
  466. dprintf("\nType \".hh [command]\" for more detailed help\n");
  467. return S_OK;
  468. }