19 #include <freerdp/config.h>
21 #include <winpr/crt.h>
22 #include <winpr/assert.h>
23 #include <winpr/print.h>
24 #include <winpr/assert.h>
26 #include <freerdp/log.h>
30 #define TAG SERVER_TAG("shadow.win")
32 static void shw_OnChannelConnectedEventHandler(
void* context,
const ChannelConnectedEventArgs* e)
34 shwContext* shw = (shwContext*)context;
36 WLog_INFO(TAG,
"OnChannelConnected: %s", e->name);
39 static void shw_OnChannelDisconnectedEventHandler(
void* context,
40 const ChannelDisconnectedEventArgs* e)
42 shwContext* shw = (shwContext*)context;
44 WLog_INFO(TAG,
"OnChannelDisconnected: %s", e->name);
47 static BOOL shw_begin_paint(rdpContext* context)
52 WINPR_ASSERT(context);
55 shw = (shwContext*)context;
56 gdi->primary->hdc->hwnd->invalid->null = TRUE;
57 gdi->primary->hdc->hwnd->ninvalid = 0;
61 static BOOL shw_end_paint(rdpContext* context)
66 rdpGdi* gdi = context->gdi;
67 shwContext* shw = (shwContext*)context;
68 winShadowSubsystem* subsystem = shw->subsystem;
69 rdpShadowSurface* surface = subsystem->base.server->surface;
70 ninvalid = gdi->primary->hdc->hwnd->ninvalid;
71 cinvalid = gdi->primary->hdc->hwnd->cinvalid;
73 for (
int index = 0; index < ninvalid; index++)
75 invalidRect.left = cinvalid[index].x;
76 invalidRect.top = cinvalid[index].y;
77 invalidRect.right = cinvalid[index].x + cinvalid[index].w;
78 invalidRect.bottom = cinvalid[index].y + cinvalid[index].h;
79 region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
82 (void)SetEvent(subsystem->RdpUpdateEnterEvent);
83 (void)WaitForSingleObject(subsystem->RdpUpdateLeaveEvent, INFINITE);
84 (void)ResetEvent(subsystem->RdpUpdateLeaveEvent);
88 BOOL shw_desktop_resize(rdpContext* context)
90 WLog_WARN(TAG,
"Desktop resizing not implemented!");
94 static BOOL shw_surface_frame_marker(rdpContext* context,
97 shwContext* shw = (shwContext*)context;
101 static BOOL shw_authenticate(freerdp* instance,
char** username,
char** password,
char** domain)
103 WLog_WARN(TAG,
"Authentication not implemented, access granted to everyone!");
107 static int shw_verify_x509_certificate(freerdp* instance,
const BYTE* data,
size_t length,
108 const char* hostname, UINT16 port, DWORD flags)
110 WLog_WARN(TAG,
"Certificate checks not implemented, access granted to everyone!");
114 static void shw_OnConnectionResultEventHandler(
void* context,
const ConnectionResultEventArgs* e)
116 shwContext* shw = (shwContext*)context;
118 WLog_INFO(TAG,
"OnConnectionResult: %d", e->result);
121 static BOOL shw_pre_connect(freerdp* instance)
124 rdpContext* context = instance->context;
125 shw = (shwContext*)context;
126 PubSub_SubscribeConnectionResult(context->pubSub, shw_OnConnectionResultEventHandler);
127 PubSub_SubscribeChannelConnected(context->pubSub, shw_OnChannelConnectedEventHandler);
128 PubSub_SubscribeChannelDisconnected(context->pubSub, shw_OnChannelDisconnectedEventHandler);
133 static BOOL shw_post_connect(freerdp* instance)
138 rdpSettings* settings;
140 WINPR_ASSERT(instance);
142 shw = (shwContext*)instance->context;
145 update = instance->context->update;
146 WINPR_ASSERT(update);
148 settings = instance->context->settings;
149 WINPR_ASSERT(settings);
151 if (!gdi_init(instance, PIXEL_FORMAT_BGRX32))
154 gdi = instance->context->gdi;
155 update->BeginPaint = shw_begin_paint;
156 update->EndPaint = shw_end_paint;
157 update->DesktopResize = shw_desktop_resize;
158 update->SurfaceFrameMarker = shw_surface_frame_marker;
162 static DWORD WINAPI shw_client_thread(LPVOID arg)
168 rdpChannels* channels;
170 freerdp* instance = (freerdp*)arg;
171 WINPR_ASSERT(instance);
173 context = (rdpContext*)instance->context;
174 WINPR_ASSERT(context);
176 shw = (shwContext*)context;
178 bSuccess = freerdp_connect(instance);
179 WLog_INFO(TAG,
"freerdp_connect: %d", bSuccess);
187 channels = context->channels;
188 WINPR_ASSERT(channels);
193 HANDLE handles[MAXIMUM_WAIT_OBJECTS] = { 0 };
194 DWORD count = freerdp_get_event_handles(instance->context, handles, ARRAYSIZE(handles));
196 if ((count == 0) || (count == MAXIMUM_WAIT_OBJECTS))
198 WLog_ERR(TAG,
"Failed to get FreeRDP event handles");
202 handles[count++] = freerdp_channels_get_event_handle(instance);
204 if (MsgWaitForMultipleObjects(count, handles, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED)
206 WLog_ERR(TAG,
"MsgWaitForMultipleObjects failure: 0x%08lX", GetLastError());
210 if (!freerdp_check_fds(instance))
212 WLog_ERR(TAG,
"Failed to check FreeRDP file descriptor");
216 if (freerdp_shall_disconnect_context(instance->context))
221 if (!freerdp_channels_check_fds(channels, instance))
223 WLog_ERR(TAG,
"Failed to check channels file descriptor");
228 freerdp_free(instance);
237 static BOOL shw_freerdp_client_global_init(
void)
242 static void shw_freerdp_client_global_uninit(
void)
246 static int shw_freerdp_client_start(rdpContext* context)
249 freerdp* instance = context->instance;
250 shw = (shwContext*)context;
252 if (!(shw->common.thread = CreateThread(NULL, 0, shw_client_thread, instance, 0, NULL)))
254 WLog_ERR(TAG,
"Failed to create thread");
261 static int shw_freerdp_client_stop(rdpContext* context)
263 shwContext* shw = (shwContext*)context;
264 (void)SetEvent(shw->StopEvent);
268 static BOOL shw_freerdp_client_new(freerdp* instance, rdpContext* context)
271 rdpSettings* settings;
273 WINPR_ASSERT(instance);
274 WINPR_ASSERT(context);
276 shw = (shwContext*)instance->context;
279 if (!(shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
282 instance->LoadChannels = freerdp_client_load_channels;
283 instance->PreConnect = shw_pre_connect;
284 instance->PostConnect = shw_post_connect;
285 instance->Authenticate = shw_authenticate;
286 instance->VerifyX509Certificate = shw_verify_x509_certificate;
288 settings = context->settings;
289 WINPR_ASSERT(settings);
291 shw->settings = settings;
368 static void shw_freerdp_client_free(freerdp* instance, rdpContext* context)
370 shwContext* shw = (shwContext*)instance->context;
373 int shw_RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
375 pEntryPoints->Version = 1;
376 pEntryPoints->Size =
sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
377 pEntryPoints->settings = NULL;
378 pEntryPoints->ContextSize =
sizeof(shwContext);
379 pEntryPoints->GlobalInit = shw_freerdp_client_global_init;
380 pEntryPoints->GlobalUninit = shw_freerdp_client_global_uninit;
381 pEntryPoints->ClientNew = shw_freerdp_client_new;
382 pEntryPoints->ClientFree = shw_freerdp_client_free;
383 pEntryPoints->ClientStart = shw_freerdp_client_start;
384 pEntryPoints->ClientStop = shw_freerdp_client_stop;
388 int win_shadow_rdp_init(winShadowSubsystem* subsystem)
391 RDP_CLIENT_ENTRY_POINTS clientEntryPoints = { 0 };
393 clientEntryPoints.Size =
sizeof(RDP_CLIENT_ENTRY_POINTS);
394 clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
395 shw_RdpClientEntry(&clientEntryPoints);
397 if (!(subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
398 goto fail_enter_event;
400 if (!(subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
401 goto fail_leave_event;
403 if (!(context = freerdp_client_context_new(&clientEntryPoints)))
406 subsystem->shw = (shwContext*)context;
407 subsystem->shw->settings = context->settings;
408 subsystem->shw->subsystem = subsystem;
411 (void)CloseHandle(subsystem->RdpUpdateLeaveEvent);
413 (void)CloseHandle(subsystem->RdpUpdateEnterEvent);
418 int win_shadow_rdp_start(winShadowSubsystem* subsystem)
421 shwContext* shw = subsystem->shw;
422 rdpContext* context = (rdpContext*)shw;
423 status = freerdp_client_start(context);
427 int win_shadow_rdp_stop(winShadowSubsystem* subsystem)
430 shwContext* shw = subsystem->shw;
431 rdpContext* context = (rdpContext*)shw;
432 status = freerdp_client_stop(context);
436 int win_shadow_rdp_uninit(winShadowSubsystem* subsystem)
438 win_shadow_rdp_stop(subsystem);
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.
FREERDP_API void * freerdp_settings_get_pointer_writable(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a mutable pointer settings value.