From e3eeb30e2dd82c106e5b6998bc7d110e90c05ae7 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Fri, 5 Aug 2011 10:24:46 +0800 Subject: [PATCH] rdpdr: implement server/client announce. --- channels/rdpdr/rdpdr_main.c | 66 +++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/channels/rdpdr/rdpdr_main.c b/channels/rdpdr/rdpdr_main.c index 2705dce16..b6c6bf738 100644 --- a/channels/rdpdr/rdpdr_main.c +++ b/channels/rdpdr/rdpdr_main.c @@ -18,6 +18,7 @@ * limitations under the License. */ +#include "config.h" #include #include #include @@ -27,6 +28,10 @@ #include #include +#ifdef HAVE_UNISTD_H +#include +#endif + #include "rdpdr_types.h" #include "rdpdr_constants.h" #include "devman.h" @@ -38,9 +43,10 @@ struct rdpdr_plugin DEVMAN* devman; + uint16 versionMajor; uint16 versionMinor; uint16 clientID; - const char* computerName; + char computerName[256]; }; static void rdpdr_process_connect(rdpSvcPlugin* plugin) @@ -54,7 +60,7 @@ static void rdpdr_process_connect(rdpSvcPlugin* plugin) { if (strcmp((char*)data->data[0], "clientname") == 0) { - rdpdr->computerName = (const char*)data->data[1]; + strncpy(rdpdr->computerName, (char*)data->data[1], sizeof(rdpdr->computerName) - 1); DEBUG_SVC("computerName %s", rdpdr->computerName); } else @@ -65,8 +71,61 @@ static void rdpdr_process_connect(rdpSvcPlugin* plugin) } } +static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + stream_read_uint16(data_in, rdpdr->versionMajor); + stream_read_uint16(data_in, rdpdr->versionMinor); + stream_read_uint32(data_in, rdpdr->clientID); + + DEBUG_SVC("version %d.%d clientID %d", rdpdr->versionMajor, rdpdr->versionMinor, rdpdr->clientID); +} + +static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr) +{ + STREAM* data_out; + + data_out = stream_new(12); + + stream_write_uint16(data_out, RDPDR_CTYP_CORE); + stream_write_uint16(data_out, PAKID_CORE_CLIENTID_CONFIRM); + + stream_write_uint16(data_out, rdpdr->versionMajor); + stream_write_uint16(data_out, rdpdr->versionMinor); + stream_write_uint32(data_out, rdpdr->clientID); + + svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out); +} + +static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) +{ + STREAM* data_out; + size_t computerNameLenW; + UNICONV* uniconv; + char* s; + + uniconv = freerdp_uniconv_new(); + if (!rdpdr->computerName[0]) + gethostname(rdpdr->computerName, sizeof(rdpdr->computerName) - 1); + s = freerdp_uniconv_out(uniconv, rdpdr->computerName, &computerNameLenW); + data_out = stream_new(16 + computerNameLenW + 2); + + stream_write_uint16(data_out, RDPDR_CTYP_CORE); + stream_write_uint16(data_out, PAKID_CORE_CLIENT_NAME); + + stream_write_uint32(data_out, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */ + stream_write_uint32(data_out, 0); /* codePage, must be set to zero */ + stream_write_uint32(data_out, computerNameLenW + 2); /* computerNameLen, including null terminator */ + stream_write(data_out, s, computerNameLenW); + stream_write_uint16(data_out, 0); /* null terminator */ + xfree(s); + freerdp_uniconv_free(uniconv); + + svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out); +} + static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) { + rdpdrPlugin* rdpdr = (rdpdrPlugin*)plugin; uint16 component; uint16 packetID; uint32 deviceID; @@ -81,6 +140,9 @@ static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) { case PAKID_CORE_SERVER_ANNOUNCE: DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_SERVER_ANNOUNCE"); + rdpdr_process_server_announce_request(rdpdr, data_in); + rdpdr_send_client_announce_reply(rdpdr); + rdpdr_send_client_name_request(rdpdr); break; case PAKID_CORE_SERVER_CAPABILITY: