From 78520d51414344a1bc8e21176ce5c2e8efec9821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 15 Jul 2014 16:34:15 -0400 Subject: [PATCH] shadow: add basic server-side encomsp server --- channels/encomsp/client/CMakeLists.txt | 4 +- channels/encomsp/client/encomsp_main.c | 65 +++++++-- channels/encomsp/encomsp_common.c | 66 --------- channels/encomsp/server/CMakeLists.txt | 4 +- channels/encomsp/server/encomsp_main.c | 135 ++++++++++++------ include/freerdp/server/encomsp.h | 27 +++- include/freerdp/server/remdesk.h | 1 + server/shadow/CMakeLists.txt | 6 +- server/shadow/shadow_channels.c | 12 +- server/shadow/shadow_channels.h | 3 + server/shadow/shadow_encomsp.c | 108 ++++++++++++++ .../shadow/shadow_encomsp.h | 22 +-- server/shadow/shadow_remdesk.c | 35 +++++ server/shadow/shadow_remdesk.h | 37 +++++ server/shadow/{shadow.c => shadow_server.c} | 0 15 files changed, 372 insertions(+), 153 deletions(-) delete mode 100644 channels/encomsp/encomsp_common.c create mode 100644 server/shadow/shadow_encomsp.c rename channels/encomsp/encomsp_common.h => server/shadow/shadow_encomsp.h (62%) create mode 100644 server/shadow/shadow_remdesk.c create mode 100644 server/shadow/shadow_remdesk.h rename server/shadow/{shadow.c => shadow_server.c} (100%) diff --git a/channels/encomsp/client/CMakeLists.txt b/channels/encomsp/client/CMakeLists.txt index 89b2e1ed0..8842e5969 100644 --- a/channels/encomsp/client/CMakeLists.txt +++ b/channels/encomsp/client/CMakeLists.txt @@ -21,9 +21,7 @@ include_directories(..) set(${MODULE_PREFIX}_SRCS encomsp_main.c - encomsp_main.h - ../encomsp_common.c - ../encomsp_common.h) + encomsp_main.h) add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") diff --git a/channels/encomsp/client/encomsp_main.c b/channels/encomsp/client/encomsp_main.c index 3e2be2182..81bfbf111 100644 --- a/channels/encomsp/client/encomsp_main.c +++ b/channels/encomsp/client/encomsp_main.c @@ -26,10 +26,47 @@ #include -#include "encomsp_common.h" - #include "encomsp_main.h" +static int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE) + return -1; + + Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ + Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ + + return 1; +} + +static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ + Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ + + return 1; +} + +static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) +{ + ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING)); + + if (Stream_GetRemainingLength(s) < 2) + return -1; + + Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */ + + if (str->cchString > 1024) + return -1; + + if (Stream_GetRemainingLength(s) < (str->cchString * 2)) + return -1; + + Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ + + return 1; +} + EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp) { EncomspClientContext* pInterface; @@ -61,7 +98,7 @@ int encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) return 1; } -int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -102,7 +139,7 @@ int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ return 1; } -int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -147,7 +184,7 @@ int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENC return 1; } -int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -188,7 +225,7 @@ int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENC return 1; } -int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -234,7 +271,7 @@ int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ return 1; } -int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -275,7 +312,7 @@ int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ return 1; } -int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -316,7 +353,7 @@ int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORD return 1; } -int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -362,7 +399,7 @@ int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENC return 1; } -int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -405,7 +442,7 @@ int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENC return 1; } -int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -447,7 +484,7 @@ int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wS return 1; } -int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) +static int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) { wStream* s; encomspPlugin* encomsp; @@ -471,7 +508,7 @@ int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* cont return 1; } -int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -507,7 +544,7 @@ int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, return 1; } -int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; diff --git a/channels/encomsp/encomsp_common.c b/channels/encomsp/encomsp_common.c deleted file mode 100644 index 6f3d61cad..000000000 --- a/channels/encomsp/encomsp_common.c +++ /dev/null @@ -1,66 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Multiparty Virtual Channel - * - * 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 "encomsp_common.h" - -int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) -{ - if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE) - return -1; - - Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ - Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ - - return 1; -} - -int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) -{ - Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ - Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ - - return 1; -} - -int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) -{ - ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING)); - - if (Stream_GetRemainingLength(s) < 2) - return -1; - - Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */ - - if (str->cchString > 1024) - return -1; - - if (Stream_GetRemainingLength(s) < (str->cchString * 2)) - return -1; - - Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ - - return 1; -} diff --git a/channels/encomsp/server/CMakeLists.txt b/channels/encomsp/server/CMakeLists.txt index 1fe84d63e..4cb47966e 100644 --- a/channels/encomsp/server/CMakeLists.txt +++ b/channels/encomsp/server/CMakeLists.txt @@ -21,9 +21,7 @@ include_directories(..) set(${MODULE_PREFIX}_SRCS encomsp_main.c - encomsp_main.h - ../encomsp_common.c - ../encomsp_common.h) + encomsp_main.h) add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") diff --git a/channels/encomsp/server/encomsp_main.c b/channels/encomsp/server/encomsp_main.c index bab08d351..4e826cb21 100644 --- a/channels/encomsp/server/encomsp_main.c +++ b/channels/encomsp/server/encomsp_main.c @@ -25,10 +25,83 @@ #include #include -#include "encomsp_common.h" - #include "encomsp_main.h" +static int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE) + return -1; + + Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ + Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ + + return 1; +} + +static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ + Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ + + return 1; +} + +static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) +{ + ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING)); + + if (Stream_GetRemainingLength(s) < 2) + return -1; + + Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */ + + if (str->cchString > 1024) + return -1; + + if (Stream_GetRemainingLength(s) < (str->cchString * 2)) + return -1; + + Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ + + return 1; +} + +static int encomsp_recv_change_participant_control_level_pdu(EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + int beg, end; + ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu; + + beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; + + CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); + + if (Stream_GetRemainingLength(s) < 6) + return -1; + + Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ + Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ + + end = (int) Stream_GetPosition(s); + + if ((beg + header->Length) < end) + return -1; + + if ((beg + header->Length) > end) + { + if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + return -1; + + Stream_SetPosition(s, (beg + header->Length)); + } + + if (context->ChangeParticipantControlLevel) + { + return context->ChangeParticipantControlLevel(context, &pdu); + } + + return 1; +} + static int encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s) { int status = 1; @@ -41,55 +114,12 @@ static int encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s) printf("EncomspReceive: Type: %d Length: %d\n", header.Type, header.Length); - return 1; - -#if 0 switch (header.Type) { - case ODTYPE_FILTER_STATE_UPDATED: - status = encomsp_recv_filter_updated_pdu(context, s, &header); - break; - - case ODTYPE_APP_REMOVED: - status = encomsp_recv_application_removed_pdu(context, s, &header); - break; - - case ODTYPE_APP_CREATED: - status = encomsp_recv_application_created_pdu(context, s, &header); - break; - - case ODTYPE_WND_REMOVED: - status = encomsp_recv_window_removed_pdu(context, s, &header); - break; - - case ODTYPE_WND_CREATED: - status = encomsp_recv_window_created_pdu(context, s, &header); - break; - - case ODTYPE_WND_SHOW: - status = encomsp_recv_show_window_pdu(context, s, &header); - break; - - case ODTYPE_PARTICIPANT_REMOVED: - status = encomsp_recv_participant_removed_pdu(context, s, &header); - break; - - case ODTYPE_PARTICIPANT_CREATED: - status = encomsp_recv_participant_created_pdu(context, s, &header); - break; - case ODTYPE_PARTICIPANT_CTRL_CHANGED: status = encomsp_recv_change_participant_control_level_pdu(context, s, &header); break; - case ODTYPE_GRAPHICS_STREAM_PAUSED: - status = encomsp_recv_graphics_stream_paused_pdu(context, s, &header); - break; - - case ODTYPE_GRAPHICS_STREAM_RESUMED: - status = encomsp_recv_graphics_stream_resumed_pdu(context, s, &header); - break; - default: status = -1; break; @@ -97,7 +127,6 @@ static int encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s) if (status < 0) return -1; -#endif } return status; @@ -112,6 +141,7 @@ static void* encomsp_server_thread(void* arg) HANDLE events[8]; HANDLE ChannelEvent; DWORD BytesReturned; + ENCOMSP_ORDER_HEADER* header; EncomspServerContext* context; context = (EncomspServerContext*) arg; @@ -154,7 +184,18 @@ static void* encomsp_server_thread(void* arg) Stream_EnsureRemainingCapacity(s, BytesReturned); } - encomsp_server_receive_pdu(context, s); + if (Stream_GetPosition(s) >= ENCOMSP_ORDER_HEADER_SIZE) + { + header = (ENCOMSP_ORDER_HEADER*) Stream_Buffer(s); + + if (header->Length >= Stream_GetPosition(s)) + { + Stream_SealLength(s); + Stream_SetPosition(s, 0); + encomsp_server_receive_pdu(context, s); + Stream_SetPosition(s, 0); + } + } } Stream_Free(s, TRUE); diff --git a/include/freerdp/server/encomsp.h b/include/freerdp/server/encomsp.h index f692073b8..dd1f9eba9 100644 --- a/include/freerdp/server/encomsp.h +++ b/include/freerdp/server/encomsp.h @@ -24,7 +24,7 @@ #include #include -#include +#include /** * Server Interface @@ -36,13 +36,38 @@ typedef struct _encomsp_server_private EncomspServerPrivate; typedef int (*psEncomspStart)(EncomspServerContext* context); typedef int (*psEncomspStop)(EncomspServerContext* context); +typedef int (*psEncomspFilterUpdated)(EncomspServerContext* context, ENCOMSP_FILTER_UPDATED_PDU* filterUpdated); +typedef int (*psEncomspApplicationCreated)(EncomspServerContext* context, ENCOMSP_APPLICATION_CREATED_PDU* applicationCreated); +typedef int (*psEncomspApplicationRemoved)(EncomspServerContext* context, ENCOMSP_APPLICATION_REMOVED_PDU* applicationRemoved); +typedef int (*psEncomspWindowCreated)(EncomspServerContext* context, ENCOMSP_WINDOW_CREATED_PDU* windowCreated); +typedef int (*psEncomspWindowRemoved)(EncomspServerContext* context, ENCOMSP_WINDOW_REMOVED_PDU* windowRemoved); +typedef int (*psEncomspShowWindow)(EncomspServerContext* context, ENCOMSP_SHOW_WINDOW_PDU* showWindow); +typedef int (*psEncomspParticipantCreated)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated); +typedef int (*psEncomspParticipantRemoved)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_REMOVED_PDU* participantRemoved); +typedef int (*psEncomspChangeParticipantControlLevel)(EncomspServerContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* changeParticipantControlLevel); +typedef int (*psEncomspGraphicsStreamPaused)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU* graphicsStreamPaused); +typedef int (*psEncomspGraphicsStreamResumed)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU* graphicsStreamResumed); + struct _encomsp_server_context { HANDLE vcm; + void* custom; psEncomspStart Start; psEncomspStop Stop; + psEncomspFilterUpdated FilterUpdated; + psEncomspApplicationCreated ApplicationCreated; + psEncomspApplicationRemoved ApplicationRemoved; + psEncomspWindowCreated WindowCreated; + psEncomspWindowRemoved WindowRemoved; + psEncomspShowWindow ShowWindow; + psEncomspParticipantCreated ParticipantCreated; + psEncomspParticipantRemoved ParticipantRemoved; + psEncomspChangeParticipantControlLevel ChangeParticipantControlLevel; + psEncomspGraphicsStreamPaused GraphicsStreamPaused; + psEncomspGraphicsStreamResumed GraphicsStreamResumed; + EncomspServerPrivate* priv; }; diff --git a/include/freerdp/server/remdesk.h b/include/freerdp/server/remdesk.h index 75b1e0a93..b2c3f118c 100644 --- a/include/freerdp/server/remdesk.h +++ b/include/freerdp/server/remdesk.h @@ -39,6 +39,7 @@ typedef int (*psRemdeskStop)(RemdeskServerContext* context); struct _remdesk_server_context { HANDLE vcm; + void* custom; psRemdeskStart Start; psRemdeskStop Stop; diff --git a/server/shadow/CMakeLists.txt b/server/shadow/CMakeLists.txt index 9bec3b117..cf843ade4 100644 --- a/server/shadow/CMakeLists.txt +++ b/server/shadow/CMakeLists.txt @@ -128,7 +128,11 @@ set(${MODULE_PREFIX}_SRCS shadow_encoder.h shadow_channels.c shadow_channels.h - shadow.c + shadow_encomsp.c + shadow_encomsp.h + shadow_remdesk.c + shadow_remdesk.h + shadow_server.c shadow.h) set(${MODULE_PREFIX}_X11_SRCS diff --git a/server/shadow/shadow_channels.c b/server/shadow/shadow_channels.c index eeb4e7e0e..5a2e4bb03 100644 --- a/server/shadow/shadow_channels.c +++ b/server/shadow/shadow_channels.c @@ -28,19 +28,13 @@ int shadow_client_channels_post_connect(rdpShadowClient* client) { if (WTSVirtualChannelManagerIsChannelJoined(client->vcm, ENCOMSP_SVC_CHANNEL_NAME)) { - client->encomsp = encomsp_server_context_new(client->vcm); - - if (client->encomsp) - client->encomsp->Start(client->encomsp); + shadow_client_encomsp_init(client); } if (WTSVirtualChannelManagerIsChannelJoined(client->vcm, REMDESK_SVC_CHANNEL_NAME)) { - client->remdesk = remdesk_server_context_new(client->vcm); - - if (client->remdesk) - client->remdesk->Start(client->remdesk); + shadow_client_remdesk_init(client); } - return 0; + return 1; } diff --git a/server/shadow/shadow_channels.h b/server/shadow/shadow_channels.h index fab849ded..7c11eb84e 100644 --- a/server/shadow/shadow_channels.h +++ b/server/shadow/shadow_channels.h @@ -24,6 +24,9 @@ #include #include +#include "shadow_encomsp.h" +#include "shadow_remdesk.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/server/shadow/shadow_encomsp.c b/server/shadow/shadow_encomsp.c new file mode 100644 index 000000000..3bca7e7d6 --- /dev/null +++ b/server/shadow/shadow_encomsp.c @@ -0,0 +1,108 @@ +/** + * 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 "shadow.h" + +#include "shadow_encomsp.h" + +static int encomsp_change_participant_control_level(EncomspServerContext* context, + ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) +{ + BOOL inLobby; + BOOL mayView; + BOOL mayInteract; + rdpShadowClient* client = (rdpShadowClient*) context->custom; + + printf("ChangeParticipantControlLevel: ParticipantId: %d Flags: 0x%04X\n", + pdu->ParticipantId, pdu->Flags); + + mayView = (pdu->Flags & ENCOMSP_MAY_VIEW) ? TRUE : FALSE; + mayInteract = (pdu->Flags & ENCOMSP_MAY_INTERACT) ? TRUE : FALSE; + + if (mayInteract && !mayView) + mayView = TRUE; /* may interact implies may view */ + + if (mayInteract) + { + if (!client->mayInteract) + { + /* request interact + view */ + client->mayInteract = TRUE; + client->mayView = TRUE; + } + } + else if (mayView) + { + if (client->mayInteract) + { + /* release interact */ + client->mayInteract = FALSE; + } + else if (!client->mayView) + { + /* request view */ + client->mayView = TRUE; + } + } + else + { + if (client->mayInteract) + { + /* release interact + view */ + client->mayView = FALSE; + client->mayInteract = FALSE; + } + else if (client->mayView) + { + /* release view */ + client->mayView = FALSE; + client->mayInteract = FALSE; + } + } + + inLobby = client->mayView ? FALSE : TRUE; + + if (inLobby != client->inLobby) + { + shadow_encoder_reset(client->server->encoder); + client->inLobby = inLobby; + } + + return 1; +} + +int shadow_client_encomsp_init(rdpShadowClient* client) +{ + EncomspServerContext* encomsp; + + encomsp = client->encomsp = encomsp_server_context_new(client->vcm); + + encomsp->custom = (void*) client; + + encomsp->ChangeParticipantControlLevel = encomsp_change_participant_control_level; + + if (client->encomsp) + client->encomsp->Start(client->encomsp); + + return 1; +} + diff --git a/channels/encomsp/encomsp_common.h b/server/shadow/shadow_encomsp.h similarity index 62% rename from channels/encomsp/encomsp_common.h rename to server/shadow/shadow_encomsp.h index 8ce493ab7..d7187b5cb 100644 --- a/channels/encomsp/encomsp_common.h +++ b/server/shadow/shadow_encomsp.h @@ -1,6 +1,5 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * Multiparty Virtual Channel * * Copyright 2014 Marc-Andre Moreau * @@ -17,17 +16,22 @@ * limitations under the License. */ -#ifndef FREERDP_CHANNEL_ENCOMSP_COMMON_H -#define FREERDP_CHANNEL_ENCOMSP_COMMON_H +#ifndef FREERDP_SHADOW_SERVER_ENCOMSP_H +#define FREERDP_SHADOW_SERVER_ENCOMSP_H + +#include #include -#include +#include -#include +#ifdef __cplusplus +extern "C" { +#endif -int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header); -int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header); +int shadow_client_encomsp_init(rdpShadowClient* client); -int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str); +#ifdef __cplusplus +} +#endif -#endif /* FREERDP_CHANNEL_ENCOMSP_COMMON_H */ +#endif /* FREERDP_SHADOW_SERVER_ENCOMSP_H */ diff --git a/server/shadow/shadow_remdesk.c b/server/shadow/shadow_remdesk.c new file mode 100644 index 000000000..c88681352 --- /dev/null +++ b/server/shadow/shadow_remdesk.c @@ -0,0 +1,35 @@ +/** + * 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 "shadow.h" + +#include "shadow_remdesk.h" + +int shadow_client_remdesk_init(rdpShadowClient* client) +{ + client->remdesk = remdesk_server_context_new(client->vcm); + + if (client->remdesk) + client->remdesk->Start(client->remdesk); + + return 1; +} diff --git a/server/shadow/shadow_remdesk.h b/server/shadow/shadow_remdesk.h new file mode 100644 index 000000000..f99a42d24 --- /dev/null +++ b/server/shadow/shadow_remdesk.h @@ -0,0 +1,37 @@ +/** + * 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. + */ + +#ifndef FREERDP_SHADOW_SERVER_REMDESK_H +#define FREERDP_SHADOW_SERVER_REMDESK_H + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int shadow_client_remdesk_init(rdpShadowClient* client); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_REMDESK_H */ diff --git a/server/shadow/shadow.c b/server/shadow/shadow_server.c similarity index 100% rename from server/shadow/shadow.c rename to server/shadow/shadow_server.c