FreeRDP
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 
32 static 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 
39 static 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 
47 static 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 
61 static 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 
88 BOOL shw_desktop_resize(rdpContext* context)
89 {
90  WLog_WARN(TAG, "Desktop resizing not implemented!");
91  return TRUE;
92 }
93 
94 static BOOL shw_surface_frame_marker(rdpContext* context,
95  const SURFACE_FRAME_MARKER* surfaceFrameMarker)
96 {
97  shwContext* shw = (shwContext*)context;
98  return TRUE;
99 }
100 
101 static 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 
107 static 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 
114 static 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 
121 static 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 
133 static 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 
162 static 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 
237 static BOOL shw_freerdp_client_global_init(void)
238 {
239  return TRUE;
240 }
241 
242 static void shw_freerdp_client_global_uninit(void)
243 {
244 }
245 
246 static 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 
261 static int shw_freerdp_client_stop(rdpContext* context)
262 {
263  shwContext* shw = (shwContext*)context;
264  (void)SetEvent(shw->StopEvent);
265  return 0;
266 }
267 
268 static 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 
368 static void shw_freerdp_client_free(freerdp* instance, rdpContext* context)
369 {
370  shwContext* shw = (shwContext*)instance->context;
371 }
372 
373 int 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 
388 int 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;
410 fail_context:
411  (void)CloseHandle(subsystem->RdpUpdateLeaveEvent);
412 fail_leave_event:
413  (void)CloseHandle(subsystem->RdpUpdateEnterEvent);
414 fail_enter_event:
415  return -1;
416 }
417 
418 int 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 
427 int 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 
436 int win_shadow_rdp_uninit(winShadowSubsystem* subsystem)
437 {
438  win_shadow_rdp_stop(subsystem);
439  return 1;
440 }
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.