shadow: start hooking X11 code as subsystem
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 11 Jul 2014 23:30:40 +0000 (19:30 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 11 Jul 2014 23:30:40 +0000 (19:30 -0400)
include/freerdp/peer.h
include/freerdp/server/shadow.h
libfreerdp/core/listener.c
libfreerdp/core/peer.c
server/shadow/X11/x11_client.c
server/shadow/X11/x11_shadow.c
server/shadow/X11/x11_shadow.h
server/shadow/shadow.c
server/shadow/shadow.h
server/shadow/shadow_client.c

index 4fbe75b..1fba990 100644 (file)
@@ -58,6 +58,7 @@ struct rdp_freerdp_peer
        rdpUpdate* update;
        rdpSettings* settings;
 
+       void* ContextExtra;
        size_t ContextSize;
        psPeerContextNew ContextNew;
        psPeerContextFree ContextFree;
index 98b7d6b..08a0a80 100644 (file)
 #include <freerdp/api.h>
 #include <freerdp/types.h>
 
+#include <freerdp/listener.h>
 
+typedef struct rdp_shadow_client rdpShadowClient;
+typedef struct rdp_shadow_server rdpShadowServer;
+
+struct rdp_shadow_client
+{
+       rdpContext context;
+       rdpShadowServer* server;
+
+       void* ext;
+};
+
+struct rdp_shadow_server
+{
+       DWORD port;
+       HANDLE thread;
+       freerdp_listener* listener;
+
+       void* ext;
+};
 
 #endif /* FREERDP_SERVER_SHADOW_H */
 
index e37c4c8..2164267 100644 (file)
@@ -346,8 +346,10 @@ freerdp_listener* freerdp_listener_new(void)
        freerdp_listener* instance;
        rdpListener* listener;
 
-       instance = (freerdp_listener*) malloc(sizeof(freerdp_listener));
-       ZeroMemory(instance, sizeof(freerdp_listener));
+       instance = (freerdp_listener*) calloc(1, sizeof(freerdp_listener));
+
+       if (!instance)
+               return NULL;
 
        instance->Open = freerdp_listener_open;
        instance->OpenLocal = freerdp_listener_open_local;
@@ -356,8 +358,10 @@ freerdp_listener* freerdp_listener_new(void)
        instance->CheckFileDescriptor = freerdp_listener_check_fds;
        instance->Close = freerdp_listener_close;
 
-       listener = (rdpListener*) malloc(sizeof(rdpListener));
-       ZeroMemory(listener, sizeof(rdpListener));
+       listener = (rdpListener*) calloc(1, sizeof(rdpListener));
+
+       if (!listener)
+               return NULL;
 
        listener->instance = instance;
 
index 8b5ac3c..10b10ff 100644 (file)
@@ -431,7 +431,7 @@ void freerdp_peer_context_new(freerdp_peer* client)
 {
        rdpRdp* rdp;
 
-       client->context = (rdpContext *)calloc(1, client->ContextSize);
+       client->context = (rdpContext*) calloc(1, client->ContextSize);
 
        client->context->ServerMode = TRUE;
 
index 33f7aaf..2796ab0 100644 (file)
@@ -20,7 +20,6 @@
 #include "config.h"
 #endif
 
-#include <assert.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -28,6 +27,7 @@
 #include <unistd.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
+
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <sys/select.h>
@@ -169,7 +169,7 @@ int x11_shadow_xshm_init(x11ShadowServer* server)
        return 0;
 }
 
-void x11_shadow_peer_context_new(freerdp_peer* client, x11ShadowClient* context)
+x11ShadowClient* x11_shadow_client_new(rdpShadowClient* rdp)
 {
        int i;
        int pf_count;
@@ -180,9 +180,15 @@ void x11_shadow_peer_context_new(freerdp_peer* client, x11ShadowClient* context)
        XPixmapFormatValues* pf;
        XPixmapFormatValues* pfs;
        x11ShadowServer* server;
+       x11ShadowClient* client;
+
+       client = (x11ShadowClient*) calloc(1, sizeof(x11ShadowClient));
+
+       if (!client)
+               return NULL;
 
-       server = (x11ShadowServer*) client->context;
-       context->server = server;
+       server = (x11ShadowServer*) rdp->server->ext;
+       client->server = server;
 
        /**
         * Recent X11 servers drop support for shared pixmaps
@@ -279,78 +285,33 @@ void x11_shadow_peer_context_new(freerdp_peer* client, x11ShadowClient* context)
 
        freerdp_keyboard_init(0);
 
-       context->rfx_context = rfx_context_new(TRUE);
-       context->rfx_context->mode = RLGR3;
-       context->rfx_context->width = server->width;
-       context->rfx_context->height = server->height;
-
-       rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
-
-       context->s = Stream_New(NULL, 65536);
-       Stream_Clear(context->s);
-}
-
-void x11_shadow_peer_context_free(freerdp_peer* client, x11ShadowClient* context)
-{
-       x11ShadowServer* server;
+       client->rfx_context = rfx_context_new(TRUE);
+       client->rfx_context->mode = RLGR3;
+       client->rfx_context->width = server->width;
+       client->rfx_context->height = server->height;
 
-       if (context)
-       {
-               server = context->server;
+       rfx_context_set_pixel_format(client->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
 
-               if (server->display)
-                       XCloseDisplay(server->display);
+       client->s = Stream_New(NULL, 65536);
+       Stream_Clear(client->s);
 
-               Stream_Free(context->s, TRUE);
-               rfx_context_free(context->rfx_context);
-       }
+       return client;
 }
 
-void x11_shadow_peer_init(freerdp_peer* client)
+void x11_shadow_client_free(x11ShadowClient* client)
 {
-       client->ContextSize = sizeof(x11ShadowClient);
-       client->ContextNew = (psPeerContextNew) x11_shadow_peer_context_new;
-       client->ContextFree = (psPeerContextFree) x11_shadow_peer_context_free;
-       freerdp_peer_context_new(client);
-}
-
-BOOL x11_shadow_peer_capabilities(freerdp_peer* client)
-{
-       return TRUE;
-}
-
-BOOL x11_shadow_peer_post_connect(freerdp_peer* client)
-{
-       x11ShadowClient* context;
        x11ShadowServer* server;
 
-       context = (x11ShadowClient*) client->context;
-       server = context->server;
-
-       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;
-       }
+       if (!client)
+               return;
 
-       client->settings->DesktopWidth = server->width;
-       client->settings->DesktopHeight = server->height;
+       server = client->server;
 
-       client->update->DesktopResize(client->update->context);
+       if (server->display)
+               XCloseDisplay(server->display);
 
-       return TRUE;
+       Stream_Free(client->s, TRUE);
+       rfx_context_free(client->rfx_context);
 }
 
 BOOL x11_shadow_peer_activate(freerdp_peer* client)
@@ -363,163 +324,8 @@ BOOL x11_shadow_peer_activate(freerdp_peer* client)
 
        server->activePeerCount++;
 
-       context->monitorThread = CreateThread(NULL, 0,
-                       (LPTHREAD_START_ROUTINE) x11_shadow_update_thread, (void*) client, 0, NULL);
+       context->monitorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
+                       x11_shadow_update_thread, (void*) client, 0, NULL);
 
        return TRUE;
 }
-
-const char* makecert_argv[4] =
-{
-       "makecert",
-       "-rdp",
-       "-live",
-       "-silent"
-};
-
-int makecert_argc = (sizeof(makecert_argv) / sizeof(char*));
-
-int x11_shadow_generate_certificate(rdpSettings* settings)
-{
-       char* server_file_path;
-       MAKECERT_CONTEXT* context;
-
-       server_file_path = GetCombinedPath(settings->ConfigPath, "server");
-
-       if (!PathFileExistsA(server_file_path))
-               CreateDirectoryA(server_file_path, 0);
-
-       settings->CertificateFile = GetCombinedPath(server_file_path, "server.crt");
-       settings->PrivateKeyFile = GetCombinedPath(server_file_path, "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, server_file_path);
-
-               if (!PathFileExistsA(settings->PrivateKeyFile))
-                       makecert_context_output_private_key_file(context, server_file_path);
-
-               makecert_context_free(context);
-       }
-
-       free(server_file_path);
-
-       return 0;
-}
-
-static void* x11_shadow_client_thread(void* arg)
-{
-       int i;
-       int fds;
-       int max_fds;
-       int rcount;
-       void* rfds[32];
-       fd_set rfds_set;
-       rdpSettings* settings;
-       x11ShadowClient* xfp;
-       struct timeval timeout;
-       freerdp_peer* client = (freerdp_peer*) arg;
-
-       ZeroMemory(rfds, sizeof(rfds));
-       ZeroMemory(&timeout, sizeof(struct timeval));
-
-       fprintf(stderr, "We've got a client %s\n", client->hostname);
-
-       x11_shadow_peer_init(client);
-
-       xfp = (x11ShadowClient*) client->context;
-       settings = client->settings;
-
-       x11_shadow_generate_certificate(settings);
-
-       settings->RemoteFxCodec = TRUE;
-       settings->ColorDepth = 32;
-
-       settings->NlaSecurity = FALSE;
-       settings->TlsSecurity = TRUE;
-       settings->RdpSecurity = FALSE;
-
-       client->Capabilities = x11_shadow_peer_capabilities;
-       client->PostConnect = x11_shadow_peer_post_connect;
-       client->Activate = x11_shadow_peer_activate;
-
-       x11_shadow_input_register_callbacks(client->input);
-
-       client->Initialize(client);
-
-       while (1)
-       {
-               rcount = 0;
-
-               if (client->GetFileDescriptor(client, rfds, &rcount) != TRUE)
-               {
-                       fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
-                       break;
-               }
-
-               max_fds = 0;
-               FD_ZERO(&rfds_set);
-
-               for (i = 0; i < rcount; i++)
-               {
-                       fds = (int)(long)(rfds[i]);
-
-                       if (fds > max_fds)
-                               max_fds = fds;
-
-                       FD_SET(fds, &rfds_set);
-               }
-
-               if (max_fds == 0)
-                       break;
-
-               timeout.tv_sec = 0;
-               timeout.tv_usec = 100;
-
-               if (select(max_fds + 1, &rfds_set, NULL, NULL, &timeout) == -1)
-               {
-                       /* these are not really errors */
-                       if (!((errno == EAGAIN) ||
-                               (errno == EWOULDBLOCK) ||
-                               (errno == EINPROGRESS) ||
-                               (errno == EINTR))) /* signal occurred */
-                       {
-                               fprintf(stderr, "select failed\n");
-                               break;
-                       }
-               }
-
-               if (client->CheckFileDescriptor(client) != TRUE)
-               {
-                       //fprintf(stderr, "Failed to check freerdp file descriptor\n");
-                       //break;
-               }
-       }
-
-       fprintf(stderr, "Client %s disconnected.\n", client->hostname);
-
-       client->Disconnect(client);
-       
-       freerdp_peer_context_free(client);
-       freerdp_peer_free(client);
-
-       ExitThread(0);
-
-       return NULL;
-}
-
-void x11_shadow_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
-{
-       HANDLE thread;
-
-       thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
-                       x11_shadow_client_thread, client, 0, NULL);
-}
index 80fb00d..d599f42 100644 (file)
 
 #include "x11_shadow.h"
 
-void* x11_shadow_server_thread(void* param)
+x11ShadowServer* x11_shadow_server_new(rdpShadowServer* rdp)
 {
-       int i;
-       int fds;
-       int max_fds;
-       int rcount;
-       void* rfds[32];
-       fd_set rfds_set;
        x11ShadowServer* server;
-       freerdp_listener* listener;
 
-       server = (x11ShadowServer*) param;
-       listener = server->listener;
+       server = (x11ShadowServer*) calloc(1, sizeof(x11ShadowServer));
 
-       while (1)
-       {
-               rcount = 0;
-
-               ZeroMemory(rfds, sizeof(rfds));
-               if (listener->GetFileDescriptor(listener, rfds, &rcount) != TRUE)
-               {
-                       fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
-                       break;
-               }
-
-               max_fds = 0;
-               FD_ZERO(&rfds_set);
-
-               for (i = 0; i < rcount; i++)
-               {
-                       fds = (int)(long)(rfds[i]);
-
-                       if (fds > max_fds)
-                               max_fds = fds;
-
-                       FD_SET(fds, &rfds_set);
-               }
-
-               if (max_fds == 0)
-                       break;
-
-               if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1)
-               {
-                       /* these are not really errors */
-                       if (!((errno == EAGAIN) ||
-                               (errno == EWOULDBLOCK) ||
-                               (errno == EINPROGRESS) ||
-                               (errno == EINTR))) /* signal occurred */
-                       {
-                               fprintf(stderr, "select failed\n");
-                               break;
-                       }
-               }
-
-               if (listener->CheckFileDescriptor(listener) != TRUE)
-               {
-                       fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
-                       break;
-               }
-       }
-
-       ExitThread(0);
-
-       return NULL;
-}
-
-int x11_shadow_server_start(x11ShadowServer* server)
-{
-       server->thread = NULL;
-
-       if (server->listener->Open(server->listener, NULL, 3389))
-       {
-               server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
-                               x11_shadow_server_thread, (void*) server, 0, NULL);
-       }
-
-       return 0;
-}
-
-int x11_shadow_server_stop(x11ShadowServer* server)
-{
-       if (server->thread)
-       {
-               TerminateThread(server->thread, 0);
-               WaitForSingleObject(server->thread, INFINITE);
-               CloseHandle(server->thread);
-       
-               server->listener->Close(server->listener);
-       }
-       return 0;
-}
-
-HANDLE x11_shadow_server_get_thread(x11ShadowServer* server)
-{
-       return server->thread;
-}
-
-x11ShadowServer* x11_shadow_server_new(int argc, char** argv)
-{
-       x11ShadowServer* server;
-
-       server = (x11ShadowServer*) malloc(sizeof(x11ShadowServer));
-
-       if (server)
-       {
-               server->listener = freerdp_listener_new();
-               server->listener->PeerAccepted = x11_shadow_peer_accepted;
-       }
+       if (!server)
+               return NULL;
 
        signal(SIGPIPE, SIG_IGN);
 
@@ -145,9 +45,8 @@ x11ShadowServer* x11_shadow_server_new(int argc, char** argv)
 
 void x11_shadow_server_free(x11ShadowServer* server)
 {
-       if (server)
-       {
-               freerdp_listener_free(server->listener);
-               free(server);
-       }
+       if (!server)
+               return;
+
+       free(server);
 }
index f74f3e4..59783a0 100644 (file)
 #ifndef FREERDP_SHADOW_SERVER_X11_H
 #define FREERDP_SHADOW_SERVER_X11_H
 
-#include <winpr/crt.h>
-
-#include <freerdp/api.h>
-#include <freerdp/freerdp.h>
+#include <freerdp/server/shadow.h>
 
+typedef struct x11_shadow_client x11ShadowClient;
 typedef struct x11_shadow_server x11ShadowServer;
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-FREERDP_API int x11_shadow_server_start(x11ShadowServer* server);
-FREERDP_API int x11_shadow_server_stop(x11ShadowServer* server);
-
-FREERDP_API HANDLE x11_shadow_server_get_thread(x11ShadowServer* server);
-
-FREERDP_API x11ShadowServer* x11_shadow_server_new(int argc, char** argv);
-FREERDP_API void x11_shadow_server_free(x11ShadowServer* server);
-
-#ifdef __cplusplus
-}
-#endif
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+#include <winpr/stream.h>
+#include <winpr/collections.h>
 
-#include <freerdp/api.h>
-#include <freerdp/freerdp.h>
+#include <freerdp/gdi/gdi.h>
+#include <freerdp/gdi/dc.h>
+#include <freerdp/gdi/region.h>
+#include <freerdp/codec/rfx.h>
 #include <freerdp/listener.h>
-#include <freerdp/codec/color.h>
+#include <freerdp/utils/stopwatch.h>
 
 #include <X11/Xlib.h>
 
@@ -103,21 +93,6 @@ struct x11_shadow_server
 #endif
 };
 
-#include <winpr/crt.h>
-#include <winpr/synch.h>
-#include <winpr/thread.h>
-#include <winpr/stream.h>
-#include <winpr/collections.h>
-
-#include <freerdp/gdi/gdi.h>
-#include <freerdp/gdi/dc.h>
-#include <freerdp/gdi/region.h>
-#include <freerdp/codec/rfx.h>
-#include <freerdp/listener.h>
-#include <freerdp/utils/stopwatch.h>
-
-typedef struct x11_shadow_client x11ShadowClient;
-
 struct x11_shadow_client
 {
        rdpContext _p;
@@ -129,16 +104,24 @@ struct x11_shadow_client
        x11ShadowServer* server;
 };
 
-void x11_shadow_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+FREERDP_API x11ShadowServer* x11_shadow_server_new(rdpShadowServer* rdp);
+FREERDP_API void x11_shadow_server_free(x11ShadowServer* server);
 
-void* x11_shadow_server_thread(void* param);
+x11ShadowClient* x11_shadow_client_new(rdpShadowClient* rdp);
+void x11_shadow_client_free(x11ShadowClient* client);
 
 void* x11_shadow_update_thread(void* param);
 
 int x11_shadow_cursor_init(x11ShadowServer* server);
-
 void x11_shadow_input_register_callbacks(rdpInput* input);
-
 int x11_shadow_update_encode(freerdp_peer* client, int x, int y, int width, int height);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* FREERDP_SHADOW_SERVER_X11_H */
index 9c81d88..42698cc 100644 (file)
 
 #include "shadow.h"
 
-#include "X11/x11_shadow.h"
-
-void* shadow_server_thread(void* param)
+void* shadow_server_thread(rdpShadowServer* server)
 {
        DWORD status;
        DWORD nCount;
        HANDLE events[32];
-       rdpShadowServer* server;
        freerdp_listener* listener;
 
-       server = (rdpShadowServer*) param;
-       listener = (freerdp_listener*) server->listener;
+       listener = server->listener;
 
        while (1)
        {
@@ -95,51 +91,45 @@ rdpShadowServer* shadow_server_new(int argc, char** argv)
 {
        rdpShadowServer* server;
 
-       server = (rdpShadowServer*) malloc(sizeof(rdpShadowServer));
+       server = (rdpShadowServer*) calloc(1, sizeof(rdpShadowServer));
 
-       if (server)
-       {
-               server->port = 3389;
+       if (!server)
+               return NULL;
 
-               server->listener = freerdp_listener_new();
-               server->listener->PeerAccepted = shadow_client_accepted;
-       }
+       server->port = 3389;
+
+       server->listener = freerdp_listener_new();
+
+       if (!server->listener)
+               return NULL;
+
+       server->listener->info = (void*) server;
+       server->listener->PeerAccepted = shadow_client_accepted;
+
+       server->ext = x11_shadow_server_new(server);
+
+       if (!server->ext)
+               return NULL;
 
        return server;
 }
 
 void shadow_server_free(rdpShadowServer* server)
 {
-       if (server)
-       {
-               freerdp_listener_free(server->listener);
-               free(server);
-       }
+       if (!server)
+               return;
+
+       freerdp_listener_free(server->listener);
+
+       x11_shadow_server_free(server->ext);
+
+       free(server);
 }
 
 int main(int argc, char* argv[])
 {
        HANDLE thread;
        DWORD dwExitCode;
-
-#if 1
-       x11ShadowServer* server;
-
-       server = x11_shadow_server_new(argc, argv);
-
-       if (!server)
-               return 0;
-
-       x11_shadow_server_start(server);
-
-       thread = x11_shadow_server_get_thread(server);
-
-       WaitForSingleObject(thread, INFINITE);
-
-       GetExitCodeThread(thread, &dwExitCode);
-
-       x11_shadow_server_free(server);
-#else
        rdpShadowServer* server;
 
        server = shadow_server_new(argc, argv);
@@ -156,7 +146,6 @@ int main(int argc, char* argv[])
        GetExitCodeThread(thread, &dwExitCode);
 
        shadow_server_free(server);
-#endif
 
        return 0;
 }
index 56c0d57..033e79f 100644 (file)
 #ifndef FREERDP_SHADOW_SERVER_H
 #define FREERDP_SHADOW_SERVER_H
 
-#include <winpr/crt.h>
-
-#include <freerdp/api.h>
-#include <freerdp/freerdp.h>
-#include <freerdp/listener.h>
-
 #include <freerdp/server/shadow.h>
 
-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;
-};
+#include "X11/x11_shadow.h"
 
 #ifdef __cplusplus
 extern "C" {
index df1415d..1947477 100644 (file)
 
 #include "shadow.h"
 
-void shadow_client_context_new(freerdp_peer* client, rdpShadowClient* context)
+void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
 {
+       rdpShadowServer* server;
 
-}
-
-void shadow_client_context_free(freerdp_peer* client, rdpShadowClient* context)
-{
+       server = (rdpShadowServer*) peer->ContextExtra;
+       client->server = server;
 
+       client->ext = x11_shadow_client_new(client);
 }
 
-void shadow_client_init(freerdp_peer* client)
+void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client)
 {
-       client->ContextSize = sizeof(rdpShadowClient);
-       client->ContextNew = (psPeerContextNew) shadow_client_context_new;
-       client->ContextFree = (psPeerContextFree) shadow_client_context_free;
-       freerdp_peer_context_new(client);
+       x11_shadow_client_free(client->ext);
 }
 
-BOOL shadow_client_get_fds(freerdp_peer* client, void** rfds, int* rcount)
+BOOL shadow_client_get_fds(freerdp_peer* peer, void** rfds, int* rcount)
 {
        return TRUE;
 }
 
-BOOL shadow_client_check_fds(freerdp_peer* client)
+BOOL shadow_client_check_fds(freerdp_peer* peer)
 {
        return TRUE;
 }
 
-BOOL shadow_client_capabilities(freerdp_peer* client)
+BOOL shadow_client_capabilities(freerdp_peer* peer)
 {
        return TRUE;
 }
 
-BOOL shadow_client_post_connect(freerdp_peer* client)
+BOOL shadow_client_post_connect(freerdp_peer* peer)
 {
-       fprintf(stderr, "Client %s is activated", client->hostname);
+       fprintf(stderr, "Client %s is activated", peer->hostname);
 
-       if (client->settings->AutoLogonEnabled)
+       if (peer->settings->AutoLogonEnabled)
        {
                fprintf(stderr, " and wants to login automatically as %s\\%s",
-                       client->settings->Domain ? client->settings->Domain : "",
-                       client->settings->Username);
+                       peer->settings->Domain ? peer->settings->Domain : "",
+                       peer->settings->Username);
        }
        fprintf(stderr, "\n");
 
        fprintf(stderr, "Client requested desktop: %dx%dx%d\n",
-               client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth);
+               peer->settings->DesktopWidth, peer->settings->DesktopHeight, peer->settings->ColorDepth);
 
-       if (!client->settings->RemoteFxCodec)
+       if (!peer->settings->RemoteFxCodec)
        {
                fprintf(stderr, "Client does not support RemoteFX\n");
                return FALSE;
@@ -87,12 +84,12 @@ BOOL shadow_client_post_connect(freerdp_peer* client)
        //client->settings->DesktopWidth = 1024;
        //client->settings->DesktopHeight = 768;
 
-       client->update->DesktopResize(client->update->context);
+       peer->update->DesktopResize(peer->update->context);
 
        return TRUE;
 }
 
-BOOL shadow_client_activate(freerdp_peer* client)
+BOOL shadow_client_activate(freerdp_peer* peer)
 {
        return TRUE;
 }
@@ -143,20 +140,17 @@ int shadow_generate_certificate(rdpSettings* settings)
        return 0;
 }
 
-void* shadow_client_thread(void* param)
+void* shadow_client_thread(rdpShadowClient* client)
 {
        DWORD status;
        DWORD nCount;
        HANDLE events[32];
        HANDLE ClientEvent;
+       freerdp_peer* peer;
        rdpSettings* settings;
-       rdpShadowClient* context;
-       freerdp_peer* client = (freerdp_peer*) param;
-
-       shadow_client_init(client);
 
-       settings = client->settings;
-       context = (rdpShadowClient*) client->context;
+       peer = ((rdpContext*) client)->peer;
+       settings = peer->settings;
 
        shadow_generate_certificate(settings);
 
@@ -167,15 +161,15 @@ void* shadow_client_thread(void* param)
        settings->TlsSecurity = TRUE;
        settings->RdpSecurity = FALSE;
 
-       client->Capabilities = shadow_client_capabilities;
-       client->PostConnect = shadow_client_post_connect;
-       client->Activate = shadow_client_activate;
+       peer->Capabilities = shadow_client_capabilities;
+       peer->PostConnect = shadow_client_post_connect;
+       peer->Activate = shadow_client_activate;
 
-       shadow_input_register_callbacks(client->input);
+       shadow_input_register_callbacks(peer->input);
 
-       client->Initialize(client);
+       peer->Initialize(peer);
 
-       ClientEvent = client->GetEventHandle(client);
+       ClientEvent = peer->GetEventHandle(peer);
 
        while (1)
        {
@@ -186,7 +180,7 @@ void* shadow_client_thread(void* param)
 
                if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0)
                {
-                       if (!client->CheckFileDescriptor(client))
+                       if (!peer->CheckFileDescriptor(peer))
                        {
                                fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
                                break;
@@ -194,20 +188,32 @@ void* shadow_client_thread(void* param)
                }
        }
 
-       client->Disconnect(client);
+       peer->Disconnect(peer);
        
-       freerdp_peer_context_free(client);
-       freerdp_peer_free(client);
+       freerdp_peer_context_free(peer);
+       freerdp_peer_free(peer);
 
        ExitThread(0);
 
        return NULL;
 }
 
-void shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client)
+void shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer)
 {
        HANDLE thread;
+       rdpShadowClient* client;
+       rdpShadowServer* server;
+
+       server = (rdpShadowServer*) listener->info;
+
+       peer->ContextExtra = (void*) server;
+       peer->ContextSize = sizeof(rdpShadowClient);
+       peer->ContextNew = (psPeerContextNew) shadow_client_context_new;
+       peer->ContextFree = (psPeerContextFree) shadow_client_context_free;
+       freerdp_peer_context_new(peer);
+
+       client = (rdpShadowClient*) peer->context;
 
-       thread = CreateThread(NULL, 0,
-                       (LPTHREAD_START_ROUTINE) shadow_client_thread, client, 0, NULL);
+       thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
+                       shadow_client_thread, client, 0, NULL);
 }