FreeRDP
win_wds.c
1 
19 #include <freerdp/config.h>
20 
21 #include <winpr/crt.h>
22 #include <winpr/print.h>
23 #include <freerdp/log.h>
24 
25 #include "win_rdp.h"
26 
27 #include "win_wds.h"
28 
43 #undef DEFINE_GUID
44 #define INITGUID
45 
46 #include <initguid.h>
47 
48 #include <freerdp/assistance.h>
49 
50 #define TAG SERVER_TAG("shadow.win")
51 
52 DEFINE_GUID(CLSID_RDPSession, 0x9B78F0E6, 0x3E05, 0x4A5B, 0xB2, 0xE8, 0xE7, 0x43, 0xA8, 0x95, 0x6B,
53  0x65);
54 DEFINE_GUID(DIID__IRDPSessionEvents, 0x98a97042, 0x6698, 0x40e9, 0x8e, 0xfd, 0xb3, 0x20, 0x09, 0x90,
55  0x00, 0x4b);
56 DEFINE_GUID(IID_IRDPSRAPISharingSession, 0xeeb20886, 0xe470, 0x4cf6, 0x84, 0x2b, 0x27, 0x39, 0xc0,
57  0xec, 0x5c, 0xfb);
58 DEFINE_GUID(IID_IRDPSRAPIAttendee, 0xec0671b3, 0x1b78, 0x4b80, 0xa4, 0x64, 0x91, 0x32, 0x24, 0x75,
59  0x43, 0xe3);
60 DEFINE_GUID(IID_IRDPSRAPIAttendeeManager, 0xba3a37e8, 0x33da, 0x4749, 0x8d, 0xa0, 0x07, 0xfa, 0x34,
61  0xda, 0x79, 0x44);
62 DEFINE_GUID(IID_IRDPSRAPISessionProperties, 0x339b24f2, 0x9bc0, 0x4f16, 0x9a, 0xac, 0xf1, 0x65,
63  0x43, 0x3d, 0x13, 0xd4);
64 DEFINE_GUID(CLSID_RDPSRAPIApplicationFilter, 0xe35ace89, 0xc7e8, 0x427e, 0xa4, 0xf9, 0xb9, 0xda,
65  0x07, 0x28, 0x26, 0xbd);
66 DEFINE_GUID(CLSID_RDPSRAPIInvitationManager, 0x53d9c9db, 0x75ab, 0x4271, 0x94, 0x8a, 0x4c, 0x4e,
67  0xb3, 0x6a, 0x8f, 0x2b);
68 
69 static ULONG Shadow_IRDPSessionEvents_RefCount = 0;
70 
71 const char* GetRDPSessionEventString(DISPID id)
72 {
73  switch (id)
74  {
75  case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_CONNECTED:
76  return "OnAttendeeConnected";
77  break;
78 
79  case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_DISCONNECTED:
80  return "OnAttendeeDisconnected";
81  break;
82 
83  case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_UPDATE:
84  return "OnAttendeeUpdate";
85  break;
86 
87  case DISPID_RDPSRAPI_EVENT_ON_ERROR:
88  return "OnError";
89  break;
90 
91  case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTED:
92  return "OnConnectionEstablished";
93  break;
94 
95  case DISPID_RDPSRAPI_EVENT_ON_VIEWER_DISCONNECTED:
96  return "OnConnectionTerminated";
97  break;
98 
99  case DISPID_RDPSRAPI_EVENT_ON_VIEWER_AUTHENTICATED:
100  return "OnConnectionAuthenticated";
101  break;
102 
103  case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTFAILED:
104  return "OnConnectionFailed";
105  break;
106 
107  case DISPID_RDPSRAPI_EVENT_ON_CTRLLEVEL_CHANGE_REQUEST:
108  return "OnControlLevelChangeRequest";
109  break;
110 
111  case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_PAUSED:
112  return "OnGraphicsStreamPaused";
113  break;
114 
115  case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_RESUMED:
116  return "OnGraphicsStreamResumed";
117  break;
118 
119  case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_JOIN:
120  return "OnChannelJoin";
121  break;
122 
123  case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_LEAVE:
124  return "OnChannelLeave";
125  break;
126 
127  case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_DATARECEIVED:
128  return "OnChannelDataReceived";
129  break;
130 
131  case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_SENDCOMPLETED:
132  return "OnChannelDataSent";
133  break;
134 
135  case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_OPEN:
136  return "OnApplicationOpen";
137  break;
138 
139  case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_CLOSE:
140  return "OnApplicationClose";
141  break;
142 
143  case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_UPDATE:
144  return "OnApplicationUpdate";
145  break;
146 
147  case DISPID_RDPSRAPI_EVENT_ON_WINDOW_OPEN:
148  return "OnWindowOpen";
149  break;
150 
151  case DISPID_RDPSRAPI_EVENT_ON_WINDOW_CLOSE:
152  return "OnWindowClose";
153  break;
154 
155  case DISPID_RDPSRAPI_EVENT_ON_WINDOW_UPDATE:
156  return "OnWindowUpdate";
157  break;
158 
159  case DISPID_RDPSRAPI_EVENT_ON_APPFILTER_UPDATE:
160  return "OnAppFilterUpdate";
161  break;
162 
163  case DISPID_RDPSRAPI_EVENT_ON_SHARED_RECT_CHANGED:
164  return "OnSharedRectChanged";
165  break;
166 
167  case DISPID_RDPSRAPI_EVENT_ON_FOCUSRELEASED:
168  return "OnFocusReleased";
169  break;
170 
171  case DISPID_RDPSRAPI_EVENT_ON_SHARED_DESKTOP_SETTINGS_CHANGED:
172  return "OnSharedDesktopSettingsChanged";
173  break;
174 
175  case DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED:
176  return "OnViewingSizeChanged";
177  break;
178  }
179 
180  return "OnUnknown";
181 }
182 
183 static HRESULT STDMETHODCALLTYPE
184 Shadow_IRDPSessionEvents_QueryInterface(__RPC__in _IRDPSessionEvents* This,
185  /* [in] */ __RPC__in REFIID riid,
186  /* [annotation][iid_is][out] */
187  _COM_Outptr_ void** ppvObject)
188 {
189  *ppvObject = NULL;
190 
191  if (IsEqualIID(riid, &DIID__IRDPSessionEvents) || IsEqualIID(riid, &IID_IDispatch) ||
192  IsEqualIID(riid, &IID_IUnknown))
193  {
194  *ppvObject = This;
195  }
196 
197  if (!(*ppvObject))
198  return E_NOINTERFACE;
199 
200  This->lpVtbl->AddRef(This);
201  return S_OK;
202 }
203 
204 static ULONG STDMETHODCALLTYPE Shadow_IRDPSessionEvents_AddRef(__RPC__in _IRDPSessionEvents* This)
205 {
206  Shadow_IRDPSessionEvents_RefCount++;
207  return Shadow_IRDPSessionEvents_RefCount;
208 }
209 
210 static ULONG STDMETHODCALLTYPE Shadow_IRDPSessionEvents_Release(__RPC__in _IRDPSessionEvents* This)
211 {
212  if (!Shadow_IRDPSessionEvents_RefCount)
213  return 0;
214 
215  Shadow_IRDPSessionEvents_RefCount--;
216  return Shadow_IRDPSessionEvents_RefCount;
217 }
218 
219 static HRESULT STDMETHODCALLTYPE
220 Shadow_IRDPSessionEvents_GetTypeInfoCount(__RPC__in _IRDPSessionEvents* This,
221  /* [out] */ __RPC__out UINT* pctinfo)
222 {
223  WLog_INFO(TAG, "Shadow_IRDPSessionEvents_GetTypeInfoCount");
224  *pctinfo = 1;
225  return S_OK;
226 }
227 
228 static HRESULT STDMETHODCALLTYPE
229 Shadow_IRDPSessionEvents_GetTypeInfo(__RPC__in _IRDPSessionEvents* This,
230  /* [in] */ UINT iTInfo,
231  /* [in] */ LCID lcid,
232  /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo)
233 {
234  WLog_INFO(TAG, "Shadow_IRDPSessionEvents_GetTypeInfo");
235  return E_NOTIMPL;
236 }
237 
238 static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_GetIDsOfNames(
239  __RPC__in _IRDPSessionEvents* This,
240  /* [in] */ __RPC__in REFIID riid,
241  /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
242  /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
243  /* [in] */ LCID lcid,
244  /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId)
245 {
246  WLog_INFO(TAG, "Shadow_IRDPSessionEvents_GetIDsOfNames");
247  return E_NOTIMPL;
248 }
249 
250 static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_Invoke(_IRDPSessionEvents* This,
251  /* [annotation][in] */
252  _In_ DISPID dispIdMember,
253  /* [annotation][in] */
254  _In_ REFIID riid,
255  /* [annotation][in] */
256  _In_ LCID lcid,
257  /* [annotation][in] */
258  _In_ WORD wFlags,
259  /* [annotation][out][in] */
260  _In_ DISPPARAMS* pDispParams,
261  /* [annotation][out] */
262  _Out_opt_ VARIANT* pVarResult,
263  /* [annotation][out] */
264  _Out_opt_ EXCEPINFO* pExcepInfo,
265  /* [annotation][out] */
266  _Out_opt_ UINT* puArgErr)
267 {
268  HRESULT hr;
269  VARIANT vr;
270  UINT uArgErr;
271  WLog_INFO(TAG, "%s (%ld)", GetRDPSessionEventString(dispIdMember), dispIdMember);
272 
273  switch (dispIdMember)
274  {
275  case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_CONNECTED:
276  {
277  int level;
278  IDispatch* pDispatch;
279  IRDPSRAPIAttendee* pAttendee;
280  vr.vt = VT_DISPATCH;
281  vr.pdispVal = NULL;
282  hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &vr, &uArgErr);
283 
284  if (FAILED(hr))
285  {
286  WLog_ERR(TAG, "%s DispGetParam(0, VT_DISPATCH) failure: 0x%08lX",
287  GetRDPSessionEventString(dispIdMember), hr);
288  return hr;
289  }
290 
291  pDispatch = vr.pdispVal;
292  hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IRDPSRAPIAttendee,
293  (void**)&pAttendee);
294 
295  if (FAILED(hr))
296  {
297  WLog_INFO(TAG, "%s IDispatch::QueryInterface(IRDPSRAPIAttendee) failure: 0x%08lX",
298  GetRDPSessionEventString(dispIdMember), hr);
299  return hr;
300  }
301 
302  level = CTRL_LEVEL_VIEW;
303  // level = CTRL_LEVEL_INTERACTIVE;
304  hr = pAttendee->lpVtbl->put_ControlLevel(pAttendee, level);
305 
306  if (FAILED(hr))
307  {
308  WLog_INFO(TAG, "%s IRDPSRAPIAttendee::put_ControlLevel() failure: 0x%08lX",
309  GetRDPSessionEventString(dispIdMember), hr);
310  return hr;
311  }
312 
313  pAttendee->lpVtbl->Release(pAttendee);
314  }
315  break;
316 
317  case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_DISCONNECTED:
318  break;
319 
320  case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_UPDATE:
321  break;
322 
323  case DISPID_RDPSRAPI_EVENT_ON_ERROR:
324  break;
325 
326  case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTED:
327  break;
328 
329  case DISPID_RDPSRAPI_EVENT_ON_VIEWER_DISCONNECTED:
330  break;
331 
332  case DISPID_RDPSRAPI_EVENT_ON_VIEWER_AUTHENTICATED:
333  break;
334 
335  case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTFAILED:
336  break;
337 
338  case DISPID_RDPSRAPI_EVENT_ON_CTRLLEVEL_CHANGE_REQUEST:
339  {
340  int level;
341  IDispatch* pDispatch;
342  IRDPSRAPIAttendee* pAttendee;
343  vr.vt = VT_INT;
344  vr.pdispVal = NULL;
345  hr = DispGetParam(pDispParams, 1, VT_INT, &vr, &uArgErr);
346 
347  if (FAILED(hr))
348  {
349  WLog_INFO(TAG, "%s DispGetParam(1, VT_INT) failure: 0x%08lX",
350  GetRDPSessionEventString(dispIdMember), hr);
351  return hr;
352  }
353 
354  level = vr.intVal;
355  vr.vt = VT_DISPATCH;
356  vr.pdispVal = NULL;
357  hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &vr, &uArgErr);
358 
359  if (FAILED(hr))
360  {
361  WLog_ERR(TAG, "%s DispGetParam(0, VT_DISPATCH) failure: 0x%08lX",
362  GetRDPSessionEventString(dispIdMember), hr);
363  return hr;
364  }
365 
366  pDispatch = vr.pdispVal;
367  hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IRDPSRAPIAttendee,
368  (void**)&pAttendee);
369 
370  if (FAILED(hr))
371  {
372  WLog_INFO(TAG, "%s IDispatch::QueryInterface(IRDPSRAPIAttendee) failure: 0x%08lX",
373  GetRDPSessionEventString(dispIdMember), hr);
374  return hr;
375  }
376 
377  hr = pAttendee->lpVtbl->put_ControlLevel(pAttendee, level);
378 
379  if (FAILED(hr))
380  {
381  WLog_INFO(TAG, "%s IRDPSRAPIAttendee::put_ControlLevel() failure: 0x%08lX",
382  GetRDPSessionEventString(dispIdMember), hr);
383  return hr;
384  }
385 
386  pAttendee->lpVtbl->Release(pAttendee);
387  }
388  break;
389 
390  case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_PAUSED:
391  break;
392 
393  case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_RESUMED:
394  break;
395 
396  case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_JOIN:
397  break;
398 
399  case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_LEAVE:
400  break;
401 
402  case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_DATARECEIVED:
403  break;
404 
405  case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_SENDCOMPLETED:
406  break;
407 
408  case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_OPEN:
409  break;
410 
411  case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_CLOSE:
412  break;
413 
414  case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_UPDATE:
415  break;
416 
417  case DISPID_RDPSRAPI_EVENT_ON_WINDOW_OPEN:
418  break;
419 
420  case DISPID_RDPSRAPI_EVENT_ON_WINDOW_CLOSE:
421  break;
422 
423  case DISPID_RDPSRAPI_EVENT_ON_WINDOW_UPDATE:
424  break;
425 
426  case DISPID_RDPSRAPI_EVENT_ON_APPFILTER_UPDATE:
427  break;
428 
429  case DISPID_RDPSRAPI_EVENT_ON_SHARED_RECT_CHANGED:
430  break;
431 
432  case DISPID_RDPSRAPI_EVENT_ON_FOCUSRELEASED:
433  break;
434 
435  case DISPID_RDPSRAPI_EVENT_ON_SHARED_DESKTOP_SETTINGS_CHANGED:
436  break;
437 
438  case DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED:
439  break;
440  }
441 
442  return S_OK;
443 }
444 
445 static _IRDPSessionEventsVtbl Shadow_IRDPSessionEventsVtbl = {
446  /* IUnknown */
447  Shadow_IRDPSessionEvents_QueryInterface, Shadow_IRDPSessionEvents_AddRef,
448  Shadow_IRDPSessionEvents_Release,
449 
450  /* IDispatch */
451  Shadow_IRDPSessionEvents_GetTypeInfoCount, Shadow_IRDPSessionEvents_GetTypeInfo,
452  Shadow_IRDPSessionEvents_GetIDsOfNames, Shadow_IRDPSessionEvents_Invoke
453 };
454 
455 static _IRDPSessionEvents Shadow_IRDPSessionEvents = { &Shadow_IRDPSessionEventsVtbl };
456 
457 static LRESULT CALLBACK ShadowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
458 {
459  switch (uMsg)
460  {
461  case WM_CLOSE:
462  DestroyWindow(hwnd);
463  break;
464 
465  case WM_DESTROY:
466  PostQuitMessage(0);
467  break;
468 
469  default:
470  return DefWindowProc(hwnd, uMsg, wParam, lParam);
471  break;
472  }
473 
474  return 0;
475 }
476 
477 int win_shadow_wds_wnd_init(winShadowSubsystem* subsystem)
478 {
479  HMODULE hModule;
480  HINSTANCE hInstance;
481  WNDCLASSEX wndClassEx = { 0 };
482  hModule = GetModuleHandle(NULL);
483 
484  wndClassEx.cbSize = sizeof(WNDCLASSEX);
485  wndClassEx.style = 0;
486  wndClassEx.lpfnWndProc = ShadowWndProc;
487  wndClassEx.cbClsExtra = 0;
488  wndClassEx.cbWndExtra = 0;
489  wndClassEx.hInstance = hModule;
490  wndClassEx.hIcon = NULL;
491  wndClassEx.hCursor = NULL;
492  wndClassEx.hbrBackground = NULL;
493  wndClassEx.lpszMenuName = _T("ShadowWndMenu");
494  wndClassEx.lpszClassName = _T("ShadowWndClass");
495  wndClassEx.hIconSm = NULL;
496 
497  if (!RegisterClassEx(&wndClassEx))
498  {
499  WLog_ERR(TAG, "RegisterClassEx failure");
500  return -1;
501  }
502 
503  hInstance = wndClassEx.hInstance;
504  subsystem->hWnd = CreateWindowEx(0, wndClassEx.lpszClassName, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
505  hInstance, NULL);
506 
507  if (!subsystem->hWnd)
508  {
509  WLog_INFO(TAG, "CreateWindowEx failure");
510  return -1;
511  }
512 
513  return 1;
514 }
515 
516 int win_shadow_wds_init(winShadowSubsystem* subsystem)
517 {
518  int status = -1;
519 
520  long left = 0;
521  long top = 0;
522  long right = 0;
523  long bottom = 0;
524  BSTR bstrAuthString = NULL;
525  BSTR bstrGroupName = NULL;
526  BSTR bstrPassword = NULL;
527  BSTR bstrPropertyName = NULL;
528  VARIANT varPropertyValue;
529  rdpAssistanceFile* file = NULL;
530  IConnectionPoint* pCP = NULL;
531  IConnectionPointContainer* pCPC = NULL;
532 
533  win_shadow_wds_wnd_init(subsystem);
534  HRESULT hr = OleInitialize(NULL);
535 
536  if (FAILED(hr))
537  {
538  WLog_ERR(TAG, "OleInitialize() failure");
539  return -1;
540  }
541 
542  hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
543 
544  if (FAILED(hr))
545  {
546  WLog_ERR(TAG, "CoInitialize() failure");
547  return -1;
548  }
549 
550  hr = CoCreateInstance(&CLSID_RDPSession, NULL, CLSCTX_ALL, &IID_IRDPSRAPISharingSession,
551  (void**)&(subsystem->pSharingSession));
552 
553  if (FAILED(hr))
554  {
555  WLog_ERR(TAG, "CoCreateInstance(IRDPSRAPISharingSession) failure: 0x%08lX", hr);
556  return -1;
557  }
558 
559  IUnknown* pUnknown = (IUnknown*)subsystem->pSharingSession;
560  hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IConnectionPointContainer, (void**)&pCPC);
561 
562  if (FAILED(hr))
563  {
564  WLog_ERR(TAG, "QueryInterface(IID_IConnectionPointContainer) failure: 0x%08lX", hr);
565  return -1;
566  }
567 
568  pCPC->lpVtbl->FindConnectionPoint(pCPC, &DIID__IRDPSessionEvents, &pCP);
569 
570  if (FAILED(hr))
571  {
572  WLog_ERR(
573  TAG,
574  "IConnectionPointContainer::FindConnectionPoint(_IRDPSessionEvents) failure: 0x%08lX",
575  hr);
576  return -1;
577  }
578 
579  DWORD dwCookie = 0;
580  subsystem->pSessionEvents = &Shadow_IRDPSessionEvents;
581  subsystem->pSessionEvents->lpVtbl->AddRef(subsystem->pSessionEvents);
582  hr = pCP->lpVtbl->Advise(pCP, (IUnknown*)subsystem->pSessionEvents, &dwCookie);
583 
584  if (FAILED(hr))
585  {
586  WLog_ERR(TAG, "IConnectionPoint::Advise(Shadow_IRDPSessionEvents) failure: 0x%08lX", hr);
587  return -1;
588  }
589 
590  hr = subsystem->pSharingSession->lpVtbl->put_ColorDepth(subsystem->pSharingSession, 32);
591 
592  if (FAILED(hr))
593  {
594  WLog_ERR(TAG, "IRDPSRAPISharingSession::put_ColorDepth() failure: 0x%08lX", hr);
595  return -1;
596  }
597 
598  hr = subsystem->pSharingSession->lpVtbl->GetDesktopSharedRect(subsystem->pSharingSession, &left,
599  &top, &right, &bottom);
600 
601  if (FAILED(hr))
602  {
603  WLog_ERR(TAG, "IRDPSRAPISharingSession::GetDesktopSharedRect() failure: 0x%08lX", hr);
604  return -1;
605  }
606 
607  long width = right - left;
608  long height = bottom - top;
609  WLog_INFO(
610  TAG,
611  "GetDesktopSharedRect(): left: %ld top: %ld right: %ld bottom: %ld width: %ld height: %ld",
612  left, top, right, bottom, width, height);
613  hr = subsystem->pSharingSession->lpVtbl->get_VirtualChannelManager(
614  subsystem->pSharingSession, &(subsystem->pVirtualChannelMgr));
615 
616  if (FAILED(hr))
617  {
618  WLog_ERR(TAG, "IRDPSRAPISharingSession::get_VirtualChannelManager() failure: 0x%08lX", hr);
619  return -1;
620  }
621 
622  hr = subsystem->pSharingSession->lpVtbl->get_ApplicationFilter(
623  subsystem->pSharingSession, &(subsystem->pApplicationFilter));
624 
625  if (FAILED(hr))
626  {
627  WLog_ERR(TAG, "IRDPSRAPISharingSession::get_ApplicationFilter() failure: 0x%08lX", hr);
628  return -1;
629  }
630 
631  hr = subsystem->pSharingSession->lpVtbl->get_Attendees(subsystem->pSharingSession,
632  &(subsystem->pAttendeeMgr));
633 
634  if (FAILED(hr))
635  {
636  WLog_ERR(TAG, "IRDPSRAPISharingSession::get_Attendees() failure: 0x%08lX", hr);
637  return -1;
638  }
639 
640  hr = subsystem->pSharingSession->lpVtbl->get_Properties(subsystem->pSharingSession,
641  &(subsystem->pSessionProperties));
642 
643  if (FAILED(hr))
644  {
645  WLog_ERR(TAG, "IRDPSRAPISharingSession::get_Properties() failure: 0x%08lX", hr);
646  return -1;
647  }
648 
649  bstrPropertyName = SysAllocString(L"PortId");
650  varPropertyValue.vt = VT_I4;
651  varPropertyValue.intVal = 40000;
652  hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
653  bstrPropertyName, varPropertyValue);
654  SysFreeString(bstrPropertyName);
655 
656  if (FAILED(hr))
657  {
658  WLog_ERR(TAG, "IRDPSRAPISessionProperties::put_Property(PortId) failure: 0x%08lX", hr);
659  return -1;
660  }
661 
662  bstrPropertyName = SysAllocString(L"DrvConAttach");
663  varPropertyValue.vt = VT_BOOL;
664  varPropertyValue.boolVal = VARIANT_TRUE;
665  hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
666  bstrPropertyName, varPropertyValue);
667  SysFreeString(bstrPropertyName);
668 
669  if (FAILED(hr))
670  {
671  WLog_ERR(TAG, "IRDPSRAPISessionProperties::put_Property(DrvConAttach) failure: 0x%08lX",
672  hr);
673  return -1;
674  }
675 
676  bstrPropertyName = SysAllocString(L"PortProtocol");
677  varPropertyValue.vt = VT_I4;
678  // varPropertyValue.intVal = 0; // AF_UNSPEC
679  varPropertyValue.intVal = 2; // AF_INET
680  // varPropertyValue.intVal = 23; // AF_INET6
681  hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
682  bstrPropertyName, varPropertyValue);
683  SysFreeString(bstrPropertyName);
684 
685  if (FAILED(hr))
686  {
687  WLog_ERR(TAG, "IRDPSRAPISessionProperties::put_Property(PortProtocol) failure: 0x%08lX",
688  hr);
689  return -1;
690  }
691 
692  hr = subsystem->pSharingSession->lpVtbl->Open(subsystem->pSharingSession);
693 
694  if (FAILED(hr))
695  {
696  WLog_ERR(TAG, "IRDPSRAPISharingSession::Open() failure: 0x%08lX", hr);
697  return -1;
698  }
699 
700  hr = subsystem->pSharingSession->lpVtbl->get_Invitations(subsystem->pSharingSession,
701  &(subsystem->pInvitationMgr));
702 
703  if (FAILED(hr))
704  {
705  WLog_ERR(TAG, "IRDPSRAPISharingSession::get_Invitations() failure");
706  return -1;
707  }
708 
709  bstrAuthString = SysAllocString(L"Shadow");
710  bstrGroupName = SysAllocString(L"ShadowGroup");
711  bstrPassword = SysAllocString(L"Shadow123!");
712  hr = subsystem->pInvitationMgr->lpVtbl->CreateInvitation(
713  subsystem->pInvitationMgr, bstrAuthString, bstrGroupName, bstrPassword, 5,
714  &(subsystem->pInvitation));
715  SysFreeString(bstrAuthString);
716  SysFreeString(bstrGroupName);
717  SysFreeString(bstrPassword);
718 
719  if (FAILED(hr))
720  {
721  WLog_ERR(TAG, "IRDPSRAPIInvitationManager::CreateInvitation() failure: 0x%08lX", hr);
722  return -1;
723  }
724 
725  file = subsystem->pAssistanceFile = freerdp_assistance_file_new();
726 
727  if (!file)
728  {
729  WLog_ERR(TAG, "freerdp_assistance_file_new() failed");
730  return -1;
731  }
732 
733  {
734  int status2 = -1;
735  char* ConnectionString2;
736  BSTR bstrConnectionString;
737  hr = subsystem->pInvitation->lpVtbl->get_ConnectionString(subsystem->pInvitation,
738  &bstrConnectionString);
739 
740  if (FAILED(hr))
741  {
742  WLog_ERR(TAG, "IRDPSRAPIInvitation::get_ConnectionString() failure: 0x%08lX", hr);
743  return -1;
744  }
745 
746  ConnectionString2 = ConvertWCharToUtf8Alloc(bstrConnectionString, NULL);
747  SysFreeString(bstrConnectionString);
748  status2 = freerdp_assistance_set_connection_string2(file, ConnectionString2, "Shadow123!");
749  free(ConnectionString2);
750 
751  if ((!ConnectionString2) || (status2 < 1))
752  {
753  WLog_ERR(TAG, "failed to convert connection string");
754  return -1;
755  }
756  }
757 
758  freerdp_assistance_print_file(file, WLog_Get(TAG), WLOG_INFO);
759  status = win_shadow_rdp_init(subsystem);
760 
761  if (status < 0)
762  {
763  WLog_ERR(TAG, "win_shadow_rdp_init() failure: %d", status);
764  return status;
765  }
766 
767  rdpSetting* settings = subsystem->shw->settings;
768  if (!freerdp_assistance_populate_settings_from_assistance_file(file, settings))
769  return -1;
770  if (!freerdp_settings_set_string(settings, FreeRDP_Domain, "RDP"))
771  return -1;
772  if (!freerdp_settings_set_string(settings, FreeRDP_Username, "Shadow"))
773  return -1;
774  if (!freerdp_settings_set_bool(settings, FreeRDP_AutoLogonEnabled, TRUE))
775  return -1;
776  if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, width))
777  return -1;
778  if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, height))
779  return -1;
780  status = win_shadow_rdp_start(subsystem);
781 
782  if (status < 0)
783  {
784  WLog_ERR(TAG, "win_shadow_rdp_start() failure: %d", status);
785  return status;
786  }
787 
788  return 1;
789 }
790 
791 int win_shadow_wds_uninit(winShadowSubsystem* subsystem)
792 {
793  if (subsystem->pSharingSession)
794  {
795  subsystem->pSharingSession->lpVtbl->Close(subsystem->pSharingSession);
796  subsystem->pSharingSession->lpVtbl->Release(subsystem->pSharingSession);
797  subsystem->pSharingSession = NULL;
798  }
799 
800  if (subsystem->pVirtualChannelMgr)
801  {
802  subsystem->pVirtualChannelMgr->lpVtbl->Release(subsystem->pVirtualChannelMgr);
803  subsystem->pVirtualChannelMgr = NULL;
804  }
805 
806  if (subsystem->pApplicationFilter)
807  {
808  subsystem->pApplicationFilter->lpVtbl->Release(subsystem->pApplicationFilter);
809  subsystem->pApplicationFilter = NULL;
810  }
811 
812  if (subsystem->pAttendeeMgr)
813  {
814  subsystem->pAttendeeMgr->lpVtbl->Release(subsystem->pAttendeeMgr);
815  subsystem->pAttendeeMgr = NULL;
816  }
817 
818  if (subsystem->pSessionProperties)
819  {
820  subsystem->pSessionProperties->lpVtbl->Release(subsystem->pSessionProperties);
821  subsystem->pSessionProperties = NULL;
822  }
823 
824  if (subsystem->pInvitationMgr)
825  {
826  subsystem->pInvitationMgr->lpVtbl->Release(subsystem->pInvitationMgr);
827  subsystem->pInvitationMgr = NULL;
828  }
829 
830  if (subsystem->pInvitation)
831  {
832  subsystem->pInvitation->lpVtbl->Release(subsystem->pInvitation);
833  subsystem->pInvitation = NULL;
834  }
835 
836  if (subsystem->pAssistanceFile)
837  {
838  freerdp_assistance_file_free(subsystem->pAssistanceFile);
839  subsystem->pAssistanceFile = NULL;
840  }
841 
842  if (subsystem->hWnd)
843  {
844  DestroyWindow(subsystem->hWnd);
845  subsystem->hWnd = NULL;
846  }
847 
848  if (subsystem->shw)
849  {
850  win_shadow_rdp_uninit(subsystem);
851  subsystem->shw = NULL;
852  }
853 
854  return 1;
855 }
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.