FreeRDP
Loading...
Searching...
No Matches
win_rdp.c
1
19#include <freerdp/config.h>
20
21#include <winpr/crt.h>
22#include <winpr/assert.h>
23#include <winpr/print.h>
24#include <winpr/assert.h>
25
26#include <freerdp/log.h>
27
28#include "win_rdp.h"
29
30#define TAG SERVER_TAG("shadow.win")
31
32static void shw_OnChannelConnectedEventHandler(void* context, const ChannelConnectedEventArgs* e)
33{
34 shwContext* shw = (shwContext*)context;
35 WINPR_ASSERT(e);
36 WLog_INFO(TAG, "OnChannelConnected: %s", e->name);
37}
38
39static void shw_OnChannelDisconnectedEventHandler(void* context,
40 const ChannelDisconnectedEventArgs* e)
41{
42 shwContext* shw = (shwContext*)context;
43 WINPR_ASSERT(e);
44 WLog_INFO(TAG, "OnChannelDisconnected: %s", e->name);
45}
46
47static BOOL shw_begin_paint(rdpContext* context)
48{
49 shwContext* shw;
50 rdpGdi* gdi;
51
52 WINPR_ASSERT(context);
53 gdi = context->gdi;
54 WINPR_ASSERT(gdi);
55 shw = (shwContext*)context;
56 gdi->primary->hdc->hwnd->invalid->null = TRUE;
57 gdi->primary->hdc->hwnd->ninvalid = 0;
58 return TRUE;
59}
60
61static BOOL shw_end_paint(rdpContext* context)
62{
63 int ninvalid;
64 HGDI_RGN cinvalid;
65 RECTANGLE_16 invalidRect;
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;
72
73 for (int index = 0; index < ninvalid; index++)
74 {
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);
80 }
81
82 (void)SetEvent(subsystem->RdpUpdateEnterEvent);
83 (void)WaitForSingleObject(subsystem->RdpUpdateLeaveEvent, INFINITE);
84 (void)ResetEvent(subsystem->RdpUpdateLeaveEvent);
85 return TRUE;
86}
87
88BOOL shw_desktop_resize(rdpContext* context)
89{
90 WLog_WARN(TAG, "Desktop resizing not implemented!");
91 return TRUE;
92}
93
94static BOOL shw_surface_frame_marker(rdpContext* context,
95 const SURFACE_FRAME_MARKER* surfaceFrameMarker)
96{
97 shwContext* shw = (shwContext*)context;
98 return TRUE;
99}
100
101static BOOL shw_authenticate(freerdp* instance, char** username, char** password, char** domain)
102{
103 WLog_WARN(TAG, "Authentication not implemented, access granted to everyone!");
104 return TRUE;
105}
106
107static int shw_verify_x509_certificate(freerdp* instance, const BYTE* data, size_t length,
108 const char* hostname, UINT16 port, DWORD flags)
109{
110 WLog_WARN(TAG, "Certificate checks not implemented, access granted to everyone!");
111 return 1;
112}
113
114static void shw_OnConnectionResultEventHandler(void* context, const ConnectionResultEventArgs* e)
115{
116 shwContext* shw = (shwContext*)context;
117 WINPR_ASSERT(e);
118 WLog_INFO(TAG, "OnConnectionResult: %d", e->result);
119}
120
121static BOOL shw_pre_connect(freerdp* instance)
122{
123 shwContext* shw;
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);
129
130 return TRUE;
131}
132
133static BOOL shw_post_connect(freerdp* instance)
134{
135 rdpGdi* gdi;
136 shwContext* shw;
137 rdpUpdate* update;
138 rdpSettings* settings;
139
140 WINPR_ASSERT(instance);
141
142 shw = (shwContext*)instance->context;
143 WINPR_ASSERT(shw);
144
145 update = instance->context->update;
146 WINPR_ASSERT(update);
147
148 settings = instance->context->settings;
149 WINPR_ASSERT(settings);
150
151 if (!gdi_init(instance, PIXEL_FORMAT_BGRX32))
152 return FALSE;
153
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;
159 return TRUE;
160}
161
162static DWORD WINAPI shw_client_thread(LPVOID arg)
163{
164 int index;
165 BOOL bSuccess;
166 shwContext* shw;
167 rdpContext* context;
168 rdpChannels* channels;
169
170 freerdp* instance = (freerdp*)arg;
171 WINPR_ASSERT(instance);
172
173 context = (rdpContext*)instance->context;
174 WINPR_ASSERT(context);
175
176 shw = (shwContext*)context;
177
178 bSuccess = freerdp_connect(instance);
179 WLog_INFO(TAG, "freerdp_connect: %d", bSuccess);
180
181 if (!bSuccess)
182 {
183 ExitThread(0);
184 return 0;
185 }
186
187 channels = context->channels;
188 WINPR_ASSERT(channels);
189
190 while (1)
191 {
192 DWORD status;
193 HANDLE handles[MAXIMUM_WAIT_OBJECTS] = { 0 };
194 DWORD count = freerdp_get_event_handles(instance->context, handles, ARRAYSIZE(handles));
195
196 if ((count == 0) || (count == MAXIMUM_WAIT_OBJECTS))
197 {
198 WLog_ERR(TAG, "Failed to get FreeRDP event handles");
199 break;
200 }
201
202 handles[count++] = freerdp_channels_get_event_handle(instance);
203
204 if (MsgWaitForMultipleObjects(count, handles, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED)
205 {
206 WLog_ERR(TAG, "MsgWaitForMultipleObjects failure: 0x%08lX", GetLastError());
207 break;
208 }
209
210 if (!freerdp_check_fds(instance))
211 {
212 WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
213 break;
214 }
215
216 if (freerdp_shall_disconnect_context(instance->context))
217 {
218 break;
219 }
220
221 if (!freerdp_channels_check_fds(channels, instance))
222 {
223 WLog_ERR(TAG, "Failed to check channels file descriptor");
224 break;
225 }
226 }
227
228 freerdp_free(instance);
229 ExitThread(0);
230 return 0;
231}
232
237static BOOL shw_freerdp_client_global_init(void)
238{
239 return TRUE;
240}
241
242static void shw_freerdp_client_global_uninit(void)
243{
244}
245
246static int shw_freerdp_client_start(rdpContext* context)
247{
248 shwContext* shw;
249 freerdp* instance = context->instance;
250 shw = (shwContext*)context;
251
252 if (!(shw->common.thread = CreateThread(NULL, 0, shw_client_thread, instance, 0, NULL)))
253 {
254 WLog_ERR(TAG, "Failed to create thread");
255 return -1;
256 }
257
258 return 0;
259}
260
261static int shw_freerdp_client_stop(rdpContext* context)
262{
263 shwContext* shw = (shwContext*)context;
264 (void)SetEvent(shw->StopEvent);
265 return 0;
266}
267
268static BOOL shw_freerdp_client_new(freerdp* instance, rdpContext* context)
269{
270 shwContext* shw;
271 rdpSettings* settings;
272
273 WINPR_ASSERT(instance);
274 WINPR_ASSERT(context);
275
276 shw = (shwContext*)instance->context;
277 WINPR_ASSERT(shw);
278
279 if (!(shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
280 return FALSE;
281
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;
287
288 settings = context->settings;
289 WINPR_ASSERT(settings);
290
291 shw->settings = settings;
292 if (!freerdp_settings_set_bool(settings, FreeRDP_AsyncChannels, FALSE))
293 return FALSE;
294 if (!freerdp_settings_set_bool(settings, FreeRDP_AsyncUpdate, FALSE))
295 return FALSE;
296 if (!freerdp_settings_set_bool(settings, FreeRDP_IgnoreCertificate, TRUE))
297 return FALSE;
298 if (!freerdp_settings_set_bool(settings, FreeRDP_ExternalCertificateManagement, TRUE))
299 return FALSE;
300 if (!freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, TRUE))
301 return FALSE;
302 if (!freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, TRUE))
303 return FALSE;
304 if (!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, FALSE))
305 return FALSE;
306 if (!freerdp_settings_set_bool(settings, FreeRDP_BitmapCacheEnabled, FALSE))
307 return FALSE;
308 if (!freerdp_settings_set_bool(settings, FreeRDP_BitmapCacheV3Enabled, FALSE))
309 return FALSE;
310 if (!freerdp_settings_set_bool(settings, FreeRDP_OffscreenSupportLevel, FALSE))
311 return FALSE;
312 if (!freerdp_settings_set_uint32(settings, FreeRDP_GlyphSupportLevel, GLYPH_SUPPORT_NONE))
313 return FALSE;
314 if (!freerdp_settings_set_bool(settings, FreeRDP_BrushSupportLevel, FALSE))
315 return FALSE;
316 ZeroMemory(freerdp_settings_get_pointer_writable(settings, FreeRDP_OrderSupport), 32);
317 if (!freerdp_settings_set_bool(settings, FreeRDP_FrameMarkerCommandEnabled, TRUE))
318 return FALSE;
319 if (!freerdp_settings_set_bool(settings, FreeRDP_SurfaceFrameMarkerEnabled, TRUE))
320 return FALSE;
321 if (!freerdp_settings_set_bool(settings, FreeRDP_AltSecFrameMarkerSupport, TRUE))
322 return FALSE;
323 if (!freerdp_settings_set_uint32(settings, FreeRDP_ColorDepth, 32))
324 return FALSE;
325 if (!freerdp_settings_set_bool(settings, FreeRDP_NSCodec, TRUE))
326 return FALSE;
327 if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteFxCodec, TRUE))
328 return FALSE;
329 if (!freerdp_settings_set_bool(settings, FreeRDP_FastPathInput, TRUE))
330 return FALSE;
331 if (!freerdp_settings_set_bool(settings, FreeRDP_FastPathOutput, TRUE))
332 return FALSE;
333 if (!freerdp_settings_set_bool(settings, FreeRDP_LargePointerFlag, TRUE))
334 return FALSE;
335 if (!freerdp_settings_set_bool(settings, FreeRDP_CompressionEnabled, FALSE))
336 return FALSE;
337 if (!freerdp_settings_set_bool(settings, FreeRDP_AutoReconnectionEnabled, FALSE))
338 return FALSE;
339 if (!freerdp_settings_set_bool(settings, FreeRDP_NetworkAutoDetect, FALSE))
340 return FALSE;
341 if (!freerdp_settings_set_bool(settings, FreeRDP_SupportHeartbeatPdu, FALSE))
342 return FALSE;
343 if (!freerdp_settings_set_bool(settings, FreeRDP_SupportMultitransport, FALSE))
344 return FALSE;
345 if (!freerdp_settings_set_uint32(settings, FreeRDP_ConnectionType, CONNECTION_TYPE_LAN))
346 return FALSE;
347 if (!freerdp_settings_set_bool(settings, FreeRDP_AllowFontSmoothing, TRUE))
348 return FALSE;
349 if (!freerdp_settings_set_bool(settings, FreeRDP_AllowDesktopComposition, TRUE))
350 return FALSE;
351 if (!freerdp_settings_set_bool(settings, FreeRDP_DisableWallpaper, FALSE))
352 return FALSE;
353 if (!freerdp_settings_set_bool(settings, FreeRDP_DisableFullWindowDrag, TRUE))
354 return FALSE;
355 if (!freerdp_settings_set_bool(settings, FreeRDP_DisableMenuAnims, TRUE))
356 return FALSE;
357 if (!freerdp_settings_set_bool(settings, FreeRDP_DisableThemes, FALSE))
358 return FALSE;
359 if (!freerdp_settings_set_bool(settings, FreeRDP_DeviceRedirection, TRUE))
360 return FALSE;
361 if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectClipboard, TRUE))
362 return FALSE;
363 if (!freerdp_settings_set_bool(settings, FreeRDP_SupportDynamicChannels, TRUE))
364 return FALSE;
365 return TRUE;
366}
367
368static void shw_freerdp_client_free(freerdp* instance, rdpContext* context)
369{
370 shwContext* shw = (shwContext*)instance->context;
371}
372
373int shw_RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
374{
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;
385 return 0;
386}
387
388int win_shadow_rdp_init(winShadowSubsystem* subsystem)
389{
390 rdpContext* context;
391 RDP_CLIENT_ENTRY_POINTS clientEntryPoints = { 0 };
392
393 clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
394 clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
395 shw_RdpClientEntry(&clientEntryPoints);
396
397 if (!(subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
398 goto fail_enter_event;
399
400 if (!(subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
401 goto fail_leave_event;
402
403 if (!(context = freerdp_client_context_new(&clientEntryPoints)))
404 goto fail_context;
405
406 subsystem->shw = (shwContext*)context;
407 subsystem->shw->settings = context->settings;
408 subsystem->shw->subsystem = subsystem;
409 return 1;
410fail_context:
411 (void)CloseHandle(subsystem->RdpUpdateLeaveEvent);
412fail_leave_event:
413 (void)CloseHandle(subsystem->RdpUpdateEnterEvent);
414fail_enter_event:
415 return -1;
416}
417
418int win_shadow_rdp_start(winShadowSubsystem* subsystem)
419{
420 int status;
421 shwContext* shw = subsystem->shw;
422 rdpContext* context = (rdpContext*)shw;
423 status = freerdp_client_start(context);
424 return status;
425}
426
427int win_shadow_rdp_stop(winShadowSubsystem* subsystem)
428{
429 int status;
430 shwContext* shw = subsystem->shw;
431 rdpContext* context = (rdpContext*)shw;
432 status = freerdp_client_stop(context);
433 return status;
434}
435
436int win_shadow_rdp_uninit(winShadowSubsystem* subsystem)
437{
438 win_shadow_rdp_stop(subsystem);
439 return 1;
440}
FREERDP_API void * freerdp_settings_get_pointer_writable(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a mutable pointer settings value.
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.