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.

612 lines
15 KiB

  1. /*++
  2. Copyright (c) 1993-2000 Microsoft Corporation
  3. Module Name:
  4. kdexts.cxx
  5. Abstract:
  6. This file contains the generic routines and initialization code
  7. for the kernel debugger extensions dll.
  8. Author:
  9. Wesley Witt (wesw) 26-Aug-1993
  10. Environment:
  11. User Mode
  12. --*/
  13. #include "precomp.hxx"
  14. //
  15. // globals
  16. //
  17. HINSTANCE ghDllInst;
  18. WINDBG_EXTENSION_APIS64 ExtensionApis;
  19. BOOL gbVerbose = FALSE;
  20. DBGKD_GET_VERSION64 KernelVersionPacket;
  21. ULONG64 EXPRLastDump = 0;
  22. //
  23. // Valid for the lifetime of the debug session.
  24. //
  25. ULONG PageSize;
  26. ULONG PageShift;
  27. ULONG64 PaeEnabled;
  28. ULONG TargetMachine;
  29. ULONG TargetClass;
  30. ULONG PlatformId = -1;
  31. ULONG MajorVer = 0;
  32. ULONG MinorVer = 0;
  33. ULONG SrvPack = 0;
  34. ULONG BuildNo = 0;
  35. BOOL NewPool = FALSE;
  36. ULONG PoolBlockShift;
  37. BOOL Connected = FALSE;
  38. BOOL Remote = FALSE;
  39. CHAR RemoteID[MAX_PATH];
  40. ModuleParameters GDIKM_Module = { 0, DEBUG_ANY_ID, "win32k", "sys" };
  41. ModuleParameters GDIUM_Module = { 0, DEBUG_ANY_ID, "gdi32", "dll" };
  42. ModuleParameters Type_Module;
  43. HRESULT SymbolInit(PDEBUG_CLIENT);
  44. BOOLEAN
  45. WINAPI
  46. DllMain(
  47. HINSTANCE hInstDll,
  48. DWORD fdwReason,
  49. LPVOID lpvReserved
  50. )
  51. {
  52. switch (fdwReason) {
  53. case DLL_THREAD_ATTACH:
  54. break;
  55. case DLL_THREAD_DETACH:
  56. break;
  57. case DLL_PROCESS_DETACH:
  58. break;
  59. case DLL_PROCESS_ATTACH:
  60. DbgPrint("DllMain: DLL_PROCESS_ATTACH: hInstance = %lx => ghDllInit(%lx)\n", hInstDll, ghDllInst);
  61. ghDllInst = hInstDll;
  62. break;
  63. }
  64. return TRUE;
  65. }
  66. extern "C"
  67. HRESULT
  68. CALLBACK
  69. DebugExtensionSetClient(
  70. LPCSTR RemoteArgs
  71. )
  72. {
  73. if (RemoteArgs != NULL)
  74. {
  75. Remote = TRUE;
  76. strncpy(RemoteID, RemoteArgs, sizeof(RemoteID));
  77. }
  78. else
  79. {
  80. Remote = FALSE;
  81. }
  82. return S_OK;
  83. }
  84. HRESULT
  85. GetDebugClient(
  86. PDEBUG_CLIENT *pClient
  87. )
  88. {
  89. HRESULT Hr = S_FALSE;
  90. PDEBUG_CLIENT Client;
  91. if (pClient == NULL)
  92. {
  93. return S_FALSE;
  94. }
  95. *pClient = NULL;
  96. if (Remote)
  97. {
  98. Hr = DebugConnect(RemoteID, __uuidof(IDebugClient), (void **)&Client);
  99. if (Hr == S_OK)
  100. {
  101. Hr = Client->ConnectSession(DEBUG_CONNECT_SESSION_NO_VERSION |
  102. DEBUG_CONNECT_SESSION_NO_ANNOUNCE,
  103. 0);
  104. if (Hr != S_OK)
  105. {
  106. Client->Release();
  107. }
  108. }
  109. }
  110. else
  111. {
  112. Hr = DebugCreate(__uuidof(IDebugClient), (void **)&Client);
  113. }
  114. if (Hr == S_OK)
  115. {
  116. *pClient = Client;
  117. }
  118. return Hr;
  119. }
  120. void
  121. GetLabIdFromBuildString(
  122. PSTR BuildString,
  123. PULONG pLabId
  124. )
  125. {
  126. PCHAR pstr;
  127. *pLabId = 0;
  128. _strlwr(BuildString);
  129. pstr = strstr(BuildString, "lab");
  130. if (pstr) {
  131. sscanf(pstr+3, "%ld", pLabId);
  132. }
  133. }
  134. //PDEBUG_EXTENSION_INITIALIZE
  135. extern "C"
  136. HRESULT
  137. CALLBACK
  138. DebugExtensionInitialize(
  139. PULONG Version,
  140. PULONG Flags
  141. )
  142. {
  143. IDebugClient *DebugClient;
  144. PDEBUG_CONTROL DebugControl;
  145. HRESULT Hr;
  146. DbgPrint("DebugExtensionInitialize called.\n");
  147. *Version = DEBUG_EXTENSION_VERSION(1, 0);
  148. *Flags = 0;
  149. if ((Hr = GetDebugClient(&DebugClient)) != S_OK)
  150. {
  151. return Hr;
  152. }
  153. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
  154. (void **)&DebugControl)) != S_OK)
  155. {
  156. DebugClient->Release();
  157. return Hr;
  158. }
  159. ExtensionApis.nSize = sizeof(ExtensionApis);
  160. if ((Hr = DebugControl->GetWindbgExtensionApis64(&ExtensionApis)) != S_OK)
  161. {
  162. GetRemoteWindbgExtApis(&ExtensionApis);
  163. }
  164. Hr = SetEventCallbacks(DebugClient);
  165. DbgPrint("EventCallbacks set for 0x%p returned %s.\n",
  166. DebugClient, pszHRESULT(Hr));
  167. ViewerInit();
  168. DebugControl->Release();
  169. DebugClient->Release();
  170. return S_OK;
  171. }
  172. //PDEBUG_EXTENSION_NOTIFY
  173. extern "C"
  174. void
  175. CALLBACK
  176. DebugExtensionNotify(
  177. ULONG Notify,
  178. ULONG64 Argument
  179. )
  180. {
  181. switch (Notify) {
  182. case DEBUG_NOTIFY_SESSION_ACTIVE:
  183. DbgPrint("DebugExtensionNotify recieved DEBUG_NOTIFY_SESSION_ACTIVE\n");
  184. break;
  185. case DEBUG_NOTIFY_SESSION_INACTIVE:
  186. DbgPrint("DebugExtensionNotify recieved DEBUG_NOTIFY_SESSION_INACTIVE\n");
  187. break;
  188. case DEBUG_NOTIFY_SESSION_ACCESSIBLE:
  189. DbgPrint("DebugExtensionNotify recieved DEBUG_NOTIFY_SESSION_ACCESSIBLE\n");
  190. break;
  191. case DEBUG_NOTIFY_SESSION_INACCESSIBLE:
  192. DbgPrint("DebugExtensionNotify recieved DEBUG_NOTIFY_SESSION_INACCESSIBLE\n");
  193. break;
  194. default:
  195. DbgPrint("DebugExtensionNotify recieved unknown notification %u\n", Notify);
  196. break;
  197. }
  198. //
  199. // The first time we actually connect to a target, get the architecture
  200. //
  201. if ((Notify == DEBUG_NOTIFY_SESSION_ACCESSIBLE) && (!Connected))
  202. {
  203. IDebugClient *DebugClient;
  204. PDEBUG_CONTROL DebugControl;
  205. PDEBUG_DATA_SPACES DebugDataSpaces;
  206. HRESULT Hr;
  207. ULONG64 Page;
  208. if ((Hr = GetDebugClient(&DebugClient)) == S_OK)
  209. {
  210. //
  211. // Get the page size and PAE enable flag
  212. //
  213. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugDataSpaces),
  214. (void **)&DebugDataSpaces)) == S_OK)
  215. {
  216. if ((Hr = DebugDataSpaces->ReadDebuggerData(
  217. DEBUG_DATA_PaeEnabled, &PaeEnabled,
  218. sizeof(PaeEnabled), NULL)) == S_OK)
  219. {
  220. if ((Hr = DebugDataSpaces->ReadDebuggerData(
  221. DEBUG_DATA_MmPageSize, &Page,
  222. sizeof(Page), NULL)) == S_OK)
  223. {
  224. PageSize = (ULONG)(ULONG_PTR)Page;
  225. for (PageShift = 0; Page >>= 1; PageShift++) ;
  226. }
  227. }
  228. DebugDataSpaces->Release();
  229. }
  230. //
  231. // Get the architecture type.
  232. //
  233. if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
  234. (void **)&DebugControl)) == S_OK)
  235. {
  236. if ((Hr = DebugControl->GetActualProcessorType(
  237. &TargetMachine)) == S_OK)
  238. {
  239. Connected = TRUE;
  240. }
  241. ULONG Qualifier;
  242. if ((Hr = DebugControl->GetDebuggeeType(&TargetClass, &Qualifier)) != S_OK)
  243. {
  244. TargetClass = DEBUG_CLASS_UNINITIALIZED;
  245. }
  246. ULONG StringUsed;
  247. CHAR BuildString[100];
  248. if ((Hr = DebugControl->GetSystemVersion(&PlatformId, &MajorVer,
  249. &MinorVer, NULL,
  250. 0, NULL,
  251. &SrvPack, BuildString,
  252. sizeof(BuildString), &StringUsed)) == S_OK)
  253. {
  254. PCHAR pstr;
  255. ULONG LabId = 0;
  256. BuildNo = MinorVer;
  257. _strlwr(BuildString);
  258. pstr = strstr(BuildString, "lab");
  259. if (pstr != NULL)
  260. {
  261. sscanf(pstr+3, "%ld", &LabId);
  262. }
  263. NewPool = ((BuildNo > 2407) || (LabId == 1 && BuildNo >= 2402));
  264. PoolBlockShift = NewPool ?
  265. POOL_BLOCK_SHIFT_LAB1_2402 : POOL_BLOCK_SHIFT_OLD;
  266. }
  267. else
  268. {
  269. PlatformId = -1;
  270. MajorVer = 0;
  271. MinorVer = 0;
  272. SrvPack = 0;
  273. BuildNo = 0;
  274. NewPool = FALSE;
  275. PoolBlockShift = PageShift - 8;
  276. }
  277. DebugControl->Release();
  278. }
  279. // Try to initialize symbols only if the event monitor
  280. // hasn't fully registered. This indicates that the
  281. // extension is just being loaded as opposed to being
  282. // loaded at system boot and reconnect (when GDI modules
  283. // won't even be loaded yet).
  284. if (UniqueTargetState == INVALID_UNIQUE_STATE)
  285. {
  286. SymbolInit(DebugClient);
  287. }
  288. DebugClient->Release();
  289. }
  290. }
  291. if (Notify == DEBUG_NOTIFY_SESSION_INACTIVE)
  292. {
  293. Connected = FALSE;
  294. TargetMachine = 0;
  295. PlatformId = -1;
  296. MajorVer = 0;
  297. MinorVer = 0;
  298. SrvPack = 0;
  299. }
  300. return;
  301. }
  302. //PDEBUG_EXTENSION_UNINITIALIZE
  303. extern "C"
  304. void
  305. CALLBACK
  306. DebugExtensionUninitialize(void)
  307. {
  308. DbgPrint("DebugExtensionUninitialize called.\n");
  309. SessionExit();
  310. HmgrExit();
  311. ViewerExit();
  312. BasicTypesExit();
  313. ReleaseEventCallbacks(NULL);
  314. ExtRelease(TRUE);
  315. return;
  316. }
  317. BOOLEAN
  318. IsCheckedBuild(
  319. PBOOLEAN Checked
  320. )
  321. {
  322. if (MajorVer == 0) return FALSE;
  323. //
  324. // 0xC for checked, 0xF for free.
  325. //
  326. *Checked = ((MajorVer & 0xFF) == 0xc) ;
  327. return TRUE;
  328. }
  329. HRESULT GetModuleParameters(
  330. PDEBUG_CLIENT Client,
  331. ModuleParameters *Module,
  332. BOOL TryReload
  333. )
  334. {
  335. HRESULT hr;
  336. PDEBUG_SYMBOLS Symbols;
  337. OutputControl OutCtl(Client);
  338. if (Client == NULL) return E_POINTER;
  339. if ((hr = Client->QueryInterface(__uuidof(IDebugSymbols),
  340. (void **)&Symbols)) != S_OK)
  341. {
  342. return hr;
  343. }
  344. hr = Symbols->GetModuleByModuleName(Module->Name, 0, &Module->Index, &Module->Base);
  345. Client->FlushCallbacks();
  346. if (hr != S_OK && TryReload)
  347. {
  348. CHAR ReloadArgs[MAX_PATH];
  349. OutCtl.OutVerb("GetModuleByModuleName returned %s.\n", pszHRESULT(hr));
  350. sprintf(ReloadArgs,
  351. (Module->Base != 0) ? "%s.%s=0x%I64x" : "%s.%s",
  352. Module->Name, Module->Ext, Module->Base);
  353. OutCtl.OutWarn("Trying %s reload.\n", ReloadArgs);
  354. hr = Symbols->Reload(ReloadArgs);
  355. Client->FlushCallbacks();
  356. if (hr == S_OK)
  357. {
  358. hr = Symbols->GetModuleByModuleName(Module->Name, 0, &Module->Index, &Module->Base);
  359. OutCtl.OutVerb("Module %s @ 0x%p; HRESULT %s\n", Module->Name, Module->Base, pszHRESULT(hr));
  360. Client->FlushCallbacks();
  361. }
  362. else
  363. {
  364. OutCtl.OutWarn("Reload(\"%s\") returned %s\n", ReloadArgs, pszHRESULT(hr));
  365. }
  366. }
  367. else
  368. {
  369. OutCtl.OutVerb("Module %s @ 0x%p.\n", Module->Name, Module->Base);
  370. }
  371. if (hr == S_OK)
  372. {
  373. hr = Symbols->GetModuleParameters(1,
  374. NULL,
  375. Module->Index,
  376. &Module->DbgModParams);
  377. OutCtl.OutVerb("SymbolType for %s: ", Module->Name);
  378. switch (Module->DbgModParams.SymbolType)
  379. {
  380. case DEBUG_SYMTYPE_NONE: OutCtl.OutVerb("NONE"); break;
  381. case DEBUG_SYMTYPE_COFF: OutCtl.OutVerb("COFF"); break;
  382. case DEBUG_SYMTYPE_CODEVIEW: OutCtl.OutVerb("CODEVIEW"); break;
  383. case DEBUG_SYMTYPE_PDB: OutCtl.OutVerb("PDB"); break;
  384. case DEBUG_SYMTYPE_EXPORT: OutCtl.OutVerb("EXPORT"); break;
  385. case DEBUG_SYMTYPE_DEFERRED: OutCtl.OutVerb("DEFERRED"); break;
  386. case DEBUG_SYMTYPE_SYM: OutCtl.OutVerb("SYM"); break;
  387. case DEBUG_SYMTYPE_DIA: OutCtl.OutVerb("DIA"); break;
  388. default:
  389. OutCtl.OutVerb("unknown %ld", Module->DbgModParams.SymbolType);
  390. break;
  391. }
  392. OutCtl.OutVerb(" (HRESULT %s)\n", pszHRESULT(hr));
  393. Client->FlushCallbacks();
  394. }
  395. Symbols->Release();
  396. return hr;
  397. }
  398. HRESULT
  399. SymbolLoad(
  400. PDEBUG_CLIENT Client
  401. )
  402. {
  403. HRESULT hr;
  404. ULONG Class;
  405. ULONG Qualifier;
  406. if (TargetClass != DEBUG_CLASS_USER_WINDOWS)
  407. {
  408. GetModuleParameters(Client, &GDIUM_Module, FALSE);
  409. if ((hr = GetModuleParameters(Client, &GDIKM_Module, TRUE)) == S_OK &&
  410. GDIKM_Module.Base != 0)
  411. {
  412. Type_Module = GDIKM_Module;
  413. }
  414. }
  415. else
  416. {
  417. hr = GetModuleParameters(Client, &GDIUM_Module, TRUE);
  418. }
  419. if (hr == S_OK)
  420. {
  421. gbSymbolsNotLoaded = FALSE;
  422. }
  423. if (Type_Module.Base == 0)
  424. {
  425. Type_Module = GDIUM_Module;
  426. }
  427. DbgPrint("Using %s for type module.\n", Type_Module.Name);
  428. return hr;
  429. }
  430. HRESULT SymbolInit(PDEBUG_CLIENT Client)
  431. {
  432. HRESULT hr;
  433. GDIKM_Module.Base = 0;
  434. GDIUM_Module.Base = 0;
  435. Type_Module.Base = 0;
  436. hr = SymbolLoad(Client);
  437. BasicTypesInit(Client);
  438. HmgrInit(Client);
  439. SessionInit(Client);
  440. return hr;
  441. }
  442. HRESULT
  443. InitAPI(PDEBUG_CLIENT Client, PCSTR ExtName)
  444. {
  445. static BOOL SecondaryCall = FALSE;
  446. HRESULT hr;
  447. hr = EventCallbacksReady(Client);
  448. if (hr != S_OK)
  449. {
  450. OutputControl OutCtl(Client);
  451. OutCtl.OutWarn(" Warning: Event callbacks have not been registered.\n");
  452. if (SecondaryCall)
  453. {
  454. OutCtl.OutWarn(" All extension caching is disabled.\n");
  455. }
  456. else
  457. {
  458. OutCtl.OutWarn(" If %s is the first extension used, use .load or !load in the future.\n"
  459. " Caching is disabled for this use of !%s.\n",
  460. ExtName, ExtName);
  461. }
  462. }
  463. SecondaryCall = TRUE;
  464. if (gbSymbolsNotLoaded)
  465. {
  466. SymbolInit(Client);
  467. }
  468. return hr;
  469. }
  470. DECLARE_API(reinit)
  471. {
  472. HRESULT hr;
  473. hr = SymbolInit(Client);
  474. return hr;
  475. }
  476. DECLARE_API(verbose)
  477. {
  478. INIT_API();
  479. gbVerbose = !gbVerbose;
  480. ExtOut(" GDIKDX Verbose mode is now %s.\n", gbVerbose ? "ON" : "OFF");
  481. EXIT_API(S_OK);
  482. }