mirror of https://github.com/FreeRDP/FreeRDP
shadow: start hooking X11 code as subsystem
This commit is contained in:
parent
7caf48bcf4
commit
8ae00f7385
|
@ -58,6 +58,7 @@ struct rdp_freerdp_peer
|
|||
rdpUpdate* update;
|
||||
rdpSettings* settings;
|
||||
|
||||
void* ContextExtra;
|
||||
size_t ContextSize;
|
||||
psPeerContextNew ContextNew;
|
||||
psPeerContextFree ContextFree;
|
||||
|
|
|
@ -23,7 +23,27 @@
|
|||
#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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
server = (x11ShadowServer*) client->context;
|
||||
context->server = server;
|
||||
client = (x11ShadowClient*) calloc(1, sizeof(x11ShadowClient));
|
||||
|
||||
if (!client)
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
client->rfx_context = rfx_context_new(TRUE);
|
||||
client->rfx_context->mode = RLGR3;
|
||||
client->rfx_context->width = server->width;
|
||||
client->rfx_context->height = server->height;
|
||||
|
||||
rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
rfx_context_set_pixel_format(client->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
|
||||
context->s = Stream_New(NULL, 65536);
|
||||
Stream_Clear(context->s);
|
||||
client->s = Stream_New(NULL, 65536);
|
||||
Stream_Clear(client->s);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
void x11_shadow_peer_context_free(freerdp_peer* client, x11ShadowClient* context)
|
||||
void x11_shadow_client_free(x11ShadowClient* client)
|
||||
{
|
||||
x11ShadowServer* server;
|
||||
|
||||
if (context)
|
||||
{
|
||||
server = context->server;
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
if (server->display)
|
||||
XCloseDisplay(server->display);
|
||||
server = client->server;
|
||||
|
||||
Stream_Free(context->s, TRUE);
|
||||
rfx_context_free(context->rfx_context);
|
||||
}
|
||||
}
|
||||
if (server->display)
|
||||
XCloseDisplay(server->display);
|
||||
|
||||
void x11_shadow_peer_init(freerdp_peer* 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;
|
||||
}
|
||||
|
||||
client->settings->DesktopWidth = server->width;
|
||||
client->settings->DesktopHeight = server->height;
|
||||
|
||||
client->update->DesktopResize(client->update->context);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -29,114 +29,14 @@
|
|||
|
||||
#include "x11_shadow.h"
|
||||
|
||||
void* x11_shadow_server_thread(void* param)
|
||||
{
|
||||
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;
|
||||
|
||||
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* x11_shadow_server_new(rdpShadowServer* rdp)
|
||||
{
|
||||
x11ShadowServer* server;
|
||||
|
||||
server = (x11ShadowServer*) malloc(sizeof(x11ShadowServer));
|
||||
server = (x11ShadowServer*) calloc(1, 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);
|
||||
}
|
||||
|
|
|
@ -19,33 +19,23 @@
|
|||
#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
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
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 <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
|
||||
|
||||
void* x11_shadow_server_thread(void* param);
|
||||
FREERDP_API x11ShadowServer* x11_shadow_server_new(rdpShadowServer* rdp);
|
||||
FREERDP_API void x11_shadow_server_free(x11ShadowServer* server);
|
||||
|
||||
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 */
|
||||
|
|
|
@ -22,18 +22,14 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -20,28 +20,9 @@
|
|||
#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" {
|
||||
|
|
|
@ -30,55 +30,52 @@
|
|||
|
||||
#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;
|
||||
|
||||
server = (rdpShadowServer*) peer->ContextExtra;
|
||||
client->server = server;
|
||||
|
||||
client->ext = x11_shadow_client_new(client);
|
||||
}
|
||||
|
||||
void shadow_client_context_free(freerdp_peer* client, rdpShadowClient* context)
|
||||
void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client)
|
||||
{
|
||||
|
||||
x11_shadow_client_free(client->ext);
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) shadow_client_thread, client, 0, NULL);
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue