FreeRDP
Loading...
Searching...
No Matches
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
52DEFINE_GUID(CLSID_RDPSession, 0x9B78F0E6, 0x3E05, 0x4A5B, 0xB2, 0xE8, 0xE7, 0x43, 0xA8, 0x95, 0x6B,
53 0x65);
54DEFINE_GUID(DIID__IRDPSessionEvents, 0x98a97042, 0x6698, 0x40e9, 0x8e, 0xfd, 0xb3, 0x20, 0x09, 0x90,
55 0x00, 0x4b);
56DEFINE_GUID(IID_IRDPSRAPISharingSession, 0xeeb20886, 0xe470, 0x4cf6, 0x84, 0x2b, 0x27, 0x39, 0xc0,
57 0xec, 0x5c, 0xfb);
58DEFINE_GUID(IID_IRDPSRAPIAttendee, 0xec0671b3, 0x1b78, 0x4b80, 0xa4, 0x64, 0x91, 0x32, 0x24, 0x75,
59 0x43, 0xe3);
60DEFINE_GUID(IID_IRDPSRAPIAttendeeManager, 0xba3a37e8, 0x33da, 0x4749, 0x8d, 0xa0, 0x07, 0xfa, 0x34,
61 0xda, 0x79, 0x44);
62DEFINE_GUID(IID_IRDPSRAPISessionProperties, 0x339b24f2, 0x9bc0, 0x4f16, 0x9a, 0xac, 0xf1, 0x65,
63 0x43, 0x3d, 0x13, 0xd4);
64DEFINE_GUID(CLSID_RDPSRAPIApplicationFilter, 0xe35ace89, 0xc7e8, 0x427e, 0xa4, 0xf9, 0xb9, 0xda,
65 0x07, 0x28, 0x26, 0xbd);
66DEFINE_GUID(CLSID_RDPSRAPIInvitationManager, 0x53d9c9db, 0x75ab, 0x4271, 0x94, 0x8a, 0x4c, 0x4e,
67 0xb3, 0x6a, 0x8f, 0x2b);
68
69static ULONG Shadow_IRDPSessionEvents_RefCount = 0;
70
71const 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
183static HRESULT STDMETHODCALLTYPE
184Shadow_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 = nullptr;
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
204static ULONG STDMETHODCALLTYPE Shadow_IRDPSessionEvents_AddRef(__RPC__in _IRDPSessionEvents* This)
205{
206 Shadow_IRDPSessionEvents_RefCount++;
207 return Shadow_IRDPSessionEvents_RefCount;
208}
209
210static 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
219static HRESULT STDMETHODCALLTYPE
220Shadow_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
228static HRESULT STDMETHODCALLTYPE
229Shadow_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
238static 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
250static 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 WLog_INFO(TAG, "%s (%ld)", GetRDPSessionEventString(dispIdMember), dispIdMember);
269
270 switch (dispIdMember)
271 {
272 case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_CONNECTED:
273 {
274 UINT uArgErr = 0;
275 int level = 0;
276 IRDPSRAPIAttendee* pAttendee = nullptr;
277 VARIANT vr = WINPR_C_ARRAY_INIT;
278
279#if defined(NONAMELESSUNION)
280 vr.n1.n2.vt = VT_DISPATCH;
281#else
282 vr.vt = VT_DISPATCH;
283#endif
284 HRESULT hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &vr, &uArgErr);
285
286 if (FAILED(hr))
287 {
288 WLog_ERR(TAG, "%s DispGetParam(0, VT_DISPATCH) failure: 0x%08lX",
289 GetRDPSessionEventString(dispIdMember), hr);
290 return hr;
291 }
292
293 IDispatch* pDispatch =
294#if defined(NONAMELESSUNION)
295 pDispatch = vr.n1.n2.n3.pdispVal;
296#else
297 pDispatch = vr.pdispVal;
298#endif
299 hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IRDPSRAPIAttendee,
300 (void**)&pAttendee);
301
302 if (FAILED(hr))
303 {
304 WLog_INFO(TAG, "%s IDispatch::QueryInterface(IRDPSRAPIAttendee) failure: 0x%08lX",
305 GetRDPSessionEventString(dispIdMember), hr);
306 return hr;
307 }
308
309 level = CTRL_LEVEL_VIEW;
310 // level = CTRL_LEVEL_INTERACTIVE;
311 hr = pAttendee->lpVtbl->put_ControlLevel(pAttendee, level);
312
313 if (FAILED(hr))
314 {
315 WLog_INFO(TAG, "%s IRDPSRAPIAttendee::put_ControlLevel() failure: 0x%08lX",
316 GetRDPSessionEventString(dispIdMember), hr);
317 return hr;
318 }
319
320 pAttendee->lpVtbl->Release(pAttendee);
321 }
322 break;
323
324 case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_DISCONNECTED:
325 break;
326
327 case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_UPDATE:
328 break;
329
330 case DISPID_RDPSRAPI_EVENT_ON_ERROR:
331 break;
332
333 case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTED:
334 break;
335
336 case DISPID_RDPSRAPI_EVENT_ON_VIEWER_DISCONNECTED:
337 break;
338
339 case DISPID_RDPSRAPI_EVENT_ON_VIEWER_AUTHENTICATED:
340 break;
341
342 case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTFAILED:
343 break;
344
345 case DISPID_RDPSRAPI_EVENT_ON_CTRLLEVEL_CHANGE_REQUEST:
346 {
347 UINT uArgErr = 0;
348 int level = 0;
349 IRDPSRAPIAttendee* pAttendee = nullptr;
350 VARIANT vr = WINPR_C_ARRAY_INIT;
351#if defined(NONAMELESSUNION)
352 vr.n1.n2.vt = VT_INT;
353#else
354 vr.vt = VT_INT;
355#endif
356
357 HRESULT hr = DispGetParam(pDispParams, 1, VT_INT, &vr, &uArgErr);
358
359 if (FAILED(hr))
360 {
361 WLog_INFO(TAG, "%s DispGetParam(1, VT_INT) failure: 0x%08lX",
362 GetRDPSessionEventString(dispIdMember), hr);
363 return hr;
364 }
365
366#if defined(NONAMELESSUNION)
367 level = vr.n1.n2.n3.intVal;
368#else
369 level = vr.intVal;
370#endif
371
372 VARIANT vr2 = WINPR_C_ARRAY_INIT;
373#if defined(NONAMELESSUNION)
374 vr2.n1.n2.vt = VT_DISPATCH;
375#else
376 vr2.vt = VT_DISPATCH;
377#endif
378 hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &vr2, &uArgErr);
379
380 if (FAILED(hr))
381 {
382 WLog_ERR(TAG, "%s DispGetParam(0, VT_DISPATCH) failure: 0x%08lX",
383 GetRDPSessionEventString(dispIdMember), hr);
384 return hr;
385 }
386
387 IDispatch* pDispatch =
388#if defined(NONAMELESSUNION)
389 vr2.n1.n2.n3.pdispVal;
390#else
391 vr2.pdispVal;
392#endif
393 hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IRDPSRAPIAttendee,
394 (void**)&pAttendee);
395
396 if (FAILED(hr))
397 {
398 WLog_INFO(TAG, "%s IDispatch::QueryInterface(IRDPSRAPIAttendee) failure: 0x%08lX",
399 GetRDPSessionEventString(dispIdMember), hr);
400 return hr;
401 }
402
403 hr = pAttendee->lpVtbl->put_ControlLevel(pAttendee, level);
404
405 if (FAILED(hr))
406 {
407 WLog_INFO(TAG, "%s IRDPSRAPIAttendee::put_ControlLevel() failure: 0x%08lX",
408 GetRDPSessionEventString(dispIdMember), hr);
409 return hr;
410 }
411
412 pAttendee->lpVtbl->Release(pAttendee);
413 }
414 break;
415
416 case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_PAUSED:
417 break;
418
419 case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_RESUMED:
420 break;
421
422 case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_JOIN:
423 break;
424
425 case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_LEAVE:
426 break;
427
428 case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_DATARECEIVED:
429 break;
430
431 case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_SENDCOMPLETED:
432 break;
433
434 case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_OPEN:
435 break;
436
437 case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_CLOSE:
438 break;
439
440 case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_UPDATE:
441 break;
442
443 case DISPID_RDPSRAPI_EVENT_ON_WINDOW_OPEN:
444 break;
445
446 case DISPID_RDPSRAPI_EVENT_ON_WINDOW_CLOSE:
447 break;
448
449 case DISPID_RDPSRAPI_EVENT_ON_WINDOW_UPDATE:
450 break;
451
452 case DISPID_RDPSRAPI_EVENT_ON_APPFILTER_UPDATE:
453 break;
454
455 case DISPID_RDPSRAPI_EVENT_ON_SHARED_RECT_CHANGED:
456 break;
457
458 case DISPID_RDPSRAPI_EVENT_ON_FOCUSRELEASED:
459 break;
460
461 case DISPID_RDPSRAPI_EVENT_ON_SHARED_DESKTOP_SETTINGS_CHANGED:
462 break;
463
464 case DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED:
465 break;
466 }
467
468 return S_OK;
469}
470
471static _IRDPSessionEventsVtbl Shadow_IRDPSessionEventsVtbl = {
472 /* IUnknown */
473 Shadow_IRDPSessionEvents_QueryInterface, Shadow_IRDPSessionEvents_AddRef,
474 Shadow_IRDPSessionEvents_Release,
475
476 /* IDispatch */
477 Shadow_IRDPSessionEvents_GetTypeInfoCount, Shadow_IRDPSessionEvents_GetTypeInfo,
478 Shadow_IRDPSessionEvents_GetIDsOfNames, Shadow_IRDPSessionEvents_Invoke
479};
480
481static _IRDPSessionEvents Shadow_IRDPSessionEvents = { &Shadow_IRDPSessionEventsVtbl };
482
483static LRESULT CALLBACK ShadowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
484{
485 switch (uMsg)
486 {
487 case WM_CLOSE:
488 DestroyWindow(hwnd);
489 break;
490
491 case WM_DESTROY:
492 PostQuitMessage(0);
493 break;
494
495 default:
496 return DefWindowProc(hwnd, uMsg, wParam, lParam);
497 break;
498 }
499
500 return 0;
501}
502
503int win_shadow_wds_wnd_init(winShadowSubsystem* subsystem)
504{
505 HMODULE hModule;
506 HINSTANCE hInstance;
507 WNDCLASSEX wndClassEx = WINPR_C_ARRAY_INIT;
508 hModule = GetModuleHandle(nullptr);
509
510 wndClassEx.cbSize = sizeof(WNDCLASSEX);
511 wndClassEx.style = 0;
512 wndClassEx.lpfnWndProc = ShadowWndProc;
513 wndClassEx.cbClsExtra = 0;
514 wndClassEx.cbWndExtra = 0;
515 wndClassEx.hInstance = hModule;
516 wndClassEx.hIcon = nullptr;
517 wndClassEx.hCursor = nullptr;
518 wndClassEx.hbrBackground = nullptr;
519 wndClassEx.lpszMenuName = _T("ShadowWndMenu");
520 wndClassEx.lpszClassName = _T("ShadowWndClass");
521 wndClassEx.hIconSm = nullptr;
522
523 if (!RegisterClassEx(&wndClassEx))
524 {
525 WLog_ERR(TAG, "RegisterClassEx failure");
526 return -1;
527 }
528
529 hInstance = wndClassEx.hInstance;
530 subsystem->hWnd = CreateWindowEx(0, wndClassEx.lpszClassName, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
531 hInstance, nullptr);
532
533 if (!subsystem->hWnd)
534 {
535 WLog_INFO(TAG, "CreateWindowEx failure");
536 return -1;
537 }
538
539 return 1;
540}
541
542int win_shadow_wds_init(winShadowSubsystem* subsystem)
543{
544 int status = -1;
545
546 long left = 0;
547 long top = 0;
548 long right = 0;
549 long bottom = 0;
550 BSTR bstrAuthString = nullptr;
551 BSTR bstrGroupName = nullptr;
552 BSTR bstrPassword = nullptr;
553 BSTR bstrPropertyName = nullptr;
554 VARIANT varPropertyValue;
555 rdpAssistanceFile* file = nullptr;
556 IConnectionPoint* pCP = nullptr;
557 IConnectionPointContainer* pCPC = nullptr;
558
559 win_shadow_wds_wnd_init(subsystem);
560 HRESULT hr = OleInitialize(nullptr);
561
562 if (FAILED(hr))
563 {
564 WLog_ERR(TAG, "OleInitialize() failure");
565 return -1;
566 }
567
568 hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
569
570 if (FAILED(hr))
571 {
572 WLog_ERR(TAG, "CoInitialize() failure");
573 return -1;
574 }
575
576 hr = CoCreateInstance(&CLSID_RDPSession, nullptr, CLSCTX_ALL, &IID_IRDPSRAPISharingSession,
577 (void**)&(subsystem->pSharingSession));
578
579 if (FAILED(hr))
580 {
581 WLog_ERR(TAG, "CoCreateInstance(IRDPSRAPISharingSession) failure: 0x%08lX", hr);
582 return -1;
583 }
584
585 IUnknown* pUnknown = (IUnknown*)subsystem->pSharingSession;
586 hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IConnectionPointContainer, (void**)&pCPC);
587
588 if (FAILED(hr))
589 {
590 WLog_ERR(TAG, "QueryInterface(IID_IConnectionPointContainer) failure: 0x%08lX", hr);
591 return -1;
592 }
593
594 pCPC->lpVtbl->FindConnectionPoint(pCPC, &DIID__IRDPSessionEvents, &pCP);
595
596 if (FAILED(hr))
597 {
598 WLog_ERR(
599 TAG,
600 "IConnectionPointContainer::FindConnectionPoint(_IRDPSessionEvents) failure: 0x%08lX",
601 hr);
602 return -1;
603 }
604
605 DWORD dwCookie = 0;
606 subsystem->pSessionEvents = &Shadow_IRDPSessionEvents;
607 subsystem->pSessionEvents->lpVtbl->AddRef(subsystem->pSessionEvents);
608 hr = pCP->lpVtbl->Advise(pCP, (IUnknown*)subsystem->pSessionEvents, &dwCookie);
609
610 if (FAILED(hr))
611 {
612 WLog_ERR(TAG, "IConnectionPoint::Advise(Shadow_IRDPSessionEvents) failure: 0x%08lX", hr);
613 return -1;
614 }
615
616 hr = subsystem->pSharingSession->lpVtbl->put_ColorDepth(subsystem->pSharingSession, 32);
617
618 if (FAILED(hr))
619 {
620 WLog_ERR(TAG, "IRDPSRAPISharingSession::put_ColorDepth() failure: 0x%08lX", hr);
621 return -1;
622 }
623
624 hr = subsystem->pSharingSession->lpVtbl->GetDesktopSharedRect(subsystem->pSharingSession, &left,
625 &top, &right, &bottom);
626
627 if (FAILED(hr))
628 {
629 WLog_ERR(TAG, "IRDPSRAPISharingSession::GetDesktopSharedRect() failure: 0x%08lX", hr);
630 return -1;
631 }
632
633 long width = right - left;
634 long height = bottom - top;
635 WLog_INFO(
636 TAG,
637 "GetDesktopSharedRect(): left: %ld top: %ld right: %ld bottom: %ld width: %ld height: %ld",
638 left, top, right, bottom, width, height);
639 hr = subsystem->pSharingSession->lpVtbl->get_VirtualChannelManager(
640 subsystem->pSharingSession, &(subsystem->pVirtualChannelMgr));
641
642 if (FAILED(hr))
643 {
644 WLog_ERR(TAG, "IRDPSRAPISharingSession::get_VirtualChannelManager() failure: 0x%08lX", hr);
645 return -1;
646 }
647
648 hr = subsystem->pSharingSession->lpVtbl->get_ApplicationFilter(
649 subsystem->pSharingSession, &(subsystem->pApplicationFilter));
650
651 if (FAILED(hr))
652 {
653 WLog_ERR(TAG, "IRDPSRAPISharingSession::get_ApplicationFilter() failure: 0x%08lX", hr);
654 return -1;
655 }
656
657 hr = subsystem->pSharingSession->lpVtbl->get_Attendees(subsystem->pSharingSession,
658 &(subsystem->pAttendeeMgr));
659
660 if (FAILED(hr))
661 {
662 WLog_ERR(TAG, "IRDPSRAPISharingSession::get_Attendees() failure: 0x%08lX", hr);
663 return -1;
664 }
665
666 hr = subsystem->pSharingSession->lpVtbl->get_Properties(subsystem->pSharingSession,
667 &(subsystem->pSessionProperties));
668
669 if (FAILED(hr))
670 {
671 WLog_ERR(TAG, "IRDPSRAPISharingSession::get_Properties() failure: 0x%08lX", hr);
672 return -1;
673 }
674
675 bstrPropertyName = SysAllocString(L"PortId");
676#if defined(NONAMELESSUNION)
677 varPropertyValue.n1.n2.vt = VT_I4;
678 varPropertyValue.n1.n2.n3.intVal = 40000;
679#else
680 varPropertyValue.vt = VT_I4;
681 varPropertyValue.intVal = 40000;
682#endif
683 hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
684 bstrPropertyName, varPropertyValue);
685 SysFreeString(bstrPropertyName);
686
687 if (FAILED(hr))
688 {
689 WLog_ERR(TAG, "IRDPSRAPISessionProperties::put_Property(PortId) failure: 0x%08lX", hr);
690 return -1;
691 }
692
693 bstrPropertyName = SysAllocString(L"DrvConAttach");
694#if defined(NONAMELESSUNION)
695 varPropertyValue.n1.n2.vt = VT_BOOL;
696 varPropertyValue.n1.n2.n3.boolVal = VARIANT_TRUE;
697#else
698 varPropertyValue.vt = VT_BOOL;
699 varPropertyValue.boolVal = VARIANT_TRUE;
700#endif
701 hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
702 bstrPropertyName, varPropertyValue);
703 SysFreeString(bstrPropertyName);
704
705 if (FAILED(hr))
706 {
707 WLog_ERR(TAG, "IRDPSRAPISessionProperties::put_Property(DrvConAttach) failure: 0x%08lX",
708 hr);
709 return -1;
710 }
711
712 bstrPropertyName = SysAllocString(L"PortProtocol");
713#if defined(NONAMELESSUNION)
714 varPropertyValue.n1.n2.vt = VT_I4;
715 varPropertyValue.n1.n2.n3.intVal = 2; // AF_INET
716#else
717 varPropertyValue.vt = VT_I4;
718 // varPropertyValue.intVal = 0; // AF_UNSPEC
719 varPropertyValue.intVal = 2; // AF_INET
720 // varPropertyValue.intVal = 23; // AF_INET6
721#endif
722 hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties,
723 bstrPropertyName, varPropertyValue);
724 SysFreeString(bstrPropertyName);
725
726 if (FAILED(hr))
727 {
728 WLog_ERR(TAG, "IRDPSRAPISessionProperties::put_Property(PortProtocol) failure: 0x%08lX",
729 hr);
730 return -1;
731 }
732
733 hr = subsystem->pSharingSession->lpVtbl->Open(subsystem->pSharingSession);
734
735 if (FAILED(hr))
736 {
737 WLog_ERR(TAG, "IRDPSRAPISharingSession::Open() failure: 0x%08lX", hr);
738 return -1;
739 }
740
741 hr = subsystem->pSharingSession->lpVtbl->get_Invitations(subsystem->pSharingSession,
742 &(subsystem->pInvitationMgr));
743
744 if (FAILED(hr))
745 {
746 WLog_ERR(TAG, "IRDPSRAPISharingSession::get_Invitations() failure");
747 return -1;
748 }
749
750 bstrAuthString = SysAllocString(L"Shadow");
751 bstrGroupName = SysAllocString(L"ShadowGroup");
752 bstrPassword = SysAllocString(L"Shadow123!");
753 hr = subsystem->pInvitationMgr->lpVtbl->CreateInvitation(
754 subsystem->pInvitationMgr, bstrAuthString, bstrGroupName, bstrPassword, 5,
755 &(subsystem->pInvitation));
756 SysFreeString(bstrAuthString);
757 SysFreeString(bstrGroupName);
758 SysFreeString(bstrPassword);
759
760 if (FAILED(hr))
761 {
762 WLog_ERR(TAG, "IRDPSRAPIInvitationManager::CreateInvitation() failure: 0x%08lX", hr);
763 return -1;
764 }
765
766 file = subsystem->pAssistanceFile = freerdp_assistance_file_new();
767
768 if (!file)
769 {
770 WLog_ERR(TAG, "freerdp_assistance_file_new() failed");
771 return -1;
772 }
773
774 {
775 int status2 = -1;
776 BSTR bstrConnectionString = nullptr;
777 hr = subsystem->pInvitation->lpVtbl->get_ConnectionString(subsystem->pInvitation,
778 &bstrConnectionString);
779
780 if (FAILED(hr))
781 {
782 WLog_ERR(TAG, "IRDPSRAPIInvitation::get_ConnectionString() failure: 0x%08lX", hr);
783 return -1;
784 }
785
786 char* ConnectionString2 = ConvertWCharToUtf8Alloc(bstrConnectionString, nullptr);
787 SysFreeString(bstrConnectionString);
788 status2 = freerdp_assistance_set_connection_string2(file, ConnectionString2, "Shadow123!");
789 free(ConnectionString2);
790
791 if ((!ConnectionString2) || (status2 < 1))
792 {
793 WLog_ERR(TAG, "failed to convert connection string");
794 return -1;
795 }
796 }
797
798 freerdp_assistance_print_file(file, WLog_Get(TAG), WLOG_INFO);
799 status = win_shadow_rdp_init(subsystem);
800
801 if (status < 0)
802 {
803 WLog_ERR(TAG, "win_shadow_rdp_init() failure: %d", status);
804 return status;
805 }
806
807 rdpSettings* settings = subsystem->shw->settings;
808 if (!freerdp_assistance_populate_settings_from_assistance_file(file, settings))
809 return -1;
810 if (!freerdp_settings_set_string(settings, FreeRDP_Domain, "RDP"))
811 return -1;
812 if (!freerdp_settings_set_string(settings, FreeRDP_Username, "Shadow"))
813 return -1;
814 if (!freerdp_settings_set_bool(settings, FreeRDP_AutoLogonEnabled, TRUE))
815 return -1;
816 if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, width))
817 return -1;
818 if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, height))
819 return -1;
820 status = win_shadow_rdp_start(subsystem);
821
822 if (status < 0)
823 {
824 WLog_ERR(TAG, "win_shadow_rdp_start() failure: %d", status);
825 return status;
826 }
827
828 return 1;
829}
830
831int win_shadow_wds_uninit(winShadowSubsystem* subsystem)
832{
833 if (subsystem->pSharingSession)
834 {
835 subsystem->pSharingSession->lpVtbl->Close(subsystem->pSharingSession);
836 subsystem->pSharingSession->lpVtbl->Release(subsystem->pSharingSession);
837 subsystem->pSharingSession = nullptr;
838 }
839
840 if (subsystem->pVirtualChannelMgr)
841 {
842 subsystem->pVirtualChannelMgr->lpVtbl->Release(subsystem->pVirtualChannelMgr);
843 subsystem->pVirtualChannelMgr = nullptr;
844 }
845
846 if (subsystem->pApplicationFilter)
847 {
848 subsystem->pApplicationFilter->lpVtbl->Release(subsystem->pApplicationFilter);
849 subsystem->pApplicationFilter = nullptr;
850 }
851
852 if (subsystem->pAttendeeMgr)
853 {
854 subsystem->pAttendeeMgr->lpVtbl->Release(subsystem->pAttendeeMgr);
855 subsystem->pAttendeeMgr = nullptr;
856 }
857
858 if (subsystem->pSessionProperties)
859 {
860 subsystem->pSessionProperties->lpVtbl->Release(subsystem->pSessionProperties);
861 subsystem->pSessionProperties = nullptr;
862 }
863
864 if (subsystem->pInvitationMgr)
865 {
866 subsystem->pInvitationMgr->lpVtbl->Release(subsystem->pInvitationMgr);
867 subsystem->pInvitationMgr = nullptr;
868 }
869
870 if (subsystem->pInvitation)
871 {
872 subsystem->pInvitation->lpVtbl->Release(subsystem->pInvitation);
873 subsystem->pInvitation = nullptr;
874 }
875
876 if (subsystem->pAssistanceFile)
877 {
878 freerdp_assistance_file_free(subsystem->pAssistanceFile);
879 subsystem->pAssistanceFile = nullptr;
880 }
881
882 if (subsystem->hWnd)
883 {
884 DestroyWindow(subsystem->hWnd);
885 subsystem->hWnd = nullptr;
886 }
887
888 if (subsystem->shw)
889 {
890 win_shadow_rdp_uninit(subsystem);
891 subsystem->shw = nullptr;
892 }
893
894 return 1;
895}
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val)
Sets a string settings value. The param is copied.