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 rdp_auth_reason reason)
103{
104 WINPR_UNUSED(reason);
105 WLog_WARN(TAG, "Authentication not implemented, access granted to everyone!");
106 return TRUE;
107}
108
109static int shw_verify_x509_certificate(freerdp* instance, const BYTE* data, size_t length,
110 const char* hostname, UINT16 port, DWORD flags)
111{
112 WLog_WARN(TAG, "Certificate checks not implemented, access granted to everyone!");
113 return 1;
114}
115
116static void shw_OnConnectionResultEventHandler(void* context, const ConnectionResultEventArgs* e)
117{
118 shwContext* shw = (shwContext*)context;
119 WINPR_ASSERT(e);
120 WLog_INFO(TAG, "OnConnectionResult: %d", e->result);
121}
122
123static BOOL shw_pre_connect(freerdp* instance)
124{
125 shwContext* shw;
126 rdpContext* context = instance->context;
127 shw = (shwContext*)context;
128 PubSub_SubscribeConnectionResult(context->pubSub, shw_OnConnectionResultEventHandler);
129 PubSub_SubscribeChannelConnected(context->pubSub, shw_OnChannelConnectedEventHandler);
130 PubSub_SubscribeChannelDisconnected(context->pubSub, shw_OnChannelDisconnectedEventHandler);
131
132 return TRUE;
133}
134
135static BOOL shw_post_connect(freerdp* instance)
136{
137 rdpGdi* gdi;
138 shwContext* shw;
139 rdpUpdate* update;
140 rdpSettings* settings;
141
142 WINPR_ASSERT(instance);
143
144 shw = (shwContext*)instance->context;
145 WINPR_ASSERT(shw);
146
147 update = instance->context->update;
148 WINPR_ASSERT(update);
149
150 settings = instance->context->settings;
151 WINPR_ASSERT(settings);
152
153 if (!gdi_init(instance, PIXEL_FORMAT_BGRX32))
154 return FALSE;
155
156 gdi = instance->context->gdi;
157 update->BeginPaint = shw_begin_paint;
158 update->EndPaint = shw_end_paint;
159 update->DesktopResize = shw_desktop_resize;
160 update->SurfaceFrameMarker = shw_surface_frame_marker;
161 return TRUE;
162}
163
164static DWORD WINAPI shw_client_thread(LPVOID arg)
165{
166 freerdp* instance = (freerdp*)arg;
167 WINPR_ASSERT(instance);
168
169 rdpContext* context = (rdpContext*)instance->context;
170 WINPR_ASSERT(context);
171
172 shwContext* shw = (shwContext*)context;
173
174 const BOOL bSuccess = freerdp_connect(instance);
175 WLog_INFO(TAG, "freerdp_connect: %d", bSuccess);
176
177 if (!bSuccess)
178 {
179 ExitThread(0);
180 return 0;
181 }
182
183 rdpChannels* channels = context->channels;
184 WINPR_ASSERT(channels);
185
186 while (1)
187 {
188 HANDLE handles[MAXIMUM_WAIT_OBJECTS] = WINPR_C_ARRAY_INIT;
189 DWORD count = freerdp_get_event_handles(instance->context, handles, ARRAYSIZE(handles));
190
191 if ((count == 0) || (count == MAXIMUM_WAIT_OBJECTS))
192 {
193 WLog_ERR(TAG, "Failed to get FreeRDP event handles");
194 break;
195 }
196
197 handles[count++] = freerdp_channels_get_event_handle(instance);
198
199 if (MsgWaitForMultipleObjects(count, handles, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED)
200 {
201 WLog_ERR(TAG, "MsgWaitForMultipleObjects failure: 0x%08lX", GetLastError());
202 break;
203 }
204
205 if (!freerdp_check_fds(instance))
206 {
207 WLog_ERR(TAG, "Failed to check FreeRDP file descriptor");
208 break;
209 }
210
211 if (freerdp_shall_disconnect_context(instance->context))
212 {
213 break;
214 }
215
216 if (!freerdp_channels_check_fds(channels, instance))
217 {
218 WLog_ERR(TAG, "Failed to check channels file descriptor");
219 break;
220 }
221 }
222
223 freerdp_free(instance);
224 ExitThread(0);
225 return 0;
226}
227
232static BOOL shw_freerdp_client_global_init(void)
233{
234 return TRUE;
235}
236
237static void shw_freerdp_client_global_uninit(void)
238{
239}
240
241static int shw_freerdp_client_start(rdpContext* context)
242{
243 shwContext* shw;
244 freerdp* instance = context->instance;
245 shw = (shwContext*)context;
246
247 if (!(shw->common.thread = CreateThread(nullptr, 0, shw_client_thread, instance, 0, nullptr)))
248 {
249 WLog_ERR(TAG, "Failed to create thread");
250 return -1;
251 }
252
253 return 0;
254}
255
256static int shw_freerdp_client_stop(rdpContext* context)
257{
258 shwContext* shw = (shwContext*)context;
259 (void)SetEvent(shw->StopEvent);
260 return 0;
261}
262
263static BOOL shw_freerdp_client_new(freerdp* instance, rdpContext* context)
264{
265 shwContext* shw;
266 rdpSettings* settings;
267
268 WINPR_ASSERT(instance);
269 WINPR_ASSERT(context);
270
271 shw = (shwContext*)instance->context;
272 WINPR_ASSERT(shw);
273
274 if (!(shw->StopEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr)))
275 return FALSE;
276
277 instance->LoadChannels = freerdp_client_load_channels;
278 instance->PreConnect = shw_pre_connect;
279 instance->PostConnect = shw_post_connect;
280 instance->AuthenticateEx = shw_authenticate;
281 instance->VerifyX509Certificate = shw_verify_x509_certificate;
282
283 settings = context->settings;
284 WINPR_ASSERT(settings);
285
286 shw->settings = settings;
287 if (!freerdp_settings_set_bool(settings, FreeRDP_AsyncChannels, FALSE))
288 return FALSE;
289 if (!freerdp_settings_set_bool(settings, FreeRDP_AsyncUpdate, FALSE))
290 return FALSE;
291 if (!freerdp_settings_set_bool(settings, FreeRDP_IgnoreCertificate, TRUE))
292 return FALSE;
293 if (!freerdp_settings_set_bool(settings, FreeRDP_ExternalCertificateManagement, TRUE))
294 return FALSE;
295 if (!freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, TRUE))
296 return FALSE;
297 if (!freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, TRUE))
298 return FALSE;
299 if (!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, FALSE))
300 return FALSE;
301 if (!freerdp_settings_set_bool(settings, FreeRDP_BitmapCacheEnabled, FALSE))
302 return FALSE;
303 if (!freerdp_settings_set_bool(settings, FreeRDP_BitmapCacheV3Enabled, FALSE))
304 return FALSE;
305 if (!freerdp_settings_set_uint32(settings, FreeRDP_OffscreenSupportLevel, 0))
306 return FALSE;
307 if (!freerdp_settings_set_uint32(settings, FreeRDP_GlyphSupportLevel, GLYPH_SUPPORT_NONE))
308 return FALSE;
309 if (!freerdp_settings_set_uint32(settings, FreeRDP_BrushSupportLevel, 0))
310 return FALSE;
311 ZeroMemory(freerdp_settings_get_pointer_writable(settings, FreeRDP_OrderSupport), 32);
312 if (!freerdp_settings_set_bool(settings, FreeRDP_FrameMarkerCommandEnabled, TRUE))
313 return FALSE;
314 if (!freerdp_settings_set_bool(settings, FreeRDP_SurfaceFrameMarkerEnabled, TRUE))
315 return FALSE;
316 if (!freerdp_settings_set_bool(settings, FreeRDP_AltSecFrameMarkerSupport, TRUE))
317 return FALSE;
318 if (!freerdp_settings_set_uint32(settings, FreeRDP_ColorDepth, 32))
319 return FALSE;
320 if (!freerdp_settings_set_bool(settings, FreeRDP_NSCodec, TRUE))
321 return FALSE;
322 if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteFxCodec, TRUE))
323 return FALSE;
324 if (!freerdp_settings_set_bool(settings, FreeRDP_FastPathInput, TRUE))
325 return FALSE;
326 if (!freerdp_settings_set_bool(settings, FreeRDP_FastPathOutput, TRUE))
327 return FALSE;
328 if (!freerdp_settings_set_uint32(settings, FreeRDP_LargePointerFlag, 1))
329 return FALSE;
330 if (!freerdp_settings_set_bool(settings, FreeRDP_CompressionEnabled, FALSE))
331 return FALSE;
332 if (!freerdp_settings_set_bool(settings, FreeRDP_AutoReconnectionEnabled, FALSE))
333 return FALSE;
334 if (!freerdp_settings_set_bool(settings, FreeRDP_NetworkAutoDetect, FALSE))
335 return FALSE;
336 if (!freerdp_settings_set_bool(settings, FreeRDP_SupportHeartbeatPdu, FALSE))
337 return FALSE;
338 if (!freerdp_settings_set_bool(settings, FreeRDP_SupportMultitransport, FALSE))
339 return FALSE;
340 if (!freerdp_settings_set_uint32(settings, FreeRDP_ConnectionType, CONNECTION_TYPE_LAN))
341 return FALSE;
342 if (!freerdp_settings_set_bool(settings, FreeRDP_AllowFontSmoothing, TRUE))
343 return FALSE;
344 if (!freerdp_settings_set_bool(settings, FreeRDP_AllowDesktopComposition, TRUE))
345 return FALSE;
346 if (!freerdp_settings_set_bool(settings, FreeRDP_DisableWallpaper, FALSE))
347 return FALSE;
348 if (!freerdp_settings_set_bool(settings, FreeRDP_DisableFullWindowDrag, TRUE))
349 return FALSE;
350 if (!freerdp_settings_set_bool(settings, FreeRDP_DisableMenuAnims, TRUE))
351 return FALSE;
352 if (!freerdp_settings_set_bool(settings, FreeRDP_DisableThemes, FALSE))
353 return FALSE;
354 if (!freerdp_settings_set_bool(settings, FreeRDP_DeviceRedirection, TRUE))
355 return FALSE;
356 if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectClipboard, TRUE))
357 return FALSE;
358 if (!freerdp_settings_set_bool(settings, FreeRDP_SupportDynamicChannels, TRUE))
359 return FALSE;
360 return TRUE;
361}
362
363static void shw_freerdp_client_free(freerdp* instance, rdpContext* context)
364{
365 shwContext* shw = (shwContext*)instance->context;
366}
367
368int shw_RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
369{
370 pEntryPoints->Version = 1;
371 pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
372 pEntryPoints->settings = nullptr;
373 pEntryPoints->ContextSize = sizeof(shwContext);
374 pEntryPoints->GlobalInit = shw_freerdp_client_global_init;
375 pEntryPoints->GlobalUninit = shw_freerdp_client_global_uninit;
376 pEntryPoints->ClientNew = shw_freerdp_client_new;
377 pEntryPoints->ClientFree = shw_freerdp_client_free;
378 pEntryPoints->ClientStart = shw_freerdp_client_start;
379 pEntryPoints->ClientStop = shw_freerdp_client_stop;
380 return 0;
381}
382
383int win_shadow_rdp_init(winShadowSubsystem* subsystem)
384{
385 rdpContext* context;
386 RDP_CLIENT_ENTRY_POINTS clientEntryPoints = WINPR_C_ARRAY_INIT;
387
388 clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
389 clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
390 shw_RdpClientEntry(&clientEntryPoints);
391
392 if (!(subsystem->RdpUpdateEnterEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr)))
393 goto fail_enter_event;
394
395 if (!(subsystem->RdpUpdateLeaveEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr)))
396 goto fail_leave_event;
397
398 if (!(context = freerdp_client_context_new(&clientEntryPoints)))
399 goto fail_context;
400
401 subsystem->shw = (shwContext*)context;
402 subsystem->shw->settings = context->settings;
403 subsystem->shw->subsystem = subsystem;
404 return 1;
405fail_context:
406 (void)CloseHandle(subsystem->RdpUpdateLeaveEvent);
407fail_leave_event:
408 (void)CloseHandle(subsystem->RdpUpdateEnterEvent);
409fail_enter_event:
410 return -1;
411}
412
413int win_shadow_rdp_start(winShadowSubsystem* subsystem)
414{
415 int status;
416 shwContext* shw = subsystem->shw;
417 rdpContext* context = (rdpContext*)shw;
418 status = freerdp_client_start(context);
419 return status;
420}
421
422int win_shadow_rdp_stop(winShadowSubsystem* subsystem)
423{
424 int status;
425 shwContext* shw = subsystem->shw;
426 rdpContext* context = (rdpContext*)shw;
427 status = freerdp_client_stop(context);
428 return status;
429}
430
431int win_shadow_rdp_uninit(winShadowSubsystem* subsystem)
432{
433 win_shadow_rdp_stop(subsystem);
434 return 1;
435}
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 void * freerdp_settings_get_pointer_writable(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a mutable pointer 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.