From 3a407c24b80c32188526c4f97f6e792036986c3f Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Fri, 13 Apr 2012 15:58:28 +0800 Subject: [PATCH] server: implement user-initiated disconnection sequence on server. --- include/freerdp/peer.h | 2 ++ libfreerdp-core/peer.c | 13 +++++++++++++ server/test/tfreerdp.c | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/include/freerdp/peer.h b/include/freerdp/peer.h index 16504101a..e16cfd6a5 100644 --- a/include/freerdp/peer.h +++ b/include/freerdp/peer.h @@ -32,6 +32,7 @@ typedef void (*psPeerContextFree)(freerdp_peer* client, rdpContext* context); typedef boolean (*psPeerInitialize)(freerdp_peer* client); typedef boolean (*psPeerGetFileDescriptor)(freerdp_peer* client, void** rfds, int* rcount); typedef boolean (*psPeerCheckFileDescriptor)(freerdp_peer* client); +typedef boolean (*psPeerClose)(freerdp_peer* client); typedef void (*psPeerDisconnect)(freerdp_peer* client); typedef boolean (*psPeerCapabilities)(freerdp_peer* client); typedef boolean (*psPeerPostConnect)(freerdp_peer* client); @@ -57,6 +58,7 @@ struct rdp_freerdp_peer psPeerInitialize Initialize; psPeerGetFileDescriptor GetFileDescriptor; psPeerCheckFileDescriptor CheckFileDescriptor; + psPeerClose Close; psPeerDisconnect Disconnect; psPeerCapabilities Capabilities; diff --git a/libfreerdp-core/peer.c b/libfreerdp-core/peer.c index 856e5522a..44091e0d6 100644 --- a/libfreerdp-core/peer.c +++ b/libfreerdp-core/peer.c @@ -294,6 +294,18 @@ static boolean peer_recv_callback(rdpTransport* transport, STREAM* s, void* extr return true; } +static boolean freerdp_peer_close(freerdp_peer* client) +{ + /** + * [MS-RDPBCGR] 1.3.1.4.2 User-Initiated Disconnection Sequence on Server + * The server first sends the client a Deactivate All PDU followed by an + * optional MCS Disconnect Provider Ultimatum PDU. + */ + if (!rdp_send_deactivate_all(client->context->rdp)) + return false; + return mcs_send_disconnect_provider_ultimatum(client->context->rdp->mcs); +} + static void freerdp_peer_disconnect(freerdp_peer* client) { transport_disconnect(client->context->rdp->transport); @@ -351,6 +363,7 @@ freerdp_peer* freerdp_peer_new(int sockfd) client->Initialize = freerdp_peer_initialize; client->GetFileDescriptor = freerdp_peer_get_fds; client->CheckFileDescriptor = freerdp_peer_check_fds; + client->Close = freerdp_peer_close; client->Disconnect = freerdp_peer_disconnect; client->SendChannelData = freerdp_peer_send_channel_data; } diff --git a/server/test/tfreerdp.c b/server/test/tfreerdp.c index 7895e76f5..3686f1d63 100644 --- a/server/test/tfreerdp.c +++ b/server/test/tfreerdp.c @@ -524,6 +524,10 @@ void tf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code) WTSVirtualChannelWrite(context->debug_channel, (uint8*) "test2", 5, NULL); } } + else if ((flags & 0x4000) && code == 0x2D) /* 'x' key */ + { + client->Close(client); + } } void tf_peer_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code)