diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am index 5f443db0..0da15e24 100644 --- a/src/protocols/rdp/Makefile.am +++ b/src/protocols/rdp/Makefile.am @@ -56,7 +56,8 @@ libguac_client_rdp_la_SOURCES = \ rdp_keymap_fr_fr.c \ rdp_keymap_en_us.c \ rdp_pointer.c \ - rdp_settings.c + rdp_settings.c \ + unicode.c guacsnd_sources = \ guac_rdpsnd/rdpsnd_messages.c \ @@ -66,7 +67,8 @@ guacdr_sources = \ guac_rdpdr/rdpdr_fs.c \ guac_rdpdr/rdpdr_messages.c \ guac_rdpdr/rdpdr_printer.c \ - guac_rdpdr/rdpdr_service.c + guac_rdpdr/rdpdr_service.c \ + unicode.c noinst_HEADERS = \ compat/client-cliprdr.h \ @@ -86,7 +88,8 @@ noinst_HEADERS = \ rdp_glyph.h \ rdp_keymap.h \ rdp_pointer.h \ - rdp_settings.h + rdp_settings.h \ + unicode.h # Add compatibility layer for WinPR if not available if ! ENABLE_WINPR diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c index 6025dd6d..05a583bb 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c @@ -47,25 +47,42 @@ #include "rdpdr_fs.h" #include "rdpdr_service.h" #include "client.h" +#include "unicode.h" #include + static void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, wStream* input_stream, int completion_id) { wStream* output_stream = Stream_New(NULL, 21); + int file_id; - /* - uint64_t allocation_size; int desired_access, file_attributes, shared_access; int create_disposition, create_options, path_length; - char* path; - */ + char path[1024]; - int file_id = guac_rdpdr_fs_open(device); + /* Read "create" information */ + Stream_Read_UINT32(input_stream, desired_access); + Stream_Seek_UINT64(input_stream); /* allocation size */ + Stream_Read_UINT32(input_stream, file_attributes); + Stream_Read_UINT32(input_stream, shared_access); + Stream_Read_UINT32(input_stream, create_disposition); + Stream_Read_UINT32(input_stream, create_options); + Stream_Read_UINT32(input_stream, path_length); + + guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path, path_length/2 - 1); + path[path_length-1] = 0; + + /* Open file */ + file_id = guac_rdpdr_fs_open(device); /* FIXME: Assuming file IDs are available */ - guac_client_log_info(device->rdpdr->client, "open: %i", file_id); + guac_client_log_info(device->rdpdr->client, "Opened file %s ... new id=%i", path, file_id); + guac_client_log_info(device->rdpdr->client, + "des=%i, attrib=%i, shared=%i, disp=%i, opt=%i", + desired_access, file_attributes, shared_access, create_disposition, + create_options); /* Write header */ Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE); @@ -99,8 +116,8 @@ static void guac_rdpdr_fs_process_close(guac_rdpdr_device* device, wStream* output_stream = Stream_New(NULL, 21); - /* STUB */ - guac_client_log_info(device->rdpdr->client, "close: %i", file_id); + /* Close file */ + guac_client_log_info(device->rdpdr->client, "Closing file id=%i", file_id); guac_rdpdr_fs_close(device, file_id); /* Write header */ diff --git a/src/protocols/rdp/unicode.c b/src/protocols/rdp/unicode.c new file mode 100644 index 00000000..3152fdff --- /dev/null +++ b/src/protocols/rdp/unicode.c @@ -0,0 +1,106 @@ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is libguac-client-rdp. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include + +int guac_rdp_encode_utf8(int codepoint, char* utf8) { + + int i; + int mask, bytes; + + /* Determine size and initial byte mask */ + if (codepoint <= 0x007F) { + mask = 0x00; + bytes = 1; + } + else if (codepoint <= 0x7FF) { + mask = 0xC0; + bytes = 2; + } + else if (codepoint <= 0xFFFF) { + mask = 0xE0; + bytes = 3; + } + else if (codepoint <= 0x1FFFFF) { + mask = 0xF0; + bytes = 4; + } + + /* Otherwise, invalid codepoint */ + else { + *(utf8++) = '?'; + return 1; + } + + /* Offset buffer by size */ + utf8 += bytes - 1; + + /* Add trailing bytes, if any */ + for (i=1; i>= 6; + } + + /* Set initial byte */ + *utf8 = mask | codepoint; + + /* Done */ + return bytes; + +} + +void guac_rdp_utf16_to_utf8(const unsigned char* utf16, char* utf8, int length) { + + int i; + const uint16_t* in_codepoint = (const uint16_t*) utf16; + + /* For each UTF-16 character */ + for (i=0; i