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.

235 lines
8.3 KiB

  1. /******************************************************************************
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. safhelper.cpp
  5. Abstract:
  6. Redirector for ISAFRemoteDesktopServerHost.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 02/27/2001
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. #include <initguid.h>
  13. #include <HelpServiceTypeLib.h>
  14. #include <rdshost_i.c>
  15. #include <HelpServiceTypeLib_i.c>
  16. #include "wtsapi32.h"
  17. #include "winsta.h"
  18. #include "rassistance.h"
  19. #include "rassistance_i.c"
  20. #define WINDOWS_SYSTEM L"%WINDIR%\\System32"
  21. extern HRESULT RDSHost_HACKED_CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj );
  22. ////////////////////////////////////////////////////////////////////////////////
  23. static const WCHAR s_location_HELPCTR [] = HC_ROOT_HELPSVC_BINARIES L"\\HelpCtr.exe";
  24. static const WCHAR s_location_HELPSVC [] = HC_ROOT_HELPSVC_BINARIES L"\\HelpSvc.exe";
  25. static const WCHAR s_location_HELPHOST[] = HC_ROOT_HELPSVC_BINARIES L"\\HelpHost.exe";
  26. static const WCHAR s_location_RCIMLBY [] = WINDOWS_SYSTEM L"\\RCIMLby.exe";
  27. static const LPCWSTR s_include_Generic[] =
  28. {
  29. s_location_HELPCTR ,
  30. s_location_HELPSVC ,
  31. s_location_HELPHOST,
  32. s_location_RCIMLBY ,
  33. NULL
  34. };
  35. HRESULT CreateObject_RemoteDesktopSession( /*[in] */ REMOTE_DESKTOP_SHARING_CLASS sharingClass ,
  36. /*[in] */ long lTimeout ,
  37. /*[in] */ BSTR bstrConnectionParms ,
  38. /*[in] */ BSTR bstrUserHelpBlob ,
  39. /*[out, retval]*/ ISAFRemoteDesktopSession* *ppRCS )
  40. {
  41. __MPC_FUNC_ENTRY( COMMONID, "CPCHUtility::CreateObject_RemoteDesktopSession" );
  42. HRESULT hr;
  43. CComPtr<ISAFRemoteDesktopServerHost> pSAFRDServer;
  44. BOOL fEnableSessRes = TRUE;
  45. PSID pSid = NULL;
  46. CComBSTR bstrUser;
  47. LONG lSessionID;
  48. if(!ppRCS) __MPC_SET_ERROR_AND_EXIT(hr, E_POINTER);
  49. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::VerifyCallerIsTrusted( s_include_Generic ));
  50. // // Create an instance of ISAFRemoteDesktopServerHost in order to create a RDSSession.
  51. // __MPC_EXIT_IF_METHOD_FAILS(hr, pSAFRDServer.CoCreateInstance( CLSID_SAFRemoteDesktopServerHost ));
  52. __MPC_EXIT_IF_METHOD_FAILS(hr, RDSHost_HACKED_CreateInstance( NULL, IID_ISAFRemoteDesktopServerHost, (void**)&pSAFRDServer ));
  53. //
  54. // Get the Caller SID and get the Session ID to invoke CreateRemoteDesktopSessionEx().
  55. //
  56. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetCallerPrincipal( /*fImpersonate*/true, bstrUser ));
  57. // Now get the Session ID
  58. {
  59. MPC::Impersonation imp;
  60. ULONG ulReturnLength;
  61. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Initialize());
  62. //
  63. // Use the _HYDRA_ extension to GetTokenInformation to
  64. // return the SessionId from the token.
  65. //
  66. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::GetTokenInformation( (HANDLE)imp, /*Token Type */TokenSessionId, &lSessionID, sizeof(lSessionID), &ulReturnLength ));
  67. }
  68. // We have the Caller SID and the Session ID, so we are ready to call CreateRemoteDesktopSessionEx().
  69. // Decide whether we need to create a new session or open an existing session.
  70. if(::SysStringLen( bstrConnectionParms ) == 0)
  71. {
  72. // Call Create RDSSession Method of ISAFRemoteDesktopServerHost.
  73. __MPC_EXIT_IF_METHOD_FAILS(hr, pSAFRDServer->CreateRemoteDesktopSessionEx( sharingClass, fEnableSessRes, lTimeout, bstrUserHelpBlob, lSessionID, bstrUser, ppRCS ));
  74. }
  75. else
  76. {
  77. // Call Open RDSSession Method of ISAFRemoteDesktopServerHost.
  78. __MPC_EXIT_IF_METHOD_FAILS(hr, pSAFRDServer->OpenRemoteDesktopSession( bstrConnectionParms, bstrUser, ppRCS));
  79. }
  80. hr = S_OK;
  81. __MPC_FUNC_CLEANUP;
  82. __MPC_FUNC_EXIT(hr);
  83. }
  84. HRESULT ConnectToExpert(/* [in] */ BSTR bstrExpertConnectParm,
  85. /* [in] */ LONG lTimeout,
  86. /* [retval][out] */ LONG *lSafErrorCode)
  87. {
  88. __MPC_FUNC_ENTRY( COMMONID, "CPCHUtility::ConnectToExpert" );
  89. HRESULT hr;
  90. CComPtr<ISAFRemoteDesktopServerHost> pSAFRDServer;
  91. BOOL fEnableSessRes = TRUE;
  92. PSID pSid = NULL;
  93. CComBSTR bstrUser;
  94. LONG lSessionID;
  95. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::VerifyCallerIsTrusted( s_include_Generic ));
  96. // // Create an instance of ISAFRemoteDesktopServerHost in order to invoke ConnectToExpert.
  97. // __MPC_EXIT_IF_METHOD_FAILS(hr, pSAFRDServer.CoCreateInstance( CLSID_SAFRemoteDesktopServerHost ));
  98. __MPC_EXIT_IF_METHOD_FAILS(hr, RDSHost_HACKED_CreateInstance( NULL, IID_ISAFRemoteDesktopServerHost, (void**)&pSAFRDServer ));
  99. // Call ConnectToExpert Method of ISAFRemoteDesktopServerHost.
  100. __MPC_EXIT_IF_METHOD_FAILS(hr, pSAFRDServer->ConnectToExpert( bstrExpertConnectParm, lTimeout, lSafErrorCode));
  101. hr = S_OK;
  102. __MPC_FUNC_CLEANUP;
  103. __MPC_FUNC_EXIT(hr);
  104. }
  105. HRESULT SwitchDesktopMode(/* [in]*/ int nMode,
  106. /* [in]*/ int nRAType)
  107. {
  108. __MPC_FUNC_ENTRY( COMMONID, "SAFHelper::SwitchDesktopMode" );
  109. HRESULT hr=E_FAIL;
  110. WINSTATIONSHADOW WinStationShadow;
  111. bool fSuccess;
  112. CComPtr<IRARegSetting> pRARegSetting;
  113. BOOL fAllowFullControl;
  114. DWORD dwSessionId;
  115. ULONG ReturnLength;
  116. MPC::Impersonation imp;
  117. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::VerifyCallerIsTrusted( s_include_Generic ));
  118. switch(nMode)
  119. {
  120. case 0:
  121. // View Only Mode
  122. // Shadow_EnableNoInputNotify(=3) or Shadow_EnableNoInputNoNotify(=4)
  123. WinStationShadow.ShadowClass = Shadow_EnableNoInputNoNotify;
  124. break;
  125. case 1:
  126. // Full Control Mode
  127. // Shadow_EnableInputNotify(=1) or Shadow_EnableInputNoNotify(=2)
  128. // Check the policy settings to see whether Remote Control is allowed, if not give an Access Denied error.
  129. // Create the RARegSetting Class.
  130. __MPC_EXIT_IF_METHOD_FAILS(hr, pRARegSetting.CoCreateInstance( CLSID_RARegSetting, NULL, CLSCTX_INPROC_SERVER ));
  131. // Based on nRAType (representing Solicited or Unsolicited RA) read the corresponding setting.
  132. switch(nRAType)
  133. {
  134. case 0:
  135. // Solicited RA
  136. // Call get_AllowFullControl() Method of IRARegSetting.
  137. __MPC_EXIT_IF_METHOD_FAILS(hr, pRARegSetting->get_AllowFullControl(&fAllowFullControl));
  138. break;
  139. case 1:
  140. // UnSolicited RA
  141. // Call get_AllowUnsolicitedFullControl() Method of IRARegSetting.
  142. __MPC_EXIT_IF_METHOD_FAILS(hr, pRARegSetting->get_AllowUnSolicitedFullControl(&fAllowFullControl));
  143. break;
  144. default:
  145. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  146. }
  147. if(fAllowFullControl)
  148. {
  149. WinStationShadow.ShadowClass = Shadow_EnableInputNoNotify;
  150. }
  151. else
  152. {
  153. __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  154. }
  155. break;
  156. default:
  157. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  158. }
  159. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Initialize ());
  160. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Impersonate());
  161. if (!GetTokenInformation((HANDLE)imp, TokenSessionId, &dwSessionId, sizeof(dwSessionId), &ReturnLength))
  162. {
  163. __MPC_SET_ERROR_AND_EXIT(hr, HRESULT_FROM_WIN32(GetLastError()));
  164. }
  165. imp.RevertToSelf();
  166. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::WinStationSetInformation(WTS_CURRENT_SERVER,
  167. dwSessionId, //WTS_CURRENT_SESSION,
  168. WinStationShadowInfo, // Use the WinStationShadowInfo enum type for WINSTATIONINFOCLASS
  169. &WinStationShadow,
  170. sizeof(WinStationShadow)));
  171. hr = S_OK;
  172. __MPC_FUNC_CLEANUP;
  173. __MPC_FUNC_EXIT(hr);
  174. }