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.

307 lines
6.0 KiB

  1. // SAFRemoteDesktopManager.cpp : Implementation of CSAFRemoteDesktopManager
  2. #include "stdafx.h"
  3. #include "SAFrdm.h"
  4. #include "SAFRemoteDesktopManager.h"
  5. //
  6. // From HelpServiceTypeLib.idl
  7. //
  8. #include <HelpServiceTypeLib.h>
  9. #include "helpservicetypelib_i.c"
  10. #include <MPC_COM.h>
  11. #include <MPC_utils.h>
  12. #include <MPC_trace.h>
  13. #define MODULE_NAME L"SAFrdm"
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CSAFRemoteDesktopManager
  16. STDMETHODIMP CSAFRemoteDesktopManager::ReserveAcceptedLock()
  17. {
  18. HRESULT hr=E_FAIL;
  19. DWORD dwR;
  20. HANDLE hMutex = NULL, hEvent = NULL;
  21. /*
  22. * Signal the session resolver
  23. */
  24. if (!m_bstrEventName.Length() || !m_bstrMutexName.Length() )
  25. {
  26. // if we got here, the environment is missing our event name
  27. // so mention it with our ret val...
  28. hr = E_INVALIDARG;
  29. goto done;
  30. }
  31. /*
  32. * Open the handles we got from the resolver, and yank it
  33. */
  34. hMutex = OpenMutex(SYNCHRONIZE, FALSE, m_bstrMutexName);
  35. hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, m_bstrEventName);
  36. if (!hEvent || !hMutex)
  37. {
  38. // only close the mutex here!
  39. if (hMutex)
  40. CloseHandle(hMutex);
  41. hr = E_HANDLE;
  42. goto done;
  43. }
  44. /*
  45. * Now see if this is the first session to click "yes"
  46. * If so, we can have the Mutex.
  47. */
  48. dwR = WaitForSingleObject(hMutex, 0);
  49. if (dwR == WAIT_OBJECT_0)
  50. {
  51. SetEvent(hEvent);
  52. hr = S_OK;
  53. m_boolAcceptReserved = TRUE;
  54. }
  55. else if (dwR == WAIT_ABANDONED)
  56. {
  57. hr = E_OUTOFMEMORY;
  58. }
  59. else if (dwR == WAIT_TIMEOUT)
  60. {
  61. hr = E_OUTOFMEMORY;
  62. }
  63. else if (dwR == WAIT_FAILED)
  64. {
  65. // If we didn't get the mutex, then close the handle
  66. hr = E_ACCESSDENIED;
  67. }
  68. else
  69. {
  70. hr = E_UNEXPECTED;
  71. }
  72. done:
  73. // close the event handle, but NOT the mutex handle
  74. if (hEvent)
  75. CloseHandle(hEvent);
  76. if (hMutex)
  77. CloseHandle(hMutex);
  78. return hr;
  79. }
  80. STDMETHODIMP CSAFRemoteDesktopManager::Accepted()
  81. {
  82. HRESULT hr = E_FAIL;
  83. if (!m_boolAcceptReserved)
  84. {
  85. hr = E_UNEXPECTED;
  86. goto done;
  87. }
  88. /*
  89. * Signal the session resolver
  90. */
  91. if (!m_bstrEventName.Length())
  92. {
  93. // if we got here, the environment is missing our event name
  94. // so mention it with our ret val...
  95. hr = E_INVALIDARG;
  96. goto done;
  97. }
  98. /*
  99. * Open the handle we got from the resolver, and yank it
  100. */
  101. HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, m_bstrEventName);
  102. if (hEvent)
  103. {
  104. /* this is the call to the resolver that tells it we are now ready to begin RA */
  105. SetEvent(hEvent);
  106. hr = S_OK;
  107. CloseHandle(hEvent);
  108. }
  109. else
  110. hr = E_HANDLE;
  111. done:
  112. return hr;
  113. }
  114. STDMETHODIMP CSAFRemoteDesktopManager::Rejected()
  115. {
  116. return S_OK;
  117. }
  118. STDMETHODIMP CSAFRemoteDesktopManager::Aborted(BSTR reason)
  119. {
  120. /*
  121. * Write out an NT Event with the "reason" in it.
  122. */
  123. HANDLE hEvent = RegisterEventSource(NULL, MODULE_NAME);
  124. LPCWSTR ArgsArray[1]={reason};
  125. if (hEvent)
  126. {
  127. ReportEvent(hEvent, EVENTLOG_INFORMATION_TYPE,
  128. 0,
  129. SAFRDM_I_ABORT,
  130. NULL,
  131. 1,
  132. 0,
  133. ArgsArray,
  134. NULL);
  135. DeregisterEventSource(hEvent);
  136. }
  137. return S_OK;
  138. }
  139. STDMETHODIMP CSAFRemoteDesktopManager::SwitchDesktopMode(/*[in]*/ int nMode, /*[in]*/ int nRAType)
  140. {
  141. __MPC_FUNC_ENTRY(COMMONID, "CSAFRemoteDesktopManager::SwitchDesktopMode" );
  142. HRESULT hr=E_FAIL;
  143. CComPtr<IClassFactory> fact;
  144. CComQIPtr<IPCHUtility> disp;
  145. //
  146. // This is handled in a special way.
  147. //
  148. // Instead of using the implementation inside HelpCtr, we QI the PCHSVC broker and then forward the call to it.
  149. //
  150. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoGetClassObject( CLSID_PCHService, CLSCTX_ALL, NULL, IID_IClassFactory, (void**)&fact ));
  151. if((disp = fact))
  152. {
  153. __MPC_EXIT_IF_METHOD_FAILS(hr, disp->SwitchDesktopMode (nMode, nRAType));
  154. }
  155. else
  156. {
  157. __MPC_SET_ERROR_AND_EXIT(hr, E_NOINTERFACE);
  158. }
  159. hr = S_OK;
  160. __MPC_FUNC_CLEANUP;
  161. __MPC_FUNC_EXIT(hr);
  162. }
  163. STDMETHODIMP CSAFRemoteDesktopManager::get_RCTicket(BSTR *pVal)
  164. {
  165. if (!pVal)
  166. return E_INVALIDARG;
  167. *pVal = m_bstrRCTicket.Copy();
  168. return S_OK;
  169. }
  170. STDMETHODIMP CSAFRemoteDesktopManager::get_DesktopUnknown(BOOL *pVal)
  171. {
  172. if (!pVal)
  173. return E_INVALIDARG;
  174. *pVal = m_boolDesktopUnknown;
  175. return S_OK;
  176. }
  177. STDMETHODIMP CSAFRemoteDesktopManager::get_SupportEngineer(BSTR *pVal)
  178. {
  179. if (!pVal)
  180. return E_INVALIDARG;
  181. *pVal = m_bstrSupportEngineer.Copy();
  182. return S_OK;
  183. }
  184. STDMETHODIMP CSAFRemoteDesktopManager::get_userHelpBlob(BSTR *pVal)
  185. {
  186. if (!pVal)
  187. return E_INVALIDARG;
  188. *pVal = m_bstruserSupportBlob.Copy();
  189. return S_OK;
  190. }
  191. STDMETHODIMP CSAFRemoteDesktopManager::get_expertHelpBlob(BSTR *pVal)
  192. {
  193. if (!pVal)
  194. return E_INVALIDARG;
  195. *pVal = m_bstrexpertSupportBlob.Copy();
  196. return S_OK;
  197. }
  198. #if 0
  199. HRESULT CSAFRemoteDesktopManager::SignalResolver(BOOL yn)
  200. {
  201. HRESULT hr = E_FAIL;
  202. if (yn)
  203. {
  204. if (!m_bstrEventName.Length())
  205. {
  206. // if we got here, the environment is missing our event name
  207. // so mention it with our ret val...
  208. hr = E_HANDLE;
  209. goto done;
  210. }
  211. /*
  212. * Open the handle we got from the resolver, and yank it
  213. */
  214. HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, m_bstrEventName);
  215. if (hEvent)
  216. {
  217. if (!m_boolResolverSignaled)
  218. {
  219. /* This is the call to tell the resolver that we WANT to start RA */
  220. DWORD dwResult = SignalObjectAndWait(hEvent, hEvent, 60000, FALSE);
  221. if (dwResult == WAIT_OBJECT_0)
  222. hr = S_OK;
  223. else
  224. /* If the resolver does not respond within 60 seconds, then another
  225. * session got in just ahead of you...
  226. */
  227. hr = E_ACCESSDENIED;
  228. }
  229. else
  230. {
  231. /* this is the call to the resolver that tells it we are now ready to begin RA */
  232. SetEvent(hEvent);
  233. hr = S_OK;
  234. }
  235. CloseHandle(hEvent);
  236. }
  237. }
  238. else
  239. {
  240. /*
  241. * Do nothing, as the script will kill the HelpCtr window
  242. */
  243. hr = S_OK;
  244. }
  245. done:
  246. // tell the ~dtor we don't need it to signal the resolver
  247. m_boolResolverSignaled = TRUE;
  248. return hr;
  249. }
  250. #endif