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.

330 lines
6.8 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. output.cpp
  5. Abstract:
  6. This file contains routines and classes
  7. to handle output.
  8. Author:
  9. Jason Hartman (JasonHa) 2000-10-16
  10. Environment:
  11. User Mode
  12. --*/
  13. #include <stdio.h>
  14. #include <dbgeng.h>
  15. #include "debug.h"
  16. #include "output.h"
  17. #define HISTORY_LENGTH 2048
  18. typedef struct {
  19. PDEBUG_CLIENT MonitorClient; // To be set by created thread
  20. PDEBUG_CLIENT Client;
  21. ULONG OutputMask;
  22. } MonitorThreadParams;
  23. DWORD WINAPI OutputMonitorThread(MonitorThreadParams *);
  24. HRESULT
  25. OutputMonitor::Monitor(
  26. PDEBUG_CLIENT ClientToMonitor,
  27. ULONG OutputMask
  28. )
  29. {
  30. Client = ClientToMonitor;
  31. if (Client == NULL) return S_FALSE;
  32. Client->AddRef();
  33. MonitorThreadParams NewThreadParams = { NULL, Client, OutputMask };
  34. HANDLE hThread;
  35. DWORD ThreadID = 0;
  36. hThread = CreateThread(NULL,
  37. 0,
  38. (LPTHREAD_START_ROUTINE)OutputMonitorThread,
  39. &NewThreadParams,
  40. 0,
  41. &ThreadID);
  42. if (hThread)
  43. {
  44. while (NewThreadParams.MonitorClient == NULL)
  45. {
  46. DWORD ExitCode = 0;
  47. if (!GetExitCodeThread(hThread, &ExitCode))
  48. DbgPrint("GetExitCodeThread returned error %lx.\n", GetLastError());
  49. if (ExitCode != STILL_ACTIVE)
  50. {
  51. ThreadID = 0;
  52. break;
  53. }
  54. SleepEx(10, TRUE);
  55. }
  56. CloseHandle(hThread);
  57. }
  58. MonitorClient = NewThreadParams.MonitorClient;
  59. return (MonitorClient != NULL) ? S_OK : S_FALSE;
  60. }
  61. HRESULT
  62. OutputMonitor::GetOutputMask(
  63. PULONG OutputMask
  64. )
  65. {
  66. HRESULT hr = S_FALSE;
  67. if (Client != NULL &&
  68. MonitorClient != NULL)
  69. {
  70. hr = Client->GetOtherOutputMask(MonitorClient, OutputMask);
  71. }
  72. return hr;
  73. }
  74. HRESULT
  75. OutputMonitor::SetOutputMask(
  76. ULONG OutputMask
  77. )
  78. {
  79. HRESULT hr = S_FALSE;
  80. if (Client != NULL &&
  81. MonitorClient != NULL)
  82. {
  83. hr = Client->SetOtherOutputMask(MonitorClient, OutputMask);
  84. }
  85. return hr;
  86. }
  87. OutputMonitor::~OutputMonitor()
  88. {
  89. if (Client)
  90. {
  91. if (MonitorClient)
  92. {
  93. Client->ExitDispatch(MonitorClient);
  94. }
  95. Client->Release();
  96. }
  97. }
  98. DWORD
  99. WINAPI
  100. OutputMonitorThread(
  101. MonitorThreadParams *Params
  102. )
  103. {
  104. HRESULT hr = S_FALSE;
  105. PDEBUG_CLIENT MonitorClient;
  106. PrintOutputCallbacks PrintCallbacks;
  107. if (Params != NULL &&
  108. Params->Client != NULL &&
  109. (hr = Params->Client->CreateClient(&MonitorClient)) == S_OK)
  110. {
  111. if ((hr = MonitorClient->SetOutputMask(Params->OutputMask |
  112. DEBUG_OUTPUT_PROMPT |
  113. DEBUG_OUTPUT_PROMPT_REGISTERS |
  114. DEBUG_OUTPUT_DEBUGGEE |
  115. DEBUG_OUTPUT_DEBUGGEE_PROMPT
  116. )) == S_OK &&
  117. (hr = MonitorClient->SetOutputCallbacks(&PrintCallbacks)) == S_OK)
  118. {
  119. if ((hr = MonitorClient->ConnectSession(DEBUG_CONNECT_SESSION_NO_ANNOUNCE, HISTORY_LENGTH)) != S_OK)
  120. {
  121. printf("Couldn't get debugger version/history: HRESULT 0x%lx\n", hr);
  122. }
  123. MonitorClient->SetOutputMask(Params->OutputMask);
  124. Params->MonitorClient = MonitorClient;
  125. hr = MonitorClient->DispatchCallbacks(INFINITE);
  126. }
  127. else
  128. {
  129. printf("Output callbacks setup failed, HRESULT: 0x%lx\n", hr);
  130. }
  131. MonitorClient->Release();
  132. }
  133. DbgPrint("OutputMonitorThread calling ExitThread().\n");
  134. ExitThread((DWORD)hr);
  135. }
  136. //----------------------------------------------------------------------------
  137. //
  138. // Default output callbacks implementation, provides IUnknown for
  139. // static classes.
  140. //
  141. //----------------------------------------------------------------------------
  142. STDMETHODIMP
  143. PrintOutputCallbacks::QueryInterface(
  144. THIS_
  145. IN REFIID InterfaceId,
  146. OUT PVOID* Interface
  147. )
  148. {
  149. *Interface = NULL;
  150. if (//(InterfaceId == IID_IUnknown) ||
  151. (InterfaceId == __uuidof(IDebugOutputCallbacks)))
  152. {
  153. *Interface = (IDebugOutputCallbacks *)this;
  154. AddRef();
  155. return S_OK;
  156. }
  157. else
  158. {
  159. return E_NOINTERFACE;
  160. }
  161. }
  162. STDMETHODIMP_(ULONG)
  163. PrintOutputCallbacks::AddRef(
  164. THIS
  165. )
  166. {
  167. // This class is designed to be static so
  168. // there's no true refcount.
  169. return 1;
  170. }
  171. STDMETHODIMP_(ULONG)
  172. PrintOutputCallbacks::Release(
  173. THIS
  174. )
  175. {
  176. // This class is designed to be static so
  177. // there's no true refcount.
  178. return 0;
  179. }
  180. STDMETHODIMP
  181. PrintOutputCallbacks::Output(
  182. THIS_
  183. IN ULONG Mask,
  184. IN PCSTR Text
  185. )
  186. {
  187. printf("%s", Text);
  188. return S_OK;
  189. }
  190. #if 0
  191. // Stuff we probably don't need
  192. OutputMonitor::OutputMonitor(
  193. PDEBUG_CLIENT DbgClient
  194. )
  195. {
  196. Client = DbgClient;
  197. if (Client != NULL)
  198. {
  199. Client->AddRef();
  200. }
  201. Saved = FALSE;
  202. }
  203. HRESULT
  204. OutputMonitor::Setup(
  205. ULONG OutMask,
  206. PDEBUG_OUTPUT_CALLBACKS OutCallbacks
  207. )
  208. {
  209. HRESULT Hr = S_FALSE;
  210. ULONG LastOutMask;
  211. PDEBUG_CLIENT f;
  212. if (Client == NULL)
  213. {
  214. return Hr;
  215. }
  216. if (!Saved)
  217. {
  218. if ((Hr = Client->GetOutputMask(&OrgOutMask)) != S_OK ||
  219. (Hr = Client->GetOutputCallbacks(&OrgOutCallbacks)) != S_OK)
  220. {
  221. return Hr;
  222. }
  223. Saved = TRUE;
  224. }
  225. if ((Hr = Client->GetOutputMask(&LastOutMask)) == S_OK &&
  226. (Hr = Client->SetOutputMask(OutMask)) == S_OK)
  227. {
  228. if ((Hr = Client->SetOutputCallbacks(OutCallbacks)) != S_OK)
  229. {
  230. Client->SetOutputMask(LastOutMask);
  231. }
  232. }
  233. return Hr;
  234. }
  235. HRESULT
  236. OutputMonitor::Execute(
  237. PCSTR pszCommand
  238. )
  239. {
  240. HRESULT hr = S_FALSE;
  241. PDEBUG_CONTROL DbgControl;
  242. if (Client != NULL &&
  243. (hr = Client->QueryInterface(__uuidof(IDebugControl),
  244. (void **)&DbgControl)) == S_OK)
  245. {
  246. hr = DbgControl->Execute(DEBUG_OUTCTL_THIS_CLIENT |
  247. DEBUG_OUTCTL_OVERRIDE_MASK,
  248. pszCommand,
  249. DEBUG_EXECUTE_NO_REPEAT);
  250. DbgControl->Release();
  251. }
  252. return hr;
  253. }
  254. #endif