21 #include <freerdp/config.h>
23 #include <winpr/assert.h>
24 #include <winpr/tchar.h>
25 #include <winpr/stream.h>
26 #include <winpr/windows.h>
28 #include <freerdp/listener.h>
29 #include <freerdp/codec/rfx.h>
30 #include <freerdp/build-config.h>
31 #include <freerdp/crypto/certificate.h>
35 #include "wf_mirage.h"
36 #include "wf_update.h"
37 #include "wf_settings.h"
38 #include "wf_rdpsnd.h"
41 #include <freerdp/peer.h>
43 #include <freerdp/log.h>
44 #define TAG SERVER_TAG("windows")
46 #define SERVER_KEY "Software\\" FREERDP_VENDOR_STRING "\\" FREERDP_PRODUCT_STRING
48 static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam);
50 static BOOL wf_peer_context_new(freerdp_peer* client, rdpContext* ctx)
52 wfPeerContext* context = (wfPeerContext*)ctx;
53 WINPR_ASSERT(context);
55 if (!(context->info = wf_info_get_instance()))
58 context->vcm = WTSOpenServerA((LPSTR)client->context);
60 if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE)
63 if (!wf_info_peer_register(context->info, context))
65 WTSCloseServer(context->vcm);
73 static void wf_peer_context_free(freerdp_peer* client, rdpContext* ctx)
75 wfPeerContext* context = (wfPeerContext*)ctx;
76 WINPR_ASSERT(context);
78 wf_info_peer_unregister(context->info, context);
83 context->info->snd_stop = TRUE;
84 rdpsnd_server_context_free(context->rdpsnd);
88 WTSCloseServer(context->vcm);
91 static BOOL wf_peer_init(freerdp_peer* client)
93 client->ContextSize =
sizeof(wfPeerContext);
94 client->ContextNew = wf_peer_context_new;
95 client->ContextFree = wf_peer_context_free;
96 return freerdp_peer_context_new(client);
99 static BOOL wf_peer_post_connect(freerdp_peer* client)
102 rdpSettings* settings;
103 wfPeerContext* context;
105 WINPR_ASSERT(client);
107 context = (wfPeerContext*)client->context;
108 WINPR_ASSERT(context);
113 settings = client->context->settings;
114 WINPR_ASSERT(settings);
116 if ((get_screen_info(wfi->screenID, NULL, 0, &wfi->servscreen_width, &wfi->servscreen_height,
117 &wfi->bitsPerPixel) == 0) ||
118 (wfi->servscreen_width == 0) || (wfi->servscreen_height == 0) || (wfi->bitsPerPixel == 0))
120 WLog_ERR(TAG,
"postconnect: error getting screen info for screen %d", wfi->screenID);
121 WLog_ERR(TAG,
"\t%dx%dx%d", wfi->servscreen_height, wfi->servscreen_width,
140 WINPR_ASSERT(client->context->update);
141 WINPR_ASSERT(client->context->update->DesktopResize);
142 client->context->update->DesktopResize(client->context);
145 if (WTSVirtualChannelManagerIsChannelJoined(context->vcm,
"rdpsnd"))
147 wf_peer_rdpsnd_init(context);
153 static BOOL wf_peer_activate(freerdp_peer* client)
156 wfPeerContext* context = (wfPeerContext*)client->context;
158 client->activated = TRUE;
159 wf_update_peer_activate(wfi, context);
160 wfreerdp_server_peer_callback_event(((rdpContext*)context)->peer->pId,
161 FREERDP_SERVER_WIN_SRV_CALLBACK_EVENT_ACTIVATE);
165 static BOOL wf_peer_logon(freerdp_peer* client,
const SEC_WINNT_AUTH_IDENTITY* identity,
168 wfreerdp_server_peer_callback_event(((rdpContext*)client->context)->peer->pId,
169 FREERDP_SERVER_WIN_SRV_CALLBACK_EVENT_AUTH);
173 static BOOL wf_peer_synchronize_event(rdpInput* input, UINT32 flags)
178 BOOL wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
182 if (!(hThread = CreateThread(NULL, 0, wf_peer_main_loop, client, 0, NULL)))
185 (void)CloseHandle(hThread);
189 static DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
191 wfPeerContext* context;
192 freerdp_peer* client = (freerdp_peer*)lpParam;
194 WINPR_ASSERT(client);
195 WINPR_ASSERT(client->GetEventHandles);
196 WINPR_ASSERT(client->CheckFileDescriptor);
198 context = (wfPeerContext*)client->context;
199 WINPR_ASSERT(context);
204 HANDLE handles[MAXIMUM_WAIT_OBJECTS] = { 0 };
205 DWORD count = client->GetEventHandles(client, handles, ARRAYSIZE(handles));
209 WLog_ERR(TAG,
"Failed to get FreeRDP file descriptor");
213 status = WaitForMultipleObjects(count, handles, FALSE, INFINITE);
214 if (status == WAIT_FAILED)
216 WLog_ERR(TAG,
"WaitForMultipleObjects failed");
220 (void)SetEvent(context->socketEvent);
221 (void)WaitForSingleObject(context->socketSemaphore, INFINITE);
223 if (context->socketClose)
230 static BOOL wf_peer_read_settings(freerdp_peer* client)
232 rdpSettings* settings;
234 WINPR_ASSERT(client);
235 WINPR_ASSERT(client->context);
237 settings = client->context->settings;
238 WINPR_ASSERT(settings);
240 char* CertificateFile = NULL;
241 if (!wf_settings_read_string_ascii(HKEY_LOCAL_MACHINE, SERVER_KEY, _T(
"CertificateFile"),
243 CertificateFile = _strdup(
"server.crt");
245 rdpCertificate* cert = freerdp_certificate_new_from_file(CertificateFile);
246 free(CertificateFile);
253 char* PrivateKeyFile = NULL;
254 if (!wf_settings_read_string_ascii(HKEY_LOCAL_MACHINE, SERVER_KEY, _T(
"PrivateKeyFile"),
256 PrivateKeyFile = _strdup(
"server.key");
258 rdpPrivateKey* key = freerdp_key_new_from_file(PrivateKeyFile);
259 free(PrivateKeyFile);
270 DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
276 rdpSettings* settings;
277 wfPeerContext* context;
278 freerdp_peer* client = (freerdp_peer*)lpParam;
280 if (!wf_peer_init(client))
283 WINPR_ASSERT(client->context);
285 settings = client->context->settings;
286 WINPR_ASSERT(settings);
297 if (!wf_peer_read_settings(client))
300 client->PostConnect = wf_peer_post_connect;
301 client->Activate = wf_peer_activate;
302 client->Logon = wf_peer_logon;
304 WINPR_ASSERT(client->context->input);
305 client->context->input->SynchronizeEvent = wf_peer_synchronize_event;
306 client->context->input->KeyboardEvent = wf_peer_keyboard_event;
307 client->context->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event;
308 client->context->input->MouseEvent = wf_peer_mouse_event;
309 client->context->input->ExtendedMouseEvent = wf_peer_extended_mouse_event;
311 WINPR_ASSERT(client->Initialize);
312 if (!client->Initialize(client))
313 goto fail_client_initialize;
315 context = (wfPeerContext*)client->context;
317 if (context->socketClose)
318 goto fail_socked_closed;
322 if (wfi->input_disabled)
324 WLog_INFO(TAG,
"client input is disabled");
325 client->context->input->KeyboardEvent = wf_peer_keyboard_event_dummy;
326 client->context->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event_dummy;
327 client->context->input->MouseEvent = wf_peer_mouse_event_dummy;
328 client->context->input->ExtendedMouseEvent = wf_peer_extended_mouse_event_dummy;
331 if (!(context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
332 goto fail_socket_event;
334 if (!(context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL)))
335 goto fail_socket_semaphore;
337 if (!(context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL)))
338 goto fail_socket_thread;
340 WLog_INFO(TAG,
"We've got a client %s", client->local ?
"(local)" : client->hostname);
342 handles[nCount++] = context->updateEvent;
343 handles[nCount++] = context->socketEvent;
347 status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
349 if ((status == WAIT_FAILED) || (status == WAIT_TIMEOUT))
351 WLog_ERR(TAG,
"WaitForMultipleObjects failed");
355 if (WaitForSingleObject(context->updateEvent, 0) == 0)
357 if (client->activated)
358 wf_update_peer_send(wfi, context);
360 (void)ResetEvent(context->updateEvent);
361 ReleaseSemaphore(wfi->updateSemaphore, 1, NULL);
364 if (WaitForSingleObject(context->socketEvent, 0) == 0)
366 if (client->CheckFileDescriptor(client) != TRUE)
368 WLog_ERR(TAG,
"Failed to check peer file descriptor");
369 context->socketClose = TRUE;
372 (void)ResetEvent(context->socketEvent);
373 ReleaseSemaphore(context->socketSemaphore, 1, NULL);
375 if (context->socketClose)
380 if (wfi->force_all_disconnect == TRUE)
382 WLog_INFO(TAG,
"Forcing Disconnect -> ");
387 if (WTSVirtualChannelManagerCheckFileDescriptor(context->vcm) != TRUE)
391 WLog_INFO(TAG,
"Client %s disconnected.", client->local ?
"(local)" : client->hostname);
393 if (WaitForSingleObject(context->updateEvent, 0) == 0)
395 (void)ResetEvent(context->updateEvent);
396 ReleaseSemaphore(wfi->updateSemaphore, 1, NULL);
399 wf_update_peer_deactivate(wfi, context);
400 client->Disconnect(client);
402 (void)CloseHandle(context->socketSemaphore);
403 context->socketSemaphore = NULL;
404 fail_socket_semaphore:
405 (void)CloseHandle(context->socketEvent);
406 context->socketEvent = NULL;
409 fail_client_initialize:
410 freerdp_peer_context_free(client);
412 freerdp_peer_free(client);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
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.