19#include <freerdp/config.h> 
   22#include <winpr/assert.h> 
   23#include <winpr/print.h> 
   24#include <winpr/assert.h> 
   26#include <freerdp/log.h> 
   30#define TAG SERVER_TAG("shadow.win") 
   32static void shw_OnChannelConnectedEventHandler(
void* context, 
const ChannelConnectedEventArgs* e)
 
   34  shwContext* shw = (shwContext*)context;
 
   36  WLog_INFO(TAG, 
"OnChannelConnected: %s", e->name);
 
   39static void shw_OnChannelDisconnectedEventHandler(
void* context,
 
   40                                                  const ChannelDisconnectedEventArgs* e)
 
   42  shwContext* shw = (shwContext*)context;
 
   44  WLog_INFO(TAG, 
"OnChannelDisconnected: %s", e->name);
 
   47static BOOL shw_begin_paint(rdpContext* context)
 
   52  WINPR_ASSERT(context);
 
   55  shw = (shwContext*)context;
 
   56  gdi->primary->hdc->hwnd->invalid->null = TRUE;
 
   57  gdi->primary->hdc->hwnd->ninvalid = 0;
 
   61static BOOL shw_end_paint(rdpContext* context)
 
   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;
 
   73  for (
int index = 0; index < ninvalid; index++)
 
   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);
 
   82  (void)SetEvent(subsystem->RdpUpdateEnterEvent);
 
   83  (void)WaitForSingleObject(subsystem->RdpUpdateLeaveEvent, INFINITE);
 
   84  (void)ResetEvent(subsystem->RdpUpdateLeaveEvent);
 
   88BOOL shw_desktop_resize(rdpContext* context)
 
   90  WLog_WARN(TAG, 
"Desktop resizing not implemented!");
 
   94static BOOL shw_surface_frame_marker(rdpContext* context,
 
   97  shwContext* shw = (shwContext*)context;
 
  101static BOOL shw_authenticate(freerdp* instance, 
char** username, 
char** password, 
char** domain)
 
  103  WLog_WARN(TAG, 
"Authentication not implemented, access granted to everyone!");
 
  107static int shw_verify_x509_certificate(freerdp* instance, 
const BYTE* data, 
size_t length,
 
  108                                       const char* hostname, UINT16 port, DWORD flags)
 
  110  WLog_WARN(TAG, 
"Certificate checks not implemented, access granted to everyone!");
 
  114static void shw_OnConnectionResultEventHandler(
void* context, 
const ConnectionResultEventArgs* e)
 
  116  shwContext* shw = (shwContext*)context;
 
  118  WLog_INFO(TAG, 
"OnConnectionResult: %d", e->result);
 
  121static BOOL shw_pre_connect(freerdp* instance)
 
  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);
 
  133static BOOL shw_post_connect(freerdp* instance)
 
  138  rdpSettings* settings;
 
  140  WINPR_ASSERT(instance);
 
  142  shw = (shwContext*)instance->context;
 
  145  update = instance->context->update;
 
  146  WINPR_ASSERT(update);
 
  148  settings = instance->context->settings;
 
  149  WINPR_ASSERT(settings);
 
  151  if (!gdi_init(instance, PIXEL_FORMAT_BGRX32))
 
  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;
 
  162static DWORD WINAPI shw_client_thread(LPVOID arg)
 
  168  rdpChannels* channels;
 
  170  freerdp* instance = (freerdp*)arg;
 
  171  WINPR_ASSERT(instance);
 
  173  context = (rdpContext*)instance->context;
 
  174  WINPR_ASSERT(context);
 
  176  shw = (shwContext*)context;
 
  178  bSuccess = freerdp_connect(instance);
 
  179  WLog_INFO(TAG, 
"freerdp_connect: %d", bSuccess);
 
  187  channels = context->channels;
 
  188  WINPR_ASSERT(channels);
 
  193    HANDLE handles[MAXIMUM_WAIT_OBJECTS] = { 0 };
 
  194    DWORD count = freerdp_get_event_handles(instance->context, handles, ARRAYSIZE(handles));
 
  196    if ((count == 0) || (count == MAXIMUM_WAIT_OBJECTS))
 
  198      WLog_ERR(TAG, 
"Failed to get FreeRDP event handles");
 
  202    handles[count++] = freerdp_channels_get_event_handle(instance);
 
  204    if (MsgWaitForMultipleObjects(count, handles, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED)
 
  206      WLog_ERR(TAG, 
"MsgWaitForMultipleObjects failure: 0x%08lX", GetLastError());
 
  210    if (!freerdp_check_fds(instance))
 
  212      WLog_ERR(TAG, 
"Failed to check FreeRDP file descriptor");
 
  216    if (freerdp_shall_disconnect_context(instance->context))
 
  221    if (!freerdp_channels_check_fds(channels, instance))
 
  223      WLog_ERR(TAG, 
"Failed to check channels file descriptor");
 
  228  freerdp_free(instance);
 
  237static BOOL shw_freerdp_client_global_init(
void)
 
  242static void shw_freerdp_client_global_uninit(
void)
 
  246static int shw_freerdp_client_start(rdpContext* context)
 
  249  freerdp* instance = context->instance;
 
  250  shw = (shwContext*)context;
 
  252  if (!(shw->common.thread = CreateThread(NULL, 0, shw_client_thread, instance, 0, NULL)))
 
  254    WLog_ERR(TAG, 
"Failed to create thread");
 
  261static int shw_freerdp_client_stop(rdpContext* context)
 
  263  shwContext* shw = (shwContext*)context;
 
  264  (void)SetEvent(shw->StopEvent);
 
  268static BOOL shw_freerdp_client_new(freerdp* instance, rdpContext* context)
 
  271  rdpSettings* settings;
 
  273  WINPR_ASSERT(instance);
 
  274  WINPR_ASSERT(context);
 
  276  shw = (shwContext*)instance->context;
 
  279  if (!(shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
 
  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;
 
  288  settings = context->settings;
 
  289  WINPR_ASSERT(settings);
 
  291  shw->settings = settings;
 
  368static void shw_freerdp_client_free(freerdp* instance, rdpContext* context)
 
  370  shwContext* shw = (shwContext*)instance->context;
 
  373int shw_RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
 
  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;
 
  388int win_shadow_rdp_init(winShadowSubsystem* subsystem)
 
  391  RDP_CLIENT_ENTRY_POINTS clientEntryPoints = { 0 };
 
  393  clientEntryPoints.Size = 
sizeof(RDP_CLIENT_ENTRY_POINTS);
 
  394  clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
 
  395  shw_RdpClientEntry(&clientEntryPoints);
 
  397  if (!(subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
 
  398    goto fail_enter_event;
 
  400  if (!(subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
 
  401    goto fail_leave_event;
 
  403  if (!(context = freerdp_client_context_new(&clientEntryPoints)))
 
  406  subsystem->shw = (shwContext*)context;
 
  407  subsystem->shw->settings = context->settings;
 
  408  subsystem->shw->subsystem = subsystem;
 
  411  (void)CloseHandle(subsystem->RdpUpdateLeaveEvent);
 
  413  (void)CloseHandle(subsystem->RdpUpdateEnterEvent);
 
  418int win_shadow_rdp_start(winShadowSubsystem* subsystem)
 
  421  shwContext* shw = subsystem->shw;
 
  422  rdpContext* context = (rdpContext*)shw;
 
  423  status = freerdp_client_start(context);
 
  427int win_shadow_rdp_stop(winShadowSubsystem* subsystem)
 
  430  shwContext* shw = subsystem->shw;
 
  431  rdpContext* context = (rdpContext*)shw;
 
  432  status = freerdp_client_stop(context);
 
  436int win_shadow_rdp_uninit(winShadowSubsystem* subsystem)
 
  438  win_shadow_rdp_stop(subsystem);
 
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.