From 4560e088bde1c1da4a95fee4707ea662c1fb6068 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sat, 9 Jul 2011 23:29:04 +0800 Subject: [PATCH 01/10] libfreerdp-utils: add svc_plugin. --- cmake/ConfigOptions.cmake | 1 + config.h.in | 1 + include/freerdp/utils/svc_plugin.h | 45 ++++++ libfreerdp-utils/CMakeLists.txt | 1 + libfreerdp-utils/svc_plugin.c | 233 +++++++++++++++++++++++++++++ 5 files changed, 281 insertions(+) create mode 100644 include/freerdp/utils/svc_plugin.h create mode 100644 libfreerdp-utils/svc_plugin.c diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index 8c1f25675..9c681f2d3 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -1,2 +1,3 @@ option(WITH_DEBUG_TRANSPORT "Print transport debug message." OFF) option(WITH_DEBUG_CHANMAN "Print channel manager debug message." OFF) +option(WITH_DEBUG_SVC "Print static virtual channel debug message." OFF) diff --git a/config.h.in b/config.h.in index 77cd75c75..1d70425fa 100644 --- a/config.h.in +++ b/config.h.in @@ -11,3 +11,4 @@ /* Options */ #cmakedefine WITH_DEBUG_TRANSPORT #cmakedefine WITH_DEBUG_CHANMAN +#cmakedefine WITH_DEBUG_SVC diff --git a/include/freerdp/utils/svc_plugin.h b/include/freerdp/utils/svc_plugin.h new file mode 100644 index 000000000..041204743 --- /dev/null +++ b/include/freerdp/utils/svc_plugin.h @@ -0,0 +1,45 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Static Virtual Channel Interface + * + * 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 __SVC_PLUGIN_UTILS_H +#define __SVC_PLUGIN_UTILS_H + +/* static channel plugin base implementation */ + +#include + +typedef struct rdp_svc_plugin_private rdpSvcPluginPrivate; +typedef struct rdp_svc_plugin rdpSvcPlugin; +struct rdp_svc_plugin +{ + CHANNEL_ENTRY_POINTS channel_entry_points; + CHANNEL_DEF channel_def; + + void (*connect_callback)(rdpSvcPlugin* plugin); + void (*receive_callback)(rdpSvcPlugin* plugin, uint8* data, int size); + void (*terminate_callback)(rdpSvcPlugin* plugin); + + rdpSvcPluginPrivate* priv; +}; + +void svc_plugin_init(rdpSvcPlugin* plugin); +int svc_plugin_send(rdpSvcPlugin* plugin, uint8* data, int size); + +#endif /* __SVC_PLUGIN_UTILS_H */ diff --git a/libfreerdp-utils/CMakeLists.txt b/libfreerdp-utils/CMakeLists.txt index 4ef3760c0..fdec57ed3 100644 --- a/libfreerdp-utils/CMakeLists.txt +++ b/libfreerdp-utils/CMakeLists.txt @@ -25,6 +25,7 @@ set(FREERDP_UTILS_SRCS mutex.c semaphore.c stream.c + svc_plugin.c unicode.c wait_obj.c) diff --git a/libfreerdp-utils/svc_plugin.c b/libfreerdp-utils/svc_plugin.c new file mode 100644 index 000000000..0d36be2ae --- /dev/null +++ b/libfreerdp-utils/svc_plugin.c @@ -0,0 +1,233 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Static Virtual Channel Interface + * + * 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 "config.h" +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_DEBUG_SVC +#define DEBUG_SVC(fmt, ...) DEBUG_CLASS(SVC, fmt, ## __VA_ARGS__) +#else +#define DEBUG_SVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +/* The list of all plugin instances. */ +typedef struct rdp_svc_plugin_list rdpSvcPluginList; +struct rdp_svc_plugin_list +{ + rdpSvcPlugin* plugin; + rdpSvcPluginList* next; +}; + +static rdpSvcPluginList* g_svc_plugin_list = NULL; + +/* For locking the global resources */ +static freerdp_mutex g_mutex = NULL; + +struct rdp_svc_plugin_private +{ + void* init_handle; + uint32 open_handle; +}; + +static rdpSvcPlugin* svc_plugin_find_by_init_handle(void* init_handle) +{ + rdpSvcPluginList * list; + rdpSvcPlugin * plugin; + + freerdp_mutex_lock(g_mutex); + for (list = g_svc_plugin_list; list; list = list->next) + { + plugin = list->plugin; + if (plugin->priv->init_handle == init_handle) + { + freerdp_mutex_unlock(g_mutex); + return plugin; + } + } + freerdp_mutex_unlock(g_mutex); + return NULL; +} + +static rdpSvcPlugin* svc_plugin_find_by_open_handle(uint32 open_handle) +{ + rdpSvcPluginList * list; + rdpSvcPlugin * plugin; + + freerdp_mutex_lock(g_mutex); + for (list = g_svc_plugin_list; list; list = list->next) + { + plugin = list->plugin; + if (plugin->priv->open_handle == open_handle) + { + freerdp_mutex_unlock(g_mutex); + return plugin; + } + } + freerdp_mutex_unlock(g_mutex); + return NULL; +} + +static void svc_plugin_remove(rdpSvcPlugin* plugin) +{ + rdpSvcPluginList* list; + rdpSvcPluginList* prev; + + /* Remove from global list */ + freerdp_mutex_lock(g_mutex); + for (prev = NULL, list = g_svc_plugin_list; list; prev = list, list = list->next) + { + if (list->plugin == plugin) + break; + } + if (list) + { + if (prev) + prev->next = list->next; + else + g_svc_plugin_list = list->next; + xfree(list); + } + freerdp_mutex_unlock(g_mutex); +} + +static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength, + uint32 totalLength, uint32 dataFlags) +{ + plugin->receive_callback(plugin, (uint8*)pData, dataLength); +} + +static void svc_plugin_open_event(uint32 openHandle, uint32 event, void* pData, uint32 dataLength, + uint32 totalLength, uint32 dataFlags) +{ + rdpSvcPlugin* plugin; + + DEBUG_SVC("event %d dataLength %d", event, dataLength); + + plugin = (rdpSvcPlugin*)svc_plugin_find_by_open_handle(openHandle); + if (plugin == NULL) + { + printf("svc_plugin_open_event: error no match\n"); + return; + } + switch (event) + { + case CHANNEL_EVENT_DATA_RECEIVED: + svc_plugin_process_received(plugin, pData, dataLength, totalLength, dataFlags); + break; + case CHANNEL_EVENT_WRITE_COMPLETE: + xfree(pData); + break; + } +} + +static void svc_plugin_process_connected(rdpSvcPlugin* plugin, void* pData, uint32 dataLength) +{ + uint32 error; + + error = plugin->channel_entry_points.pVirtualChannelOpen(plugin->priv->init_handle, &plugin->priv->open_handle, + plugin->channel_def.name, svc_plugin_open_event); + if (error != CHANNEL_RC_OK) + { + printf("svc_plugin_process_connected: open failed\n"); + return; + } + plugin->connect_callback(plugin); +} + +static void svc_plugin_process_terminated(rdpSvcPlugin* plugin) +{ + plugin->channel_entry_points.pVirtualChannelClose(plugin->priv->open_handle); + svc_plugin_remove(plugin); + xfree(plugin->priv); + plugin->priv = NULL; + plugin->terminate_callback(plugin); +} + +static void svc_plugin_init_event(void* pInitHandle, uint32 event, void* pData, uint32 dataLength) +{ + rdpSvcPlugin* plugin; + + DEBUG_SVC("event %d", event); + + plugin = (rdpSvcPlugin*)svc_plugin_find_by_init_handle(pInitHandle); + if (plugin == NULL) + { + printf("svc_plugin_init_event: error no match\n"); + return; + } + switch (event) + { + case CHANNEL_EVENT_CONNECTED: + svc_plugin_process_connected(plugin, pData, dataLength); + break; + case CHANNEL_EVENT_DISCONNECTED: + break; + case CHANNEL_EVENT_TERMINATED: + svc_plugin_process_terminated(plugin); + break; + } +} + +void svc_plugin_init(rdpSvcPlugin* plugin) +{ + rdpSvcPluginList* list; + + /** + * The channel manager will guarantee only one thread can call + * VirtualChannelInit at a time. So this should be safe. + */ + if (g_mutex == NULL) + g_mutex = freerdp_mutex_new(); + + plugin->priv = (rdpSvcPluginPrivate*)xmalloc(sizeof(rdpSvcPluginPrivate)); + memset(plugin->priv, 0, sizeof(rdpSvcPluginPrivate)); + + /* Add it to the global list */ + list = (rdpSvcPluginList*)xmalloc(sizeof(rdpSvcPluginList)); + list->plugin = plugin; + + freerdp_mutex_lock(g_mutex); + list->next = g_svc_plugin_list; + g_svc_plugin_list = list; + freerdp_mutex_unlock(g_mutex); + + plugin->channel_entry_points.pVirtualChannelInit(&plugin->priv->init_handle, + &plugin->channel_def, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, svc_plugin_init_event); +} + +int svc_plugin_send(rdpSvcPlugin* plugin, uint8* data, int size) +{ + uint32 error = 0; + + DEBUG_SVC("size %d", size); + + error = plugin->channel_entry_points.pVirtualChannelWrite(plugin->priv->open_handle, + data, size, data); + if (error != CHANNEL_RC_OK) + printf("svc_plugin_send: VirtualChannelWrite failed %d", error); + + return error; +} From 315627dd43585bd2ccd139e8fcc96ea3104a0903 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 10:00:16 +0800 Subject: [PATCH 02/10] libfreerdp-utils/svc_plugin: reassemble data chunks using stream. --- include/freerdp/utils/stream.h | 1 + include/freerdp/utils/svc_plugin.h | 3 ++- libfreerdp-utils/svc_plugin.c | 38 ++++++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/freerdp/utils/stream.h b/include/freerdp/utils/stream.h index b62bde9e8..641fe657e 100644 --- a/include/freerdp/utils/stream.h +++ b/include/freerdp/utils/stream.h @@ -50,6 +50,7 @@ stream_extend(STREAM * stream); #define stream_get_head(_s) _s->data #define stream_get_tail(_s) _s->p #define stream_get_length(_s) (_s->p - _s->data) +#define stream_get_size(_s) (_s->size) #define stream_read_uint8(_s, _v) do { _v = *_s->p++; } while (0) #define stream_read_uint16(_s, _v) do { _v = \ diff --git a/include/freerdp/utils/svc_plugin.h b/include/freerdp/utils/svc_plugin.h index 041204743..149e2091f 100644 --- a/include/freerdp/utils/svc_plugin.h +++ b/include/freerdp/utils/svc_plugin.h @@ -24,6 +24,7 @@ /* static channel plugin base implementation */ #include +#include typedef struct rdp_svc_plugin_private rdpSvcPluginPrivate; typedef struct rdp_svc_plugin rdpSvcPlugin; @@ -33,7 +34,7 @@ struct rdp_svc_plugin CHANNEL_DEF channel_def; void (*connect_callback)(rdpSvcPlugin* plugin); - void (*receive_callback)(rdpSvcPlugin* plugin, uint8* data, int size); + void (*receive_callback)(rdpSvcPlugin* plugin, STREAM* data_in); void (*terminate_callback)(rdpSvcPlugin* plugin); rdpSvcPluginPrivate* priv; diff --git a/libfreerdp-utils/svc_plugin.c b/libfreerdp-utils/svc_plugin.c index 0d36be2ae..e2344f78d 100644 --- a/libfreerdp-utils/svc_plugin.c +++ b/libfreerdp-utils/svc_plugin.c @@ -22,9 +22,11 @@ #include #include #include +#include #include #include #include +#include #include #ifdef WITH_DEBUG_SVC @@ -50,6 +52,7 @@ struct rdp_svc_plugin_private { void* init_handle; uint32 open_handle; + STREAM* data_in; }; static rdpSvcPlugin* svc_plugin_find_by_init_handle(void* init_handle) @@ -116,7 +119,29 @@ static void svc_plugin_remove(rdpSvcPlugin* plugin) static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength, uint32 totalLength, uint32 dataFlags) { - plugin->receive_callback(plugin, (uint8*)pData, dataLength); + STREAM* data_in; + + if (dataFlags & CHANNEL_FLAG_FIRST) + { + if (plugin->priv->data_in != NULL) + stream_free(plugin->priv->data_in); + plugin->priv->data_in = stream_new(totalLength); + } + + data_in = plugin->priv->data_in; + stream_check_size(data_in, dataLength); + stream_write(data_in, pData, dataLength); + + if (dataFlags & CHANNEL_FLAG_LAST) + { + if (stream_get_size(data_in) != stream_get_length(data_in)) + { + printf("svc_plugin_process_received: read error\n"); + } + /* the stream ownership is passed to the callback who is responsible for freeing it. */ + plugin->priv->data_in = NULL; + plugin->receive_callback(plugin, data_in); + } } static void svc_plugin_open_event(uint32 openHandle, uint32 event, void* pData, uint32 dataLength, @@ -124,7 +149,8 @@ static void svc_plugin_open_event(uint32 openHandle, uint32 event, void* pData, { rdpSvcPlugin* plugin; - DEBUG_SVC("event %d dataLength %d", event, dataLength); + DEBUG_SVC("openHandle %d event %d dataLength %d totalLength %d dataFlags %d", + openHandle, event, dataLength, totalLength, dataFlags); plugin = (rdpSvcPlugin*)svc_plugin_find_by_open_handle(openHandle); if (plugin == NULL) @@ -160,9 +186,17 @@ static void svc_plugin_process_connected(rdpSvcPlugin* plugin, void* pData, uint static void svc_plugin_process_terminated(rdpSvcPlugin* plugin) { plugin->channel_entry_points.pVirtualChannelClose(plugin->priv->open_handle); + svc_plugin_remove(plugin); + + if (plugin->priv->data_in != NULL) + { + stream_free(plugin->priv->data_in); + plugin->priv->data_in = NULL; + } xfree(plugin->priv); plugin->priv = NULL; + plugin->terminate_callback(plugin); } From 49d7fd81a0152b6382a40eb8b1a1e61c0c6cbfa2 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 17:16:51 +0800 Subject: [PATCH 03/10] libfreerdp-utils/svc_plugin: reset stream position after complete data received. --- libfreerdp-utils/svc_plugin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfreerdp-utils/svc_plugin.c b/libfreerdp-utils/svc_plugin.c index e2344f78d..b030a4e87 100644 --- a/libfreerdp-utils/svc_plugin.c +++ b/libfreerdp-utils/svc_plugin.c @@ -140,6 +140,7 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint3 } /* the stream ownership is passed to the callback who is responsible for freeing it. */ plugin->priv->data_in = NULL; + stream_set_pos(data_in, 0); plugin->receive_callback(plugin, data_in); } } From bea0e09e0262d6f46e8d2c54453c9eb550ac95ca Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 17:27:21 +0800 Subject: [PATCH 04/10] libfreerdp-utils/stream: fix code style. --- include/freerdp/utils/stream.h | 9 +++++---- libfreerdp-utils/stream.c | 13 +++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/freerdp/utils/stream.h b/include/freerdp/utils/stream.h index 641fe657e..8943bf0fb 100644 --- a/include/freerdp/utils/stream.h +++ b/include/freerdp/utils/stream.h @@ -27,16 +27,16 @@ struct _STREAM { int size; - uint8 * p; - uint8 * data; + uint8* p; + uint8* data; }; typedef struct _STREAM STREAM; STREAM* stream_new(int size); -void stream_free(STREAM * stream); +void stream_free(STREAM* stream); void -stream_extend(STREAM * stream); +stream_extend(STREAM* stream); #define stream_check_size(_s,_n) \ while (_s->p - _s->data + (_n) > _s->size) \ stream_extend(_s) @@ -50,6 +50,7 @@ stream_extend(STREAM * stream); #define stream_get_head(_s) _s->data #define stream_get_tail(_s) _s->p #define stream_get_length(_s) (_s->p - _s->data) +#define stream_get_data(_s) (_s->data) #define stream_get_size(_s) (_s->size) #define stream_read_uint8(_s, _v) do { _v = *_s->p++; } while (0) diff --git a/libfreerdp-utils/stream.c b/libfreerdp-utils/stream.c index a13cad4b2..5a05ba448 100644 --- a/libfreerdp-utils/stream.c +++ b/libfreerdp-utils/stream.c @@ -24,12 +24,11 @@ #include #include -STREAM * -stream_new(int size) +STREAM* stream_new(int size) { - STREAM * stream; + STREAM* stream; - stream = (STREAM *) xmalloc(sizeof(STREAM)); + stream = (STREAM*)xmalloc(sizeof(STREAM)); if (stream != NULL) { @@ -50,8 +49,7 @@ stream_new(int size) return stream; } -void -stream_free(STREAM * stream) +void stream_free(STREAM* stream) { if (stream != NULL) { @@ -60,8 +58,7 @@ stream_free(STREAM * stream) } } -void -stream_extend(STREAM * stream) +void stream_extend(STREAM* stream) { int pos; From 944f4ac8a93a2223f111dc3f6a42d29f81d727c3 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 17:28:24 +0800 Subject: [PATCH 05/10] libfreerdp-utils/svc_plugin: use STREAM for sending. --- include/freerdp/utils/svc_plugin.h | 2 +- libfreerdp-utils/svc_plugin.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/freerdp/utils/svc_plugin.h b/include/freerdp/utils/svc_plugin.h index 149e2091f..48cbdf61e 100644 --- a/include/freerdp/utils/svc_plugin.h +++ b/include/freerdp/utils/svc_plugin.h @@ -41,6 +41,6 @@ struct rdp_svc_plugin }; void svc_plugin_init(rdpSvcPlugin* plugin); -int svc_plugin_send(rdpSvcPlugin* plugin, uint8* data, int size); +int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out); #endif /* __SVC_PLUGIN_UTILS_H */ diff --git a/libfreerdp-utils/svc_plugin.c b/libfreerdp-utils/svc_plugin.c index b030a4e87..809bd906c 100644 --- a/libfreerdp-utils/svc_plugin.c +++ b/libfreerdp-utils/svc_plugin.c @@ -165,7 +165,7 @@ static void svc_plugin_open_event(uint32 openHandle, uint32 event, void* pData, svc_plugin_process_received(plugin, pData, dataLength, totalLength, dataFlags); break; case CHANNEL_EVENT_WRITE_COMPLETE: - xfree(pData); + stream_free((STREAM*)pData); break; } } @@ -253,14 +253,14 @@ void svc_plugin_init(rdpSvcPlugin* plugin) &plugin->channel_def, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, svc_plugin_init_event); } -int svc_plugin_send(rdpSvcPlugin* plugin, uint8* data, int size) +int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out) { uint32 error = 0; - DEBUG_SVC("size %d", size); + DEBUG_SVC("length %d", stream_get_length(data_out)); error = plugin->channel_entry_points.pVirtualChannelWrite(plugin->priv->open_handle, - data, size, data); + stream_get_data(data_out), stream_get_length(data_out), data_out); if (error != CHANNEL_RC_OK) printf("svc_plugin_send: VirtualChannelWrite failed %d", error); From 823ae345daadfc41ce24b2b39fd04a812f2d45c9 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 21:22:44 +0800 Subject: [PATCH 06/10] libfreerdp-chanman: fix debug messages. --- libfreerdp-chanman/libchanman.c | 82 ++++++++++++++++----------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/libfreerdp-chanman/libchanman.c b/libfreerdp-chanman/libchanman.c index 3539145c7..b126bfdf2 100644 --- a/libfreerdp-chanman/libchanman.c +++ b/libfreerdp-chanman/libchanman.c @@ -274,42 +274,42 @@ static uint32 FREERDP_CC MyVirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF *ppInitHandle = &chan_man->init_handles[chan_man->num_init_handles]; chan_man->num_init_handles++; - DEBUG_CHANMAN("MyVirtualChannelInit:"); + DEBUG_CHANMAN("enter"); if (!chan_man->can_call_init) { - DEBUG_CHANMAN("MyVirtualChannelInit: error not in entry"); + DEBUG_CHANMAN("error not in entry"); return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; } if (ppInitHandle == 0) { - DEBUG_CHANMAN("MyVirtualChannelInit: error bad pphan"); + DEBUG_CHANMAN("error bad pphan"); return CHANNEL_RC_BAD_INIT_HANDLE; } if (chan_man->num_chans + channelCount >= CHANNEL_MAX_COUNT) { - DEBUG_CHANMAN("MyVirtualChannelInit: error too many channels"); + DEBUG_CHANMAN("error too many channels"); return CHANNEL_RC_TOO_MANY_CHANNELS; } if (pChannel == 0) { - DEBUG_CHANMAN("MyVirtualChannelInit: error bad pchan"); + DEBUG_CHANMAN("error bad pchan"); return CHANNEL_RC_BAD_CHANNEL; } if (chan_man->is_connected) { - DEBUG_CHANMAN("MyVirtualChannelInit: error already connected"); + DEBUG_CHANMAN("error already connected"); return CHANNEL_RC_ALREADY_CONNECTED; } if (versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000) { - DEBUG_CHANMAN("MyVirtualChannelInit: warning version"); + DEBUG_CHANMAN("warning version"); } for (index = 0; index < channelCount; index++) { lchan_def = pChannel + index; if (freerdp_chanman_find_chan_data_by_name(chan_man, lchan_def->name, 0) != 0) { - DEBUG_CHANMAN("MyVirtualChannelInit: error channel already used"); + DEBUG_CHANMAN("error channel already used"); return CHANNEL_RC_BAD_CHANNEL; } } @@ -338,7 +338,7 @@ static uint32 FREERDP_CC MyVirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF } else { - DEBUG_CHANMAN("MyVirtualChannelInit: warning more than 16 channels"); + DEBUG_CHANMAN("warning more than 16 channels"); } chan_man->num_chans++; } @@ -356,32 +356,32 @@ static uint32 FREERDP_CC MyVirtualChannelOpen(void* pInitHandle, uint32* pOpenHa int index; struct chan_data* lchan; - DEBUG_CHANMAN("MyVirtualChannelOpen:"); + DEBUG_CHANMAN("enter"); chan_man = ((rdpInitHandle*)pInitHandle)->chan_man; if (pOpenHandle == 0) { - DEBUG_CHANMAN("MyVirtualChannelOpen: error bad chanhan"); + DEBUG_CHANMAN("error bad chanhan"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (pChannelOpenEventProc == 0) { - DEBUG_CHANMAN("MyVirtualChannelOpen: error bad proc"); + DEBUG_CHANMAN("error bad proc"); return CHANNEL_RC_BAD_PROC; } if (!chan_man->is_connected) { - DEBUG_CHANMAN("MyVirtualChannelOpen: error not connected"); + DEBUG_CHANMAN("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } lchan = freerdp_chanman_find_chan_data_by_name(chan_man, pChannelName, &index); if (lchan == 0) { - DEBUG_CHANMAN("MyVirtualChannelOpen: error chan name"); + DEBUG_CHANMAN("error chan name"); return CHANNEL_RC_UNKNOWN_CHANNEL_NAME; } if (lchan->flags == 2) { - DEBUG_CHANMAN("MyVirtualChannelOpen: error chan already open\n"); + DEBUG_CHANMAN("error chan already open"); return CHANNEL_RC_ALREADY_OPEN; } @@ -401,22 +401,22 @@ static uint32 FREERDP_CC MyVirtualChannelClose(uint32 openHandle) struct chan_data* lchan; int index; - DEBUG_CHANMAN("MyVirtualChannelClose:"); + DEBUG_CHANMAN("enter"); chan_man = freerdp_chanman_find_by_open_handle(openHandle, &index); if ((chan_man == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) { - DEBUG_CHANMAN("MyVirtualChannelClose: error bad chanhan\n"); + DEBUG_CHANMAN("error bad chanhan"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (!chan_man->is_connected) { - DEBUG_CHANMAN("MyVirtualChannelClose: error not connected\n"); + DEBUG_CHANMAN("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } lchan = chan_man->chans + index; if (lchan->flags != 2) { - DEBUG_CHANMAN("MyVirtualChannelClose: error not open\n"); + DEBUG_CHANMAN("error not open"); return CHANNEL_RC_NOT_OPEN; } lchan->flags = 0; @@ -434,35 +434,35 @@ static uint32 FREERDP_CC MyVirtualChannelWrite(uint32 openHandle, void* pData, u chan_man = freerdp_chanman_find_by_open_handle(openHandle, &index); if ((chan_man == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) { - DEBUG_CHANMAN("MyVirtualChannelWrite: error bad chanhan"); + DEBUG_CHANMAN("error bad chanhan"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (!chan_man->is_connected) { - DEBUG_CHANMAN("MyVirtualChannelWrite: error not connected"); + DEBUG_CHANMAN("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } if (pData == 0) { - DEBUG_CHANMAN("MyVirtualChannelWrite: error bad pData"); + DEBUG_CHANMAN("error bad pData"); return CHANNEL_RC_NULL_DATA; } if (dataLength == 0) { - DEBUG_CHANMAN("MyVirtualChannelWrite: error bad dataLength"); + DEBUG_CHANMAN("error bad dataLength"); return CHANNEL_RC_ZERO_LENGTH; } lchan = chan_man->chans + index; if (lchan->flags != 2) { - DEBUG_CHANMAN("MyVirtualChannelWrite: error not open"); + DEBUG_CHANMAN("error not open"); return CHANNEL_RC_NOT_OPEN; } freerdp_sem_wait(chan_man->sync_data_sem); /* lock chan_man->sync* vars */ if (!chan_man->is_connected) { freerdp_sem_signal(chan_man->sync_data_sem); - DEBUG_CHANMAN("MyVirtualChannelWrite: error not connected"); + DEBUG_CHANMAN("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } chan_man->sync_data = pData; @@ -483,30 +483,30 @@ static uint32 FREERDP_CC MyVirtualChannelEventPush(uint32 openHandle, FRDP_EVENT chan_man = freerdp_chanman_find_by_open_handle(openHandle, &index); if ((chan_man == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) { - DEBUG_CHANMAN("MyVirtualChannelEventPush: error bad chanhan"); + DEBUG_CHANMAN("error bad chanhan"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } if (!chan_man->is_connected) { - DEBUG_CHANMAN("MyVirtualChannelEventPush: error not connected"); + DEBUG_CHANMAN("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } if (event == NULL) { - DEBUG_CHANMAN("MyVirtualChannelEventPush: error bad event"); + DEBUG_CHANMAN("error bad event"); return CHANNEL_RC_NULL_DATA; } lchan = chan_man->chans + index; if (lchan->flags != 2) { - DEBUG_CHANMAN("MyVirtualChannelEventPush: error not open"); + DEBUG_CHANMAN("error not open"); return CHANNEL_RC_NOT_OPEN; } freerdp_sem_wait(chan_man->event_sem); /* lock chan_man->event */ if (!chan_man->is_connected) { freerdp_sem_signal(chan_man->event_sem); - DEBUG_CHANMAN("MyVirtualChannelEventPush: error not connected"); + DEBUG_CHANMAN("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } chan_man->event = event; @@ -606,17 +606,17 @@ int freerdp_chanman_load_plugin(rdpChanMan* chan_man, rdpSettings* settings, CHANNEL_ENTRY_POINTS_EX ep; int ok; - DEBUG_CHANMAN("freerdp_chanman_load_plugin: %s", filename); + DEBUG_CHANMAN("%s", name); if (chan_man->num_libs + 1 >= CHANNEL_MAX_COUNT) { - DEBUG_CHANMAN("freerdp_chanman_load_plugin: too many channels"); + DEBUG_CHANMAN("too many channels"); return 1; } lib = chan_man->libs + chan_man->num_libs; lib->entry = (PVIRTUALCHANNELENTRY)freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME); if (lib->entry == NULL) { - DEBUG_CHANMAN("freerdp_chanman_load_plugin: failed to find export function"); + DEBUG_CHANMAN("failed to find export function"); return 1; } ep.cbSize = sizeof(ep); @@ -643,7 +643,7 @@ int freerdp_chanman_load_plugin(rdpChanMan* chan_man, rdpSettings* settings, chan_man->can_call_init = 0; if (!ok) { - DEBUG_CHANMAN("freerdp_chanman_load_plugin: export function call failed"); + DEBUG_CHANMAN("export function call failed"); return 1; } return 0; @@ -660,7 +660,7 @@ int freerdp_chanman_pre_connect(rdpChanMan* chan_man, rdpInst* inst) CHANNEL_DEF lchannel_def; void* dummy; - DEBUG_CHANMAN("freerdp_chanman_pre_connect:"); + DEBUG_CHANMAN("enter"); chan_man->inst = inst; /** @@ -684,7 +684,7 @@ int freerdp_chanman_pre_connect(rdpChanMan* chan_man, rdpInst* inst) freerdp_mutex_unlock(g_mutex_init); chan_man->can_call_init = 0; chan_man->settings = 0; - DEBUG_CHANMAN("freerdp_chanman_pre_connect: registered fake rdpdr for rdpsnd."); + DEBUG_CHANMAN("registered fake rdpdr for rdpsnd."); } for (index = 0; index < chan_man->num_libs; index++) @@ -714,7 +714,7 @@ int freerdp_chanman_post_connect(rdpChanMan* chan_man, rdpInst* inst) chan_man->is_connected = 1; hostname = inst->settings->hostname; hostname_len = strlen(hostname); - DEBUG_CHANMAN("freerdp_chanman_post_connect: hostname [%s] chan_man->num_libs [%d]", + DEBUG_CHANMAN("hostname [%s] chan_man->num_libs [%d]", hostname, chan_man->num_libs); for (index = 0; index < chan_man->num_libs; index++) { @@ -743,7 +743,7 @@ int freerdp_chanman_data(rdpInst* inst, int chan_id, char* data, int data_size, chan_man = freerdp_chanman_find_by_rdp_inst(inst); if (chan_man == 0) { - DEBUG_CHANMAN("freerdp_chanman_data: could not find channel manager"); + DEBUG_CHANMAN("could not find channel manager"); return 1; } @@ -751,14 +751,14 @@ int freerdp_chanman_data(rdpInst* inst, int chan_id, char* data, int data_size, chan_id, &index); if (lrdp_chan == 0) { - DEBUG_CHANMAN("freerdp_chanman_data: could not find channel id"); + DEBUG_CHANMAN("could not find channel id"); return 1; } lchan_data = freerdp_chanman_find_chan_data_by_name(chan_man, lrdp_chan->name, &index); if (lchan_data == 0) { - DEBUG_CHANMAN("freerdp_chanman_data: could not find channel name"); + DEBUG_CHANMAN("could not find channel name"); return 1; } if (lchan_data->open_event_proc != 0) @@ -854,7 +854,7 @@ void freerdp_chanman_close(rdpChanMan* chan_man, rdpInst* inst) int index; struct lib_data* llib; - DEBUG_CHANMAN("freerdp_chanman_close:"); + DEBUG_CHANMAN("closing"); chan_man->is_connected = 0; freerdp_chanman_check_fds(chan_man, inst); /* tell all libraries we are shutting down */ From e88d209d0c7790446487ecf06bf0016c7a1b3780 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 21:52:19 +0800 Subject: [PATCH 07/10] libfreerdp-chanman: remove unneeded checking. --- libfreerdp-chanman/libchanman.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libfreerdp-chanman/libchanman.c b/libfreerdp-chanman/libchanman.c index b126bfdf2..5d6e2a554 100644 --- a/libfreerdp-chanman/libchanman.c +++ b/libfreerdp-chanman/libchanman.c @@ -408,11 +408,6 @@ static uint32 FREERDP_CC MyVirtualChannelClose(uint32 openHandle) DEBUG_CHANMAN("error bad chanhan"); return CHANNEL_RC_BAD_CHANNEL_HANDLE; } - if (!chan_man->is_connected) - { - DEBUG_CHANMAN("error not connected"); - return CHANNEL_RC_NOT_CONNECTED; - } lchan = chan_man->chans + index; if (lchan->flags != 2) { From 9bdb09f8761153d1c92ed07d9110ddcd2f7b72b6 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 22:24:05 +0800 Subject: [PATCH 08/10] Add rdpdbg test plugin. --- channels/CMakeLists.txt | 21 ++++++++++ channels/rdpdbg/CMakeLists.txt | 29 +++++++++++++ channels/rdpdbg/rdpdbg_main.c | 77 ++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 channels/CMakeLists.txt create mode 100644 channels/rdpdbg/CMakeLists.txt create mode 100644 channels/rdpdbg/rdpdbg_main.c diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt new file mode 100644 index 000000000..47496e308 --- /dev/null +++ b/channels/CMakeLists.txt @@ -0,0 +1,21 @@ +# 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. + +add_subdirectory(rdpdbg) + diff --git a/channels/rdpdbg/CMakeLists.txt b/channels/rdpdbg/CMakeLists.txt new file mode 100644 index 000000000..32222d100 --- /dev/null +++ b/channels/rdpdbg/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(RDPDBG_SRCS + rdpdbg_main.c +) + +add_library(rdpdbg SHARED ${RDPDBG_SRCS}) +set_target_properties(rdpdbg PROPERTIES PREFIX "") + +target_link_libraries(rdpdbg freerdp-utils) + +install(TARGETS rdpdbg DESTINATION lib/freerdp) diff --git a/channels/rdpdbg/rdpdbg_main.c b/channels/rdpdbg/rdpdbg_main.c new file mode 100644 index 000000000..0a0a7235a --- /dev/null +++ b/channels/rdpdbg/rdpdbg_main.c @@ -0,0 +1,77 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Debugging Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * 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 + +typedef struct rdpdbg_plugin rdpdbgPlugin; +struct rdpdbg_plugin +{ + rdpSvcPlugin plugin; +}; + +static void rdpdbg_process_connect(rdpSvcPlugin* plugin) +{ + printf("rdpdbg_process_connect\n"); +} + +static void rdpdbg_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) +{ + STREAM* data_out; + + printf("rdpdbg_process_receive: size %d\n", stream_get_size(data_in)); + stream_free(data_in); + + data_out = stream_new(8); + stream_write(data_out, "senddata", 8); + svc_plugin_send(plugin, data_out); +} + +static void rdpdbg_process_terminate(rdpSvcPlugin* plugin) +{ + printf("rdpdbg_process_terminate\n"); + xfree(plugin); +} + +int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +{ + rdpdbgPlugin* rdpdbg; + + rdpdbg = (rdpdbgPlugin*)xmalloc(sizeof(rdpdbgPlugin)); + memset(rdpdbg, 0, sizeof(rdpdbgPlugin)); + + rdpdbg->plugin.channel_entry_points = *pEntryPoints; + rdpdbg->plugin.channel_def.options = CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; + strcpy(rdpdbg->plugin.channel_def.name, "rdpdbg"); + + rdpdbg->plugin.connect_callback = rdpdbg_process_connect; + rdpdbg->plugin.receive_callback = rdpdbg_process_receive; + rdpdbg->plugin.terminate_callback = rdpdbg_process_terminate; + + svc_plugin_init((rdpSvcPlugin*)rdpdbg); + + return 1; +} From d0a5273abc27488ddd1f4419e2b13b5872745618 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 22:24:47 +0800 Subject: [PATCH 09/10] cunit/chanman: perform tests on channel data. --- CMakeLists.txt | 2 +- cunit/test_chanman.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ae4bf573..c2d1458cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,5 +87,5 @@ add_subdirectory(libfreerdp-kbd) add_subdirectory(libfreerdp-gdi) add_subdirectory(libfreerdp-chanman) add_subdirectory(libfreerdp-core) - +add_subdirectory(channels) add_subdirectory(freerdp-ui) diff --git a/cunit/test_chanman.c b/cunit/test_chanman.c index 931da8ddf..882368f82 100644 --- a/cunit/test_chanman.c +++ b/cunit/test_chanman.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "test_chanman.h" @@ -46,13 +47,31 @@ int add_chanman_suite(void) return 0; } +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_chanman(void) { rdpChanMan* chan_man; rdpSettings settings = { 0 }; + rdpInst inst = { 0 }; + + 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/rdpdbg/rdpdbg.so", NULL); + freerdp_chanman_pre_connect(chan_man, &inst); + freerdp_chanman_post_connect(chan_man, &inst); + + freerdp_chanman_data(&inst, 0, "testdata", 8, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 8); + + freerdp_chanman_check_fds(chan_man, &inst); + freerdp_chanman_close(chan_man, NULL); freerdp_chanman_free(chan_man); } From db86291c038acb22426aa5b4a69efac077d050bf Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sun, 10 Jul 2011 22:25:40 +0800 Subject: [PATCH 10/10] Add install_manifest.txt to .gitignore. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5fb272369..d78aa8e44 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ cmake_install.cmake CMakeFiles/ CMakeCache.txt config.h +install_manifest.txt # Make Makefile