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> 
   37#include "wf_settings.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 
   48static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam);
 
   50static 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);
 
   73static 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);
 
   91static 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);
 
   99static 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); 
 
  153static 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);
 
  165static 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);
 
  173static BOOL wf_peer_synchronize_event(rdpInput* input, UINT32 flags)
 
  178BOOL 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);
 
  189static 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)
 
  230static 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_enc(PrivateKeyFile, NULL);
 
  259  free(PrivateKeyFile);
 
  270DWORD 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;
 
  404fail_socket_semaphore:
 
  405  (void)CloseHandle(context->socketEvent);
 
  406  context->socketEvent = NULL;
 
  409fail_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.