From b1ee431a3eaba4c1af27050e28f1a92a41b01c10 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Mon, 12 Dec 2011 14:12:16 +0800 Subject: [PATCH] wtsvc: implement channel open/close. --- libfreerdp-channels/CMakeLists.txt | 3 +- libfreerdp-channels/wtsvc.c | 49 +++++++++++++++++++++++++++--- libfreerdp-channels/wtsvc.h | 41 +++++++++++++++++++++++++ server/test/CMakeLists.txt | 1 + server/test/tfreerdp.c | 21 +++++++++++++ 5 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 libfreerdp-channels/wtsvc.h diff --git a/libfreerdp-channels/CMakeLists.txt b/libfreerdp-channels/CMakeLists.txt index da2283d09..55a139a94 100644 --- a/libfreerdp-channels/CMakeLists.txt +++ b/libfreerdp-channels/CMakeLists.txt @@ -20,7 +20,8 @@ set(FREERDP_CHANNELS_SRCS libchannels.c libchannels.h - wtsvc.c) + wtsvc.c + wtsvc.h) add_library(freerdp-channels ${FREERDP_CHANNELS_SRCS}) diff --git a/libfreerdp-channels/wtsvc.c b/libfreerdp-channels/wtsvc.c index 786933865..24d68ea4e 100644 --- a/libfreerdp-channels/wtsvc.c +++ b/libfreerdp-channels/wtsvc.c @@ -21,16 +21,52 @@ #include #include #include -#include #include -#include + +#include "wtsvc.h" void* WTSVirtualChannelOpenEx( /* __in */ freerdp_peer* client, /* __in */ const char* pVirtualName, /* __in */ uint32 flags) { - return NULL; + int i; + int len; + rdpPeerChannel* channel; + const char* channel_name; + + channel_name = ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0 ? "drdynvc" : pVirtualName); + + len = strlen(channel_name); + if (len > 8) + return NULL; + + for (i = 0; i < client->settings->num_channels; i++) + { + if (client->settings->channels[i].joined && + strncmp(client->settings->channels[i].name, channel_name, len) == 0) + { + break; + } + } + if (i >= client->settings->num_channels) + return NULL; + + channel = xnew(rdpPeerChannel); + channel->client = client; + channel->channel_id = client->settings->channels[i].channel_id; + if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0) + { + channel->channel_type = RDP_PEER_CHANNEL_TYPE_DVC; + + /* TODO: do DVC channel initialization here using pVirtualName */ + } + else + { + channel->channel_type = RDP_PEER_CHANNEL_TYPE_SVC; + } + + return channel; } boolean WTSVirtualChannelQuery( @@ -69,5 +105,10 @@ boolean WTSVirtualChannelWrite( boolean WTSVirtualChannelClose( /* __in */ void* hChannelHandle) { - return false; + rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; + + if (channel != NULL) + xfree(channel); + + return true; } diff --git a/libfreerdp-channels/wtsvc.h b/libfreerdp-channels/wtsvc.h new file mode 100644 index 000000000..795e4090b --- /dev/null +++ b/libfreerdp-channels/wtsvc.h @@ -0,0 +1,41 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Server Virtual Channel Interface + * + * Copyright 2011-2012 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 __WTSVC_H +#define __WTSVC_H + +#include +#include +#include +#include + +enum +{ + RDP_PEER_CHANNEL_TYPE_SVC = 0, + RDP_PEER_CHANNEL_TYPE_DVC = 1 +}; + +typedef struct rdp_peer_channel +{ + freerdp_peer* client; + uint16 channel_id; + uint16 channel_type; +} rdpPeerChannel; + +#endif /* __WTSVC_H */ diff --git a/server/test/CMakeLists.txt b/server/test/CMakeLists.txt index 842b8617c..eb930231e 100644 --- a/server/test/CMakeLists.txt +++ b/server/test/CMakeLists.txt @@ -23,3 +23,4 @@ add_executable(tfreerdp-server target_link_libraries(tfreerdp-server freerdp-core) target_link_libraries(tfreerdp-server freerdp-utils) target_link_libraries(tfreerdp-server freerdp-codec) +target_link_libraries(tfreerdp-server freerdp-channels) diff --git a/server/test/tfreerdp.c b/server/test/tfreerdp.c index ebde3fe8b..78a1a146e 100644 --- a/server/test/tfreerdp.c +++ b/server/test/tfreerdp.c @@ -31,6 +31,7 @@ #include #include #include +#include static char* test_pcap_file = NULL; static boolean test_dump_rfx_realtime = true; @@ -54,6 +55,7 @@ struct test_peer_context int icon_x; int icon_y; boolean activated; + void* debug_channel; }; typedef struct test_peer_context testPeerContext; @@ -319,6 +321,9 @@ void tf_peer_dump_rfx(freerdp_peer* client) boolean tf_peer_post_connect(freerdp_peer* client) { + int i; + testPeerContext* context = (testPeerContext*) client->context; + /** * This callback is called when the entire connection sequence is done, i.e. we've received the * Font List PDU from the client and sent out the Font Map PDU. @@ -342,6 +347,22 @@ boolean tf_peer_post_connect(freerdp_peer* client) /* A real server should tag the peer as activated here and start sending updates in mainloop. */ test_peer_load_icon(client); + /* Iterate all channel names requested by the client and activate those supported by the server */ + for (i = 0; i < client->settings->num_channels; i++) + { + if (client->settings->channels[i].joined) + { + if (strncmp(client->settings->channels[i].name, "rdpdbg", 6) == 0) + { + context->debug_channel = WTSVirtualChannelOpenEx(client, "rdpdbg", 0); + if (context->debug_channel != NULL) + { + printf("Open channel rdpdbg.\n"); + } + } + } + } + /* Return false here would stop the execution of the peer mainloop. */ return true; }