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.

208 lines
5.1 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Generic interface-style extension support.
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include <windows.h>
  9. #define NOEXTAPI
  10. #include <wdbgexts.h>
  11. #include "ext.h"
  12. int g_ExtRecurse;
  13. PDEBUG_ADVANCED g_ExtAdvanced;
  14. PDEBUG_CLIENT g_ExtClient;
  15. PDEBUG_CONTROL g_ExtControl;
  16. PDEBUG_DATA_SPACES g_ExtData;
  17. PDEBUG_REGISTERS g_ExtRegisters;
  18. PDEBUG_SYMBOLS g_ExtSymbols;
  19. PDEBUG_SYSTEM_OBJECTS g_ExtSystem;
  20. PDEBUG_DATA_SPACES2 g_ExtData2;
  21. HANDLE g_hCurrentProcess;
  22. HANDLE g_hCurrentThread;
  23. WINDBG_EXTENSION_APIS ExtensionApis;
  24. WINDBG_EXTENSION_APIS32 ExtensionApis32;
  25. WINDBG_EXTENSION_APIS64 ExtensionApis64;
  26. // Queries for all debugger interfaces.
  27. HRESULT
  28. ExtQuery(PDEBUG_CLIENT Client)
  29. {
  30. HRESULT Status;
  31. if (++g_ExtRecurse > 1)
  32. {
  33. // Already queried.
  34. return S_OK;
  35. }
  36. if ((Status = Client->QueryInterface(__uuidof(IDebugAdvanced),
  37. (void **)&g_ExtAdvanced)) != S_OK)
  38. {
  39. goto Fail;
  40. }
  41. if ((Status = Client->QueryInterface(__uuidof(IDebugControl),
  42. (void **)&g_ExtControl)) != S_OK)
  43. {
  44. goto Fail;
  45. }
  46. if ((Status = Client->QueryInterface(__uuidof(IDebugDataSpaces),
  47. (void **)&g_ExtData)) != S_OK)
  48. {
  49. goto Fail;
  50. }
  51. if ((Status = Client->QueryInterface(__uuidof(IDebugRegisters),
  52. (void **)&g_ExtRegisters)) != S_OK)
  53. {
  54. goto Fail;
  55. }
  56. if ((Status = Client->QueryInterface(__uuidof(IDebugSymbols),
  57. (void **)&g_ExtSymbols)) != S_OK)
  58. {
  59. goto Fail;
  60. }
  61. if ((Status = Client->QueryInterface(__uuidof(IDebugSystemObjects),
  62. (void **)&g_ExtSystem)) != S_OK)
  63. {
  64. goto Fail;
  65. }
  66. ULONG64 Cur;
  67. if ((Status = g_ExtSystem->GetCurrentProcessHandle(&Cur)) != S_OK)
  68. {
  69. goto Fail;
  70. }
  71. g_hCurrentProcess = (HANDLE)(ULONG_PTR)Cur;
  72. if ((Status = g_ExtSystem->GetCurrentThreadHandle(&Cur)) != S_OK)
  73. {
  74. goto Fail;
  75. }
  76. g_hCurrentThread = (HANDLE)(ULONG_PTR)Cur;
  77. ExtensionApis64.nSize = sizeof(ExtensionApis64);
  78. if ((Status = g_ExtControl->
  79. GetWindbgExtensionApis64(&ExtensionApis64)) != S_OK)
  80. {
  81. goto Fail;
  82. }
  83. ExtensionApis32.nSize = sizeof(ExtensionApis32);
  84. if ((Status = g_ExtControl->
  85. GetWindbgExtensionApis32(&ExtensionApis32)) != S_OK)
  86. {
  87. goto Fail;
  88. }
  89. #ifdef _WIN64
  90. memcpy(&ExtensionApis, &ExtensionApis64, sizeof(ExtensionApis));
  91. #else
  92. memcpy(&ExtensionApis, &ExtensionApis32, sizeof(ExtensionApis));
  93. #endif
  94. // Check for version 2 interfaces. Do not consider
  95. // it fatal if they can't be queried. Extension code
  96. // must handle the potential lack of these interfaces.
  97. if ((Status = Client->QueryInterface(__uuidof(IDebugDataSpaces2),
  98. (void **)&g_ExtData2)) != S_OK)
  99. {
  100. g_ExtData2 = NULL;
  101. }
  102. g_ExtClient = Client;
  103. return S_OK;
  104. Fail:
  105. ExtRelease();
  106. return Status;
  107. }
  108. // Cleans up all debugger interfaces.
  109. void
  110. ExtRelease(void)
  111. {
  112. if (--g_ExtRecurse > 0)
  113. {
  114. // Recursive release so don't do anything.
  115. return;
  116. }
  117. g_ExtClient = NULL;
  118. g_hCurrentProcess = NULL;
  119. g_hCurrentThread = NULL;
  120. EXT_RELEASE(g_ExtAdvanced);
  121. EXT_RELEASE(g_ExtControl);
  122. EXT_RELEASE(g_ExtData);
  123. EXT_RELEASE(g_ExtRegisters);
  124. EXT_RELEASE(g_ExtSymbols);
  125. EXT_RELEASE(g_ExtSystem);
  126. EXT_RELEASE(g_ExtData2);
  127. }
  128. extern "C" HRESULT CALLBACK
  129. DebugExtensionInitialize(PULONG Version, PULONG Flags)
  130. {
  131. *Version = DEBUG_EXTENSION_VERSION(1, 0);
  132. *Flags = 0;
  133. return S_OK;
  134. }
  135. ULONG GetCurrentThreadUserID(void)
  136. {
  137. ULONG Id;
  138. if (!g_ExtSystem) {
  139. return 0;
  140. }
  141. if (g_ExtSystem->GetCurrentThreadId(&Id) != S_OK) {
  142. return 0;
  143. }
  144. return Id;
  145. }
  146. BOOL
  147. EnumerateUModeThreads(
  148. PENUMERATE_UMODE_THREADS_CALLBACK Callback,
  149. PVOID UserContext
  150. )
  151. {
  152. ULONG CurrentThreadId;
  153. ULONG ThreadId;
  154. if (!g_ExtSystem) {
  155. return FALSE;
  156. }
  157. // Remember thread we started with
  158. if (g_ExtSystem->GetCurrentThreadId(&CurrentThreadId) != S_OK) {
  159. return FALSE;
  160. }
  161. // Loop through all threads
  162. for (ThreadId=0;;ThreadId++) {
  163. // set ThreadId as current thread
  164. if (g_ExtSystem->SetCurrentThreadId(ThreadId) != S_OK) {
  165. // finished enumerateing threads
  166. break;
  167. }
  168. // call the callback routine
  169. if (!((*Callback)(ThreadId, UserContext))) {
  170. // callback failed, break out
  171. break;
  172. }
  173. }
  174. // Set current thread back to original value
  175. g_ExtSystem->SetCurrentThreadId(CurrentThreadId);
  176. return TRUE;
  177. }