diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt index 47496e308..cac9ecb25 100644 --- a/channels/CMakeLists.txt +++ b/channels/CMakeLists.txt @@ -17,5 +17,6 @@ # See the License for the specific language governing permissions and # limitations under the License. +add_subdirectory(cliprdr) add_subdirectory(rdpdbg) diff --git a/channels/cliprdr/CMakeLists.txt b/channels/cliprdr/CMakeLists.txt new file mode 100644 index 000000000..c15ce6dda --- /dev/null +++ b/channels/cliprdr/CMakeLists.txt @@ -0,0 +1,29 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 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. + +set(CLIPRDR_SRCS + cliprdr_main.c +) + +add_library(cliprdr SHARED ${CLIPRDR_SRCS}) +set_target_properties(cliprdr PROPERTIES PREFIX "") + +target_link_libraries(cliprdr freerdp-utils) + +install(TARGETS cliprdr DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/cliprdr/cliprdr_constants.h b/channels/cliprdr/cliprdr_constants.h new file mode 100644 index 000000000..d18864d00 --- /dev/null +++ b/channels/cliprdr/cliprdr_constants.h @@ -0,0 +1,58 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Clipboard Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * 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 __CLIPRDR_CONSTANTS +#define __CLIPRDR_CONSTANTS + +/* CLIPRDR_HEADER.msgType */ +#define CB_MONITOR_READY 1 +#define CB_FORMAT_LIST 2 +#define CB_FORMAT_LIST_RESPONSE 3 +#define CB_FORMAT_DATA_REQUEST 4 +#define CB_FORMAT_DATA_RESPONSE 5 +#define CB_TEMP_DIRECTORY 6 +#define CB_CLIP_CAPS 7 +#define CB_FILECONTENTS_REQUEST 8 +#define CB_FILECONTENTS_RESPONSE 9 +#define CB_LOCK_CLIPDATA 10 +#define CB_UNLOCK_CLIPDATA 11 + +/* CLIPRDR_HEADER.msgFlags */ +#define CB_RESPONSE_OK 1 +#define CB_RESPONSE_FAIL 2 +#define CB_ASCII_NAMES 4 + +/* CLIPRDR_CAPS_SET.capabilitySetType */ +#define CB_CAPSTYPE_GENERAL 1 + +/* CLIPRDR_GENERAL_CAPABILITY.lengthCapability */ +#define CB_CAPSTYPE_GENERAL_LEN 12 + +/* CLIPRDR_GENERAL_CAPABILITY.version */ +#define CB_CAPS_VERSION_1 1 +#define CB_CAPS_VERSION_2 2 + +/* CLIPRDR_GENERAL_CAPABILITY.generalFlags */ +#define CB_USE_LONG_FORMAT_NAMES 2 +#define CB_STREAM_FILECLIP_ENABLED 4 +#define CB_FILECLIP_NO_FILE_PATHS 8 +#define CB_CAN_LOCK_CLIPDATA 16 + +#endif /* __CLIPRDR_CONSTANTS */ diff --git a/channels/cliprdr/cliprdr_main.c b/channels/cliprdr/cliprdr_main.c new file mode 100644 index 000000000..11a4e5c81 --- /dev/null +++ b/channels/cliprdr/cliprdr_main.c @@ -0,0 +1,153 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Clipboard Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "cliprdr_constants.h" +#include "cliprdr_main.h" + +STREAM* cliprdr_packet_new(uint16 msgType, uint16 msgFlags, uint32 dataLen) +{ + STREAM* data_out; + + data_out = stream_new(dataLen + 8); + stream_write_uint16(data_out, msgType); + stream_write_uint16(data_out, msgFlags); + /* Write actual length after the entire packet has been constructed. */ + stream_seek(data_out, 4); + + return data_out; +} + +void cliprdr_packet_send(cliprdrPlugin* cliprdr, STREAM* data_out) +{ + int pos; + uint32 dataLen; + + pos = stream_get_pos(data_out); + dataLen = pos - 8; + stream_set_pos(data_out, 4); + stream_write_uint32(data_out, dataLen); + stream_set_pos(data_out, pos); + + svc_plugin_send((rdpSvcPlugin*)cliprdr, data_out); +} + +static void cliprdr_process_connect(rdpSvcPlugin* plugin) +{ + DEBUG_SVC("connecting"); +} + +static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, STREAM* data_in) +{ + uint16 cCapabilitiesSets; + + stream_read_uint16(data_in, cCapabilitiesSets); + DEBUG_SVC("cCapabilitiesSets %d", cCapabilitiesSets); +} + +static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr) +{ + STREAM* data_out; + + data_out = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN); + + stream_write_uint16(data_out, 1); /* cCapabilitiesSets */ + stream_write_uint16(data_out, 0); /* pad1 */ + stream_write_uint16(data_out, CB_CAPSTYPE_GENERAL); /* capabilitySetType */ + stream_write_uint16(data_out, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability */ + stream_write_uint32(data_out, CB_CAPS_VERSION_2); /* version */ + stream_write_uint32(data_out, 0); /* generalFlags */ + + cliprdr_packet_send(cliprdr, data_out); +} + +static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr) +{ + cliprdr_send_clip_caps(cliprdr); +} + +static void cliprdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) +{ + cliprdrPlugin* cliprdr = (cliprdrPlugin*)plugin; + uint16 msgType; + uint16 msgFlags; + uint32 dataLen; + + stream_read_uint16(data_in, msgType); + stream_read_uint16(data_in, msgFlags); + stream_read_uint32(data_in, dataLen); + + DEBUG_SVC("msgType %d msgFlags %d dataLen %d", msgType, msgFlags, dataLen); + + switch (msgType) + { + case CB_CLIP_CAPS: + cliprdr_process_clip_caps(cliprdr, data_in); + break; + + case CB_MONITOR_READY: + cliprdr_process_monitor_ready(cliprdr); + break; + + default: + DEBUG_WARN("unknown msgType %d", msgType); + break; + } + + stream_free(data_in); +} + +static void cliprdr_process_event(rdpSvcPlugin* plugin, FRDP_EVENT* event) +{ +} + +static void cliprdr_process_terminate(rdpSvcPlugin* plugin) +{ + xfree(plugin); +} + +int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +{ + cliprdrPlugin* cliprdr; + + cliprdr = (cliprdrPlugin*)xmalloc(sizeof(cliprdrPlugin)); + memset(cliprdr, 0, sizeof(cliprdrPlugin)); + + cliprdr->plugin.channel_def.options = CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; + strcpy(cliprdr->plugin.channel_def.name, "cliprdr"); + + cliprdr->plugin.connect_callback = cliprdr_process_connect; + cliprdr->plugin.receive_callback = cliprdr_process_receive; + cliprdr->plugin.event_callback = cliprdr_process_event; + cliprdr->plugin.terminate_callback = cliprdr_process_terminate; + + svc_plugin_init((rdpSvcPlugin*)cliprdr, pEntryPoints); + + return 1; +} diff --git a/channels/cliprdr/cliprdr_main.h b/channels/cliprdr/cliprdr_main.h new file mode 100644 index 000000000..1859dc122 --- /dev/null +++ b/channels/cliprdr/cliprdr_main.h @@ -0,0 +1,35 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Clipboard Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * 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 __CLIPRDR_MAIN_H +#define __CLIPRDR_MAIN_H + +#include + +typedef struct cliprdr_plugin cliprdrPlugin; +struct cliprdr_plugin +{ + rdpSvcPlugin plugin; +}; + +STREAM* cliprdr_packet_new(uint16 msgType, uint16 msgFlags, uint32 dataLen); +void cliprdr_packet_send(cliprdrPlugin* cliprdr, STREAM* data_out); + +#endif /* __CLIPRDR_MAIN_H */ diff --git a/cunit/CMakeLists.txt b/cunit/CMakeLists.txt index 4ff394cfc..4b0f84f94 100644 --- a/cunit/CMakeLists.txt +++ b/cunit/CMakeLists.txt @@ -47,6 +47,8 @@ add_executable(test_freerdp test_transport.h test_chanman.c test_chanman.h + test_cliprdr.c + test_cliprdr.h test_freerdp.c test_freerdp.h) diff --git a/cunit/test_cliprdr.c b/cunit/test_cliprdr.c new file mode 100644 index 000000000..5c71d5bbb --- /dev/null +++ b/cunit/test_cliprdr.c @@ -0,0 +1,95 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Clipboard Virtual Channel Unit Tests + * + * Copyright 2011 Vic Lee + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "test_cliprdr.h" + +int init_cliprdr_suite(void) +{ + freerdp_chanman_global_init(); + return 0; +} + +int clean_cliprdr_suite(void) +{ + freerdp_chanman_global_uninit(); + return 0; +} + +int add_cliprdr_suite(void) +{ + add_test_suite(cliprdr); + + add_test_function(cliprdr); + + return 0; +} + +static const uint8 test_clip_caps_data[] = +{ + "\x07\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x01\x00\x0C\x00" + "\x02\x00\x00\x00\x0E\x00\x00\x00" +}; + +static const uint8 test_monitor_ready_data[] = +{ + "\x01\x00\x00\x00\x00\x00\x00\x00" +}; + +static int test_rdp_channel_data(rdpInst* inst, int chan_id, char* data, int data_size) +{ + printf("chan_id %d data_size %d\n", chan_id, data_size); +} + +void test_cliprdr(void) +{ + rdpChanMan* chan_man; + rdpSettings settings = { 0 }; + rdpInst inst = { 0 }; + FRDP_EVENT* event; + + settings.hostname = "testhost"; + inst.settings = &settings; + inst.rdp_channel_data = test_rdp_channel_data; + + chan_man = freerdp_chanman_new(); + + freerdp_chanman_load_plugin(chan_man, &settings, "../channels/cliprdr/cliprdr.so", NULL); + freerdp_chanman_pre_connect(chan_man, &inst); + freerdp_chanman_post_connect(chan_man, &inst); + + freerdp_chanman_data(&inst, 0, (char*)test_clip_caps_data, sizeof(test_clip_caps_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_clip_caps_data) - 1); + + freerdp_chanman_data(&inst, 0, (char*)test_monitor_ready_data, sizeof(test_monitor_ready_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_monitor_ready_data) - 1); + + sleep(1); + freerdp_chanman_check_fds(chan_man, &inst); + + freerdp_chanman_close(chan_man, &inst); + freerdp_chanman_free(chan_man); +} diff --git a/cunit/test_cliprdr.h b/cunit/test_cliprdr.h new file mode 100644 index 000000000..f1a5509ca --- /dev/null +++ b/cunit/test_cliprdr.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Clipboard Virtual Channel Unit Tests + * + * Copyright 2011 Vic Lee + * + * 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 "test_freerdp.h" + +int init_cliprdr_suite(void); +int clean_cliprdr_suite(void); +int add_cliprdr_suite(void); + +void test_cliprdr(void); diff --git a/cunit/test_freerdp.c b/cunit/test_freerdp.c index 6da5a8d7a..959f0e636 100644 --- a/cunit/test_freerdp.c +++ b/cunit/test_freerdp.c @@ -31,6 +31,7 @@ #include "test_utils.h" #include "test_transport.h" #include "test_chanman.h" +#include "test_cliprdr.h" #include "test_freerdp.h" void dump_data(unsigned char * p, int len, int width, char* name) @@ -123,6 +124,7 @@ int main(int argc, char* argv[]) add_utils_suite(); add_transport_suite(); add_chanman_suite(); + add_cliprdr_suite(); } else { @@ -160,6 +162,10 @@ int main(int argc, char* argv[]) { add_chanman_suite(); } + else if (strcmp("cliprdr", argv[*pindex]) == 0) + { + add_cliprdr_suite(); + } else if (strcmp("per", argv[*pindex]) == 0) { add_per_suite();