Update drive redirection code to use new UTF-8 calls
This commit is contained in:
parent
f8e7fd4c2c
commit
8556f83905
@ -141,8 +141,6 @@ static int devredir_proc_query_dir_response(IRP *irp,
|
||||
enum NTSTATUS IoStatus);
|
||||
|
||||
static void devredir_cvt_slash(char *path);
|
||||
static void devredir_cvt_to_unicode(char *unicode, const char *path);
|
||||
static void devredir_cvt_from_unicode_len(char *path, char *unicode, int len);
|
||||
static int devredir_string_ends_with(const char *string, char c);
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -571,9 +569,12 @@ devredir_send_server_device_announce_resp(tui32 device_id,
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a file system object
|
||||
*
|
||||
* See [MS-RDPEFS] 2.2.1.4.1 (DR_CREATE_REQ)
|
||||
*
|
||||
* @return 0 on success, -1 on failure
|
||||
*****************************************************************************/
|
||||
|
||||
static int
|
||||
devredir_send_drive_create_request(tui32 device_id,
|
||||
const char *path,
|
||||
@ -585,7 +586,8 @@ devredir_send_drive_create_request(tui32 device_id,
|
||||
{
|
||||
struct stream *s;
|
||||
int bytes;
|
||||
int len;
|
||||
int path_len;
|
||||
unsigned int unicode_byte_count;
|
||||
tui32 SharedAccess;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=\"%s\""
|
||||
@ -597,10 +599,11 @@ devredir_send_drive_create_request(tui32 device_id,
|
||||
FileAttributes, CreateOptions,
|
||||
completion_id);
|
||||
|
||||
/* path in unicode needs this much space */
|
||||
len = ((g_mbstowcs(NULL, path, 0) * sizeof(twchar)) / 2) + 2;
|
||||
/* Find number of bytes required for Unicode path + terminator */
|
||||
path_len = strlen(path) + 1; // includes terminator
|
||||
unicode_byte_count = utf8_as_utf16_word_count(path, path_len) * 2;
|
||||
|
||||
xstream_new(s, 1024 + len);
|
||||
xstream_new(s, (int)(64 + unicode_byte_count));
|
||||
|
||||
/* FILE_SHARE_DELETE allows files to be renamed while in use
|
||||
(in some circumstances) */
|
||||
@ -621,9 +624,8 @@ devredir_send_drive_create_request(tui32 device_id,
|
||||
xstream_wr_u32_le(s, SharedAccess); /* SharedAccess */
|
||||
xstream_wr_u32_le(s, CreateDisposition); /* CreateDisposition */
|
||||
xstream_wr_u32_le(s, CreateOptions); /* CreateOptions */
|
||||
xstream_wr_u32_le(s, len); /* PathLength */
|
||||
devredir_cvt_to_unicode(s->p, path); /* path in unicode */
|
||||
xstream_seek(s, len);
|
||||
xstream_wr_u32_le(s, unicode_byte_count);/* PathLength */
|
||||
out_utf8_as_utf16_le(s, path, path_len); /* Path */
|
||||
|
||||
/* send to client */
|
||||
bytes = xstream_len(s);
|
||||
@ -671,34 +673,31 @@ devredir_send_drive_close_request(tui16 Component, tui16 PacketId,
|
||||
/**
|
||||
* @brief ask client to enumerate directory
|
||||
*
|
||||
* Server Drive Query Directory Request
|
||||
* DR_DRIVE_QUERY_DIRECTORY_REQ
|
||||
*
|
||||
* See [MS-RDPEFS] 2.2.3.3.10 (DR_DRIVE_QUERY_DIRECTORY_REQ)
|
||||
*****************************************************************************/
|
||||
// LK_TODO Path needs to be Unicode
|
||||
static void
|
||||
devredir_send_drive_dir_request(IRP *irp, tui32 device_id,
|
||||
tui32 InitialQuery, char *Path)
|
||||
{
|
||||
struct stream *s;
|
||||
int bytes;
|
||||
char upath[4096]; // LK_TODO need to malloc this
|
||||
int path_len = 0;
|
||||
unsigned int path_len;
|
||||
unsigned int unicode_byte_count;
|
||||
|
||||
/* during Initial Query, Path cannot be NULL */
|
||||
if (InitialQuery)
|
||||
if (InitialQuery && Path != NULL)
|
||||
{
|
||||
if (Path == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Path in unicode needs this much space */
|
||||
path_len = ((g_mbstowcs(NULL, Path, 0) * sizeof(twchar)) / 2) + 2;
|
||||
devredir_cvt_to_unicode(upath, Path);
|
||||
/* Find number of words required for Unicode path */
|
||||
path_len = strlen(Path) + 1; // includes terminator
|
||||
unicode_byte_count = utf8_as_utf16_word_count(Path, path_len) * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
path_len = 0;
|
||||
unicode_byte_count = 0;
|
||||
}
|
||||
|
||||
xstream_new(s, 1024 + path_len);
|
||||
xstream_new(s, (int)(64 + unicode_byte_count));
|
||||
|
||||
irp->completion_type = CID_DIRECTORY_CONTROL;
|
||||
devredir_insert_DeviceIoRequest(s,
|
||||
@ -711,17 +710,9 @@ devredir_send_drive_dir_request(IRP *irp, tui32 device_id,
|
||||
xstream_wr_u32_le(s, FileDirectoryInformation); /* FsInformationClass */
|
||||
xstream_wr_u8(s, InitialQuery); /* InitialQuery */
|
||||
|
||||
if (!InitialQuery)
|
||||
{
|
||||
xstream_wr_u32_le(s, 0); /* PathLength */
|
||||
xstream_seek(s, 23);
|
||||
}
|
||||
else
|
||||
{
|
||||
xstream_wr_u32_le(s, path_len); /* PathLength */
|
||||
xstream_seek(s, 23); /* Padding */
|
||||
xstream_wr_string(s, upath, path_len);
|
||||
}
|
||||
xstream_wr_u32_le(s, unicode_byte_count); /* PathLength */
|
||||
xstream_seek(s, 23); /* Padding */
|
||||
out_utf8_as_utf16_le(s, Path, path_len); /* Path */
|
||||
|
||||
/* send to client */
|
||||
bytes = xstream_len(s);
|
||||
@ -1191,6 +1182,7 @@ devredir_proc_query_dir_response(IRP *irp,
|
||||
tui32 FileAttributes;
|
||||
tui32 FileNameLength;
|
||||
struct file_attr fattr;
|
||||
unsigned int flen;
|
||||
|
||||
xstream_rd_u32_le(s_in, NextEntryOffset);
|
||||
xstream_seek(s_in, 4); /* FileIndex */
|
||||
@ -1208,8 +1200,14 @@ devredir_proc_query_dir_response(IRP *irp,
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
devredir_cvt_from_unicode_len(filename, s_in->p, FileNameLength);
|
||||
flen = in_utf16_le_fixed_as_utf8(s_in, FileNameLength / 2,
|
||||
filename, sizeof(filename));
|
||||
if (flen > sizeof(filename))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"Buffer was %d bytes too small for filename",
|
||||
(int)(flen - sizeof(filename)));
|
||||
}
|
||||
|
||||
//LOG_DEVEL(LOG_LEVEL_DEBUG, "LastAccessTime: 0x%llx", LastAccessTime);
|
||||
//LOG_DEVEL(LOG_LEVEL_DEBUG, "LastWriteTime: 0x%llx", LastWriteTime);
|
||||
@ -1876,69 +1874,6 @@ devredir_cvt_slash(char *path)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
devredir_cvt_to_unicode(char *unicode, const char *path)
|
||||
{
|
||||
char *dest;
|
||||
char *src;
|
||||
int rv;
|
||||
int i;
|
||||
|
||||
rv = g_mbstowcs((twchar *) unicode, path, strlen(path));
|
||||
|
||||
/* unicode is typically 4 bytes, but microsoft only uses 2 bytes */
|
||||
|
||||
src = unicode + sizeof(twchar); /* skip 1st unicode char */
|
||||
dest = unicode + 2; /* first char already in place */
|
||||
|
||||
for (i = 1; i < rv; i++)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
*dest++ = *src++;
|
||||
src += 2;
|
||||
}
|
||||
|
||||
*dest++ = 0;
|
||||
*dest++ = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
devredir_cvt_from_unicode_len(char *path, char *unicode, int len)
|
||||
{
|
||||
char *dest;
|
||||
char *dest_saved;
|
||||
char *src;
|
||||
int i;
|
||||
int bytes_to_alloc;
|
||||
int max_bytes;
|
||||
|
||||
bytes_to_alloc = (((len / 2) * sizeof(twchar)) + sizeof(twchar));
|
||||
|
||||
src = unicode;
|
||||
dest = g_new0(char, bytes_to_alloc);
|
||||
dest_saved = dest;
|
||||
|
||||
for (i = 0; i < len; i += 2)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
*dest++ = *src++;
|
||||
dest += 2;
|
||||
}
|
||||
*dest++ = 0;
|
||||
*dest++ = 0;
|
||||
*dest++ = 0;
|
||||
*dest++ = 0;
|
||||
|
||||
max_bytes = wcstombs(NULL, (wchar_t *) dest_saved, 0);
|
||||
if (max_bytes > 0)
|
||||
{
|
||||
wcstombs(path, (wchar_t *) dest_saved, max_bytes);
|
||||
path[max_bytes] = 0;
|
||||
}
|
||||
|
||||
g_free(dest_saved);
|
||||
}
|
||||
|
||||
static int
|
||||
devredir_string_ends_with(const char *string, char c)
|
||||
{
|
||||
@ -2002,13 +1937,21 @@ devredir_proc_cid_rmdir_or_file_resp(IRP *irp, enum NTSTATUS IoStatus)
|
||||
IRP_MJ_CLOSE, IRP_MN_NONE, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a file on response to the create drive request
|
||||
*
|
||||
* See :-
|
||||
* - [MS-RDPEFS] 2.2.3.3.9 (DR_DRIVE_SET_INFORMATION_REQ)`
|
||||
* - [MS-RDPEFS] 2.2.3.3.9.1 (RDP_FILE_RENAME_INFORMATION)
|
||||
*****************************************************************************/
|
||||
static void
|
||||
devredir_proc_cid_rename_file(IRP *irp, enum NTSTATUS IoStatus)
|
||||
{
|
||||
struct stream *s;
|
||||
int bytes;
|
||||
int sblen; /* SetBuffer length */
|
||||
int flen; /* FileNameLength */
|
||||
unsigned int flen; /* FileNameLength */
|
||||
unsigned int unicode_byte_count; /* Bytes to represent new name in UTF-16 */
|
||||
unsigned int sblen; /* SetBuffer length */
|
||||
|
||||
|
||||
if (IoStatus != STATUS_SUCCESS)
|
||||
@ -2021,12 +1964,13 @@ devredir_proc_cid_rename_file(IRP *irp, enum NTSTATUS IoStatus)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Path in unicode needs this much space */
|
||||
flen = ((g_mbstowcs(NULL, irp->gen.rename.new_name, 0)
|
||||
* sizeof(twchar)) / 2) + 2;
|
||||
sblen = 6 + flen;
|
||||
/* Find number of words required for Unicode path */
|
||||
flen = strlen(irp->gen.rename.new_name) + 1; // includes terminator
|
||||
unicode_byte_count = utf8_as_utf16_word_count(irp->gen.rename.new_name, flen) * 2;
|
||||
/* Length of RDP_FILE_RENAME_INFORMATION struct */
|
||||
sblen = (1 + 1 + 4) + unicode_byte_count;
|
||||
|
||||
xstream_new(s, 1024 + flen);
|
||||
xstream_new(s, (int)(64 + unicode_byte_count));
|
||||
|
||||
irp->completion_type = CID_RENAME_FILE_RESP;
|
||||
devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId,
|
||||
@ -2038,11 +1982,9 @@ devredir_proc_cid_rename_file(IRP *irp, enum NTSTATUS IoStatus)
|
||||
xstream_seek(s, 24); /* padding */
|
||||
xstream_wr_u8(s, 1); /* ReplaceIfExists */
|
||||
xstream_wr_u8(s, 0); /* RootDirectory */
|
||||
xstream_wr_u32_le(s, flen); /* FileNameLength */
|
||||
|
||||
/* filename in unicode */
|
||||
devredir_cvt_to_unicode(s->p, irp->gen.rename.new_name); /* UNICODE_TODO */
|
||||
xstream_seek(s, flen);
|
||||
xstream_wr_u32_le(s, unicode_byte_count); /* FileNameLength */
|
||||
/* filename in Unicode */
|
||||
out_utf8_as_utf16_le(s, irp->gen.rename.new_name, flen);
|
||||
|
||||
/* send to client */
|
||||
bytes = xstream_len(s);
|
||||
|
Loading…
Reference in New Issue
Block a user