From 01c557d1c30d61324fbc8cdcbef7474de32f67db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 10 Jul 2014 17:20:41 -0400 Subject: [PATCH] shadow: start making generic core --- server/shadow/CMakeLists.txt | 5 +- .../shadow/X11/{x11_peer.c => x11_client.c} | 68 +++--- server/shadow/X11/x11_input.c | 24 +- server/shadow/X11/x11_shadow.c | 2 +- server/shadow/X11/x11_shadow.h | 36 +-- server/shadow/X11/x11_update.c | 16 +- server/shadow/shadow.c | 75 ++++-- server/shadow/shadow.h | 19 +- server/shadow/shadow_client.c | 213 ++++++++++++++++++ server/shadow/shadow_input.c | 54 +++++ server/shadow/shadow_update.c | 0 11 files changed, 424 insertions(+), 88 deletions(-) rename server/shadow/X11/{x11_peer.c => x11_client.c} (87%) create mode 100644 server/shadow/shadow_client.c create mode 100644 server/shadow/shadow_input.c create mode 100644 server/shadow/shadow_update.c diff --git a/server/shadow/CMakeLists.txt b/server/shadow/CMakeLists.txt index 2fd6220d6..3ef9e46fe 100644 --- a/server/shadow/CMakeLists.txt +++ b/server/shadow/CMakeLists.txt @@ -116,12 +116,15 @@ if(WITH_X11) endif() set(${MODULE_PREFIX}_SRCS + shadow_client.c + shadow_input.c + shadow_update.c shadow.c shadow.h) set(${MODULE_PREFIX}_X11_SRCS X11/x11_input.c - X11/x11_peer.c + X11/x11_client.c X11/x11_update.c X11/x11_shadow.c X11/x11_shadow.h) diff --git a/server/shadow/X11/x11_peer.c b/server/shadow/X11/x11_client.c similarity index 87% rename from server/shadow/X11/x11_peer.c rename to server/shadow/X11/x11_client.c index ef161a5ba..3ccecf0a1 100644 --- a/server/shadow/X11/x11_peer.c +++ b/server/shadow/X11/x11_client.c @@ -48,7 +48,7 @@ #ifdef WITH_XDAMAGE -void xf_xdamage_init(xfInfo* xfi) +void x11_shadow_xdamage_init(xfInfo* xfi) { int damage_event; int damage_error; @@ -102,7 +102,7 @@ void xf_xdamage_init(xfInfo* xfi) #endif -int xf_xshm_init(xfInfo* xfi) +int x11_shadow_xshm_init(xfInfo* xfi) { Bool pixmaps; int major, minor; @@ -169,7 +169,7 @@ int xf_xshm_init(xfInfo* xfi) return 0; } -void xf_info_free(xfInfo *info) +void x11_shadow_info_free(xfInfo *info) { if (info->display) XCloseDisplay(info->display); @@ -178,7 +178,7 @@ void xf_info_free(xfInfo *info) free(info); } -xfInfo* xf_info_init() +xfInfo* x11_shadow_info_init() { int i; xfInfo* xfi; @@ -271,7 +271,7 @@ xfInfo* xf_info_init() if (xfi->use_xshm) { - if (xf_xshm_init(xfi) < 0) + if (x11_shadow_xshm_init(xfi) < 0) xfi->use_xshm = FALSE; } @@ -279,10 +279,10 @@ xfInfo* xf_info_init() printf("Using X Shared Memory Extension (XShm)\n"); #ifdef WITH_XDAMAGE - xf_xdamage_init(xfi); + x11_shadow_xdamage_init(xfi); #endif - xf_cursor_init(xfi); + x11_shadow_cursor_init(xfi); xfi->bytesPerPixel = 4; xfi->activePeerCount = 0; @@ -292,9 +292,9 @@ xfInfo* xf_info_init() return xfi; } -void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context) +void x11_shadow_peer_context_new(freerdp_peer* client, xfPeerContext* context) { - context->info = xf_info_init(); + context->info = x11_shadow_info_init(); context->rfx_context = rfx_context_new(TRUE); context->rfx_context->mode = RLGR3; context->rfx_context->width = context->info->width; @@ -309,11 +309,11 @@ void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context) context->updateSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL); } -void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context) +void x11_shadow_peer_context_free(freerdp_peer* client, xfPeerContext* context) { if (context) { - xf_info_free(context->info); + x11_shadow_info_free(context->info); CloseHandle(context->updateReadyEvent); CloseHandle(context->updateSentEvent); @@ -323,14 +323,14 @@ void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context) } } -void xf_peer_init(freerdp_peer* client) +void x11_shadow_peer_init(freerdp_peer* client) { xfInfo* xfi; xfPeerContext* xfp; client->ContextSize = sizeof(xfPeerContext); - client->ContextNew = (psPeerContextNew) xf_peer_context_new; - client->ContextFree = (psPeerContextFree) xf_peer_context_free; + client->ContextNew = (psPeerContextNew) x11_shadow_peer_context_new; + client->ContextFree = (psPeerContextFree) x11_shadow_peer_context_free; freerdp_peer_context_new(client); xfp = (xfPeerContext*) client->context; @@ -341,7 +341,7 @@ void xf_peer_init(freerdp_peer* client) xfp->mutex = CreateMutex(NULL, FALSE, NULL); } -void xf_peer_send_update(freerdp_peer* client) +void x11_shadow_peer_send_update(freerdp_peer* client) { rdpUpdate* update; SURFACE_BITS_COMMAND* cmd; @@ -353,7 +353,7 @@ void xf_peer_send_update(freerdp_peer* client) update->SurfaceBits(update->context, cmd); } -BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) +BOOL x11_shadow_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) { int fds; HANDLE event; @@ -367,7 +367,7 @@ BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) return TRUE; } -BOOL xf_peer_check_fds(freerdp_peer* client) +BOOL x11_shadow_peer_check_fds(freerdp_peer* client) { xfInfo* xfi; xfPeerContext* xfp; @@ -380,7 +380,7 @@ BOOL xf_peer_check_fds(freerdp_peer* client) if (!xfp->activated) return TRUE; - xf_peer_send_update(client); + x11_shadow_peer_send_update(client); ResetEvent(xfp->updateReadyEvent); SetEvent(xfp->updateSentEvent); @@ -389,12 +389,12 @@ BOOL xf_peer_check_fds(freerdp_peer* client) return TRUE; } -BOOL xf_peer_capabilities(freerdp_peer* client) +BOOL x11_shadow_peer_capabilities(freerdp_peer* client) { return TRUE; } -BOOL xf_peer_post_connect(freerdp_peer* client) +BOOL x11_shadow_peer_post_connect(freerdp_peer* client) { xfInfo* xfi; xfPeerContext* xfp; @@ -431,7 +431,7 @@ BOOL xf_peer_post_connect(freerdp_peer* client) return TRUE; } -BOOL xf_peer_activate(freerdp_peer* client) +BOOL x11_shadow_peer_activate(freerdp_peer* client) { xfPeerContext* xfp = (xfPeerContext*) client->context; @@ -441,7 +441,7 @@ BOOL xf_peer_activate(freerdp_peer* client) xfp->info->activePeerCount++; xfp->monitorThread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) xf_update_thread, (void*) client, 0, NULL); + (LPTHREAD_START_ROUTINE) x11_shadow_update_thread, (void*) client, 0, NULL); return TRUE; } @@ -456,7 +456,7 @@ const char* makecert_argv[4] = int makecert_argc = (sizeof(makecert_argv) / sizeof(char*)); -int xf_generate_certificate(rdpSettings* settings) +int x11_shadow_generate_certificate(rdpSettings* settings) { char* server_file_path; MAKECERT_CONTEXT* context; @@ -492,7 +492,7 @@ int xf_generate_certificate(rdpSettings* settings) return 0; } -static void* xf_peer_main_loop(void* arg) +static void* x11_shadow_peer_main_loop(void* arg) { int i; int fds; @@ -510,11 +510,11 @@ static void* xf_peer_main_loop(void* arg) fprintf(stderr, "We've got a client %s\n", client->hostname); - xf_peer_init(client); + x11_shadow_peer_init(client); xfp = (xfPeerContext*) client->context; settings = client->settings; - xf_generate_certificate(settings); + x11_shadow_generate_certificate(settings); settings->RemoteFxCodec = TRUE; settings->ColorDepth = 32; @@ -523,11 +523,11 @@ static void* xf_peer_main_loop(void* arg) settings->TlsSecurity = TRUE; settings->RdpSecurity = FALSE; - client->Capabilities = xf_peer_capabilities; - client->PostConnect = xf_peer_post_connect; - client->Activate = xf_peer_activate; + client->Capabilities = x11_shadow_peer_capabilities; + client->PostConnect = x11_shadow_peer_post_connect; + client->Activate = x11_shadow_peer_activate; - xf_input_register_callbacks(client->input); + x11_shadow_input_register_callbacks(client->input); client->Initialize(client); @@ -541,7 +541,7 @@ static void* xf_peer_main_loop(void* arg) break; } - if (xf_peer_get_fds(client, rfds, &rcount) != TRUE) + if (x11_shadow_peer_get_fds(client, rfds, &rcount) != TRUE) { fprintf(stderr, "Failed to get xfreerdp file descriptor\n"); break; @@ -585,7 +585,7 @@ static void* xf_peer_main_loop(void* arg) break; } - if ((xf_peer_check_fds(client)) != TRUE) + if ((x11_shadow_peer_check_fds(client)) != TRUE) { fprintf(stderr, "Failed to check xfreerdp file descriptor\n"); break; @@ -604,9 +604,9 @@ static void* xf_peer_main_loop(void* arg) return NULL; } -void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) +void x11_shadow_peer_accepted(freerdp_listener* instance, freerdp_peer* client) { HANDLE thread; - thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_peer_main_loop, client, 0, NULL); + thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) x11_shadow_peer_main_loop, client, 0, NULL); } diff --git a/server/shadow/X11/x11_input.c b/server/shadow/X11/x11_input.c index 314886b21..2fab1124e 100644 --- a/server/shadow/X11/x11_input.c +++ b/server/shadow/X11/x11_input.c @@ -30,7 +30,7 @@ #include "x11_shadow.h" -int xf_cursor_init(xfInfo* xfi) +int x11_shadow_cursor_init(xfInfo* xfi) { #ifdef WITH_XFIXES int event; @@ -50,12 +50,12 @@ int xf_cursor_init(xfInfo* xfi) return 0; } -void xf_input_synchronize_event(rdpInput* input, UINT32 flags) +void x11_shadow_input_synchronize_event(rdpInput* input, UINT32 flags) { fprintf(stderr, "Client sent a synchronize event (flags:0x%X)\n", flags); } -void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) +void x11_shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { #ifdef WITH_XTEST DWORD vkcode; @@ -87,12 +87,12 @@ void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) #endif } -void xf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) +void x11_shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { fprintf(stderr, "Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); } -void xf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +void x11_shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { #ifdef WITH_XTEST xfPeerContext* xfp = (xfPeerContext*) input->context; @@ -137,7 +137,7 @@ void xf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) #endif } -void xf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +void x11_shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { #ifdef WITH_XTEST xfPeerContext* xfp = (xfPeerContext*) input->context; @@ -163,11 +163,11 @@ void xf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT #endif } -void xf_input_register_callbacks(rdpInput* input) +void x11_shadow_input_register_callbacks(rdpInput* input) { - input->SynchronizeEvent = xf_input_synchronize_event; - input->KeyboardEvent = xf_input_keyboard_event; - input->UnicodeKeyboardEvent = xf_input_unicode_keyboard_event; - input->MouseEvent = xf_input_mouse_event; - input->ExtendedMouseEvent = xf_input_extended_mouse_event; + input->SynchronizeEvent = x11_shadow_input_synchronize_event; + input->KeyboardEvent = x11_shadow_input_keyboard_event; + input->UnicodeKeyboardEvent = x11_shadow_input_unicode_keyboard_event; + input->MouseEvent = x11_shadow_input_mouse_event; + input->ExtendedMouseEvent = x11_shadow_input_extended_mouse_event; } diff --git a/server/shadow/X11/x11_shadow.c b/server/shadow/X11/x11_shadow.c index 749b0759f..d0987cc01 100644 --- a/server/shadow/X11/x11_shadow.c +++ b/server/shadow/X11/x11_shadow.c @@ -135,7 +135,7 @@ xfServer* x11_shadow_server_new(int argc, char** argv) if (server) { server->listener = freerdp_listener_new(); - server->listener->PeerAccepted = xf_peer_accepted; + server->listener->PeerAccepted = x11_shadow_peer_accepted; } signal(SIGPIPE, SIG_IGN); diff --git a/server/shadow/X11/x11_shadow.h b/server/shadow/X11/x11_shadow.h index 2f45ec7a4..a3db03488 100644 --- a/server/shadow/X11/x11_shadow.h +++ b/server/shadow/X11/x11_shadow.h @@ -24,8 +24,8 @@ #include #include -typedef struct xf_info xfInfo; -typedef struct xf_server xfServer; +typedef struct x11_shadow_info xfInfo; +typedef struct x11_shadow_server xfServer; #ifdef __cplusplus extern "C" { @@ -73,7 +73,7 @@ FREERDP_API void x11_shadow_server_free(xfServer* server); #include #endif -struct xf_info +struct x11_shadow_info { int bpp; int xfds; @@ -108,7 +108,7 @@ struct xf_info #endif }; -struct xf_server +struct x11_shadow_server { DWORD port; HANDLE thread; @@ -128,7 +128,7 @@ struct xf_server #include #include -typedef struct xf_peer_context xfPeerContext; +typedef struct x11_shadow_peer_context xfPeerContext; #define PeerEvent_Base 0 @@ -136,7 +136,7 @@ typedef struct xf_peer_context xfPeerContext; #define PeerEvent_EncodeRegion 1 -struct xf_peer_context +struct x11_shadow_peer_context { rdpContext _p; @@ -151,23 +151,23 @@ struct xf_peer_context RFX_CONTEXT* rfx_context; }; -void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); +void x11_shadow_peer_accepted(freerdp_listener* instance, freerdp_peer* client); void* x11_shadow_server_thread(void* param); -void* xf_update_thread(void* param); +void* x11_shadow_update_thread(void* param); -int xf_cursor_init(xfInfo* xfi); +int x11_shadow_cursor_init(xfInfo* xfi); -XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height); -void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height); -int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height); +XImage* x11_shadow_snapshot(xfPeerContext* xfp, int x, int y, int width, int height); +void x11_shadow_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height); +int x11_shadow_update_encode(freerdp_peer* client, int x, int y, int width, int height); -void xf_input_synchronize_event(rdpInput* input, UINT32 flags); -void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); -void xf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); -void xf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); -void xf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); -void xf_input_register_callbacks(rdpInput* input); +void x11_shadow_input_synchronize_event(rdpInput* input, UINT32 flags); +void x11_shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); +void x11_shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); +void x11_shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); +void x11_shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); +void x11_shadow_input_register_callbacks(rdpInput* input); #endif /* FREERDP_SHADOW_SERVER_X11_H */ diff --git a/server/shadow/X11/x11_update.c b/server/shadow/X11/x11_update.c index c6b499cdd..95da598cb 100644 --- a/server/shadow/X11/x11_update.c +++ b/server/shadow/X11/x11_update.c @@ -29,7 +29,7 @@ #include "x11_shadow.h" -XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height) +XImage* x11_shadow_snapshot(xfPeerContext* xfp, int x, int y, int width, int height) { XImage* image; xfInfo* xfi = xfp->info; @@ -47,7 +47,7 @@ XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height) return image; } -void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height) +void x11_shadow_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height) { XRectangle region; xfInfo* xfi = xfp->info; @@ -63,7 +63,7 @@ void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int #endif } -int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height) +int x11_shadow_update_encode(freerdp_peer* client, int x, int y, int width, int height) { wStream* s; BYTE* data; @@ -101,7 +101,7 @@ int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height) rect.width = width; rect.height = height; - image = xf_snapshot(xfp, x, y, width, height); + image = x11_shadow_snapshot(xfp, x, y, width, height); data = (BYTE*) image->data; data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel / 8)]; @@ -121,7 +121,7 @@ int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height) rect.width = width; rect.height = height; - image = xf_snapshot(xfp, x, y, width, height); + image = x11_shadow_snapshot(xfp, x, y, width, height); data = (BYTE*) image->data; @@ -146,7 +146,7 @@ int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height) return 0; } -void* xf_update_thread(void* param) +void* x11_shadow_update_thread(void* param) { xfInfo* xfi; HANDLE event; @@ -184,9 +184,9 @@ void* xf_update_thread(void* param) width = notify->area.width; height = notify->area.height; - if (xf_update_encode(client, x, y, width, height) >= 0) + if (x11_shadow_update_encode(client, x, y, width, height) >= 0) { - xf_xdamage_subtract_region(xfp, x, y, width, height); + x11_shadow_xdamage_subtract_region(xfp, x, y, width, height); SetEvent(xfp->updateReadyEvent); diff --git a/server/shadow/shadow.c b/server/shadow/shadow.c index cc1e9af4d..66d3be4cb 100644 --- a/server/shadow/shadow.c +++ b/server/shadow/shadow.c @@ -1,6 +1,5 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Shadow Server * * Copyright 2014 Marc-Andre Moreau * @@ -27,16 +26,44 @@ void* shadow_server_thread(void* param) { + DWORD status; + DWORD nCount; + HANDLE events[32]; + rdpShadowServer* server; + freerdp_listener* listener; + + server = (rdpShadowServer*) param; + listener = (freerdp_listener*) server->listener; + + while (1) + { + nCount = 0; + + if (listener->GetEventHandles(listener, events, &nCount) < 0) + { + fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); + break; + } + + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (!listener->CheckFileDescriptor(listener)) + { + fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + break; + } + } + + listener->Close(listener); + ExitThread(0); return NULL; } -int shadow_server_start(xfServer* server) +int shadow_server_start(rdpShadowServer* server) { - server->thread = NULL; - - if (server->listener->Open(server->listener, NULL, 3389)) + if (server->listener->Open(server->listener, NULL, server->port)) { server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) shadow_server_thread, (void*) server, 0, NULL); @@ -45,7 +72,7 @@ int shadow_server_start(xfServer* server) return 0; } -int shadow_server_stop(xfServer* server) +int shadow_server_stop(rdpShadowServer* server) { if (server->thread) { @@ -59,27 +86,29 @@ int shadow_server_stop(xfServer* server) return 0; } -HANDLE shadow_server_get_thread(xfServer* server) +HANDLE shadow_server_get_thread(rdpShadowServer* server) { return server->thread; } -xfServer* shadow_server_new(int argc, char** argv) +rdpShadowServer* shadow_server_new(int argc, char** argv) { - xfServer* server; + rdpShadowServer* server; - server = (xfServer*) malloc(sizeof(xfServer)); + server = (rdpShadowServer*) malloc(sizeof(rdpShadowServer)); if (server) { + server->port = 3389; + server->listener = freerdp_listener_new(); - server->listener->PeerAccepted = NULL; + server->listener->PeerAccepted = shadow_client_accepted; } return server; } -void shadow_server_free(xfServer* server) +void shadow_server_free(rdpShadowServer* server) { if (server) { @@ -91,9 +120,11 @@ void shadow_server_free(xfServer* server) int main(int argc, char* argv[]) { HANDLE thread; - xfServer* server; DWORD dwExitCode; +#if 0 + xfServer* server; + server = x11_shadow_server_new(argc, argv); if (!server) @@ -108,6 +139,24 @@ int main(int argc, char* argv[]) GetExitCodeThread(thread, &dwExitCode); x11_shadow_server_free(server); +#else + rdpShadowServer* server; + + server = shadow_server_new(argc, argv); + + if (!server) + return 0; + + shadow_server_start(server); + + thread = shadow_server_get_thread(server); + + WaitForSingleObject(thread, INFINITE); + + GetExitCodeThread(thread, &dwExitCode); + + shadow_server_free(server); +#endif return 0; } diff --git a/server/shadow/shadow.h b/server/shadow/shadow.h index ef0f13638..56c0d57f4 100644 --- a/server/shadow/shadow.h +++ b/server/shadow/shadow.h @@ -24,14 +24,31 @@ #include #include +#include #include +typedef struct rdp_shadow_client rdpShadowClient; +typedef struct rdp_shadow_server rdpShadowServer; + +struct rdp_shadow_client +{ + rdpContext context; +}; + +struct rdp_shadow_server +{ + DWORD port; + HANDLE thread; + freerdp_listener* listener; +}; + #ifdef __cplusplus extern "C" { #endif - +void shadow_input_register_callbacks(rdpInput* input); +void shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client); #ifdef __cplusplus } diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c new file mode 100644 index 000000000..df1415d70 --- /dev/null +++ b/server/shadow/shadow_client.c @@ -0,0 +1,213 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include "shadow.h" + +void shadow_client_context_new(freerdp_peer* client, rdpShadowClient* context) +{ + +} + +void shadow_client_context_free(freerdp_peer* client, rdpShadowClient* context) +{ + +} + +void shadow_client_init(freerdp_peer* client) +{ + client->ContextSize = sizeof(rdpShadowClient); + client->ContextNew = (psPeerContextNew) shadow_client_context_new; + client->ContextFree = (psPeerContextFree) shadow_client_context_free; + freerdp_peer_context_new(client); +} + +BOOL shadow_client_get_fds(freerdp_peer* client, void** rfds, int* rcount) +{ + return TRUE; +} + +BOOL shadow_client_check_fds(freerdp_peer* client) +{ + return TRUE; +} + +BOOL shadow_client_capabilities(freerdp_peer* client) +{ + return TRUE; +} + +BOOL shadow_client_post_connect(freerdp_peer* client) +{ + fprintf(stderr, "Client %s is activated", client->hostname); + + if (client->settings->AutoLogonEnabled) + { + fprintf(stderr, " and wants to login automatically as %s\\%s", + client->settings->Domain ? client->settings->Domain : "", + client->settings->Username); + } + fprintf(stderr, "\n"); + + fprintf(stderr, "Client requested desktop: %dx%dx%d\n", + client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth); + + if (!client->settings->RemoteFxCodec) + { + fprintf(stderr, "Client does not support RemoteFX\n"); + return FALSE; + } + + //client->settings->DesktopWidth = 1024; + //client->settings->DesktopHeight = 768; + + client->update->DesktopResize(client->update->context); + + return TRUE; +} + +BOOL shadow_client_activate(freerdp_peer* client) +{ + return TRUE; +} + +static const char* makecert_argv[4] = +{ + "makecert", + "-rdp", + "-live", + "-silent" +}; + +static int makecert_argc = (sizeof(makecert_argv) / sizeof(char*)); + +int shadow_generate_certificate(rdpSettings* settings) +{ + char* serverFilePath; + MAKECERT_CONTEXT* context; + + serverFilePath = GetCombinedPath(settings->ConfigPath, "server"); + + if (!PathFileExistsA(serverFilePath)) + CreateDirectoryA(serverFilePath, 0); + + settings->CertificateFile = GetCombinedPath(serverFilePath, "server.crt"); + settings->PrivateKeyFile = GetCombinedPath(serverFilePath, "server.key"); + + if ((!PathFileExistsA(settings->CertificateFile)) || + (!PathFileExistsA(settings->PrivateKeyFile))) + { + context = makecert_context_new(); + + makecert_context_process(context, makecert_argc, (char**) makecert_argv); + + makecert_context_set_output_file_name(context, "server"); + + if (!PathFileExistsA(settings->CertificateFile)) + makecert_context_output_certificate_file(context, serverFilePath); + + if (!PathFileExistsA(settings->PrivateKeyFile)) + makecert_context_output_private_key_file(context, serverFilePath); + + makecert_context_free(context); + } + + free(serverFilePath); + + return 0; +} + +void* shadow_client_thread(void* param) +{ + DWORD status; + DWORD nCount; + HANDLE events[32]; + HANDLE ClientEvent; + rdpSettings* settings; + rdpShadowClient* context; + freerdp_peer* client = (freerdp_peer*) param; + + shadow_client_init(client); + + settings = client->settings; + context = (rdpShadowClient*) client->context; + + shadow_generate_certificate(settings); + + settings->RemoteFxCodec = TRUE; + settings->ColorDepth = 32; + + settings->NlaSecurity = FALSE; + settings->TlsSecurity = TRUE; + settings->RdpSecurity = FALSE; + + client->Capabilities = shadow_client_capabilities; + client->PostConnect = shadow_client_post_connect; + client->Activate = shadow_client_activate; + + shadow_input_register_callbacks(client->input); + + client->Initialize(client); + + ClientEvent = client->GetEventHandle(client); + + while (1) + { + nCount = 0; + events[nCount++] = ClientEvent; + + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0) + { + if (!client->CheckFileDescriptor(client)) + { + fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + break; + } + } + } + + client->Disconnect(client); + + freerdp_peer_context_free(client); + freerdp_peer_free(client); + + ExitThread(0); + + return NULL; +} + +void shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client) +{ + HANDLE thread; + + thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) shadow_client_thread, client, 0, NULL); +} diff --git a/server/shadow/shadow_input.c b/server/shadow/shadow_input.c new file mode 100644 index 000000000..7f7ee00ff --- /dev/null +++ b/server/shadow/shadow_input.c @@ -0,0 +1,54 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "shadow.h" + +void shadow_input_synchronize_event(rdpInput* input, UINT32 flags) +{ + +} + +void shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) +{ + +} + +void shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) +{ + +} + +void shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +{ + +} + +void shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +{ + +} + +void shadow_input_register_callbacks(rdpInput* input) +{ + input->SynchronizeEvent = shadow_input_synchronize_event; + input->KeyboardEvent = shadow_input_keyboard_event; + input->UnicodeKeyboardEvent = shadow_input_unicode_keyboard_event; + input->MouseEvent = shadow_input_mouse_event; + input->ExtendedMouseEvent = shadow_input_extended_mouse_event; +} + diff --git a/server/shadow/shadow_update.c b/server/shadow/shadow_update.c new file mode 100644 index 000000000..e69de29bb