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);
|
enum NTSTATUS IoStatus);
|
||||||
|
|
||||||
static void devredir_cvt_slash(char *path);
|
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);
|
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
|
* @return 0 on success, -1 on failure
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
devredir_send_drive_create_request(tui32 device_id,
|
devredir_send_drive_create_request(tui32 device_id,
|
||||||
const char *path,
|
const char *path,
|
||||||
@ -585,7 +586,8 @@ devredir_send_drive_create_request(tui32 device_id,
|
|||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int bytes;
|
int bytes;
|
||||||
int len;
|
int path_len;
|
||||||
|
unsigned int unicode_byte_count;
|
||||||
tui32 SharedAccess;
|
tui32 SharedAccess;
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=\"%s\""
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=\"%s\""
|
||||||
@ -597,10 +599,11 @@ devredir_send_drive_create_request(tui32 device_id,
|
|||||||
FileAttributes, CreateOptions,
|
FileAttributes, CreateOptions,
|
||||||
completion_id);
|
completion_id);
|
||||||
|
|
||||||
/* path in unicode needs this much space */
|
/* Find number of bytes required for Unicode path + terminator */
|
||||||
len = ((g_mbstowcs(NULL, path, 0) * sizeof(twchar)) / 2) + 2;
|
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
|
/* FILE_SHARE_DELETE allows files to be renamed while in use
|
||||||
(in some circumstances) */
|
(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, SharedAccess); /* SharedAccess */
|
||||||
xstream_wr_u32_le(s, CreateDisposition); /* CreateDisposition */
|
xstream_wr_u32_le(s, CreateDisposition); /* CreateDisposition */
|
||||||
xstream_wr_u32_le(s, CreateOptions); /* CreateOptions */
|
xstream_wr_u32_le(s, CreateOptions); /* CreateOptions */
|
||||||
xstream_wr_u32_le(s, len); /* PathLength */
|
xstream_wr_u32_le(s, unicode_byte_count);/* PathLength */
|
||||||
devredir_cvt_to_unicode(s->p, path); /* path in unicode */
|
out_utf8_as_utf16_le(s, path, path_len); /* Path */
|
||||||
xstream_seek(s, len);
|
|
||||||
|
|
||||||
/* send to client */
|
/* send to client */
|
||||||
bytes = xstream_len(s);
|
bytes = xstream_len(s);
|
||||||
@ -671,34 +673,31 @@ devredir_send_drive_close_request(tui16 Component, tui16 PacketId,
|
|||||||
/**
|
/**
|
||||||
* @brief ask client to enumerate directory
|
* @brief ask client to enumerate directory
|
||||||
*
|
*
|
||||||
* Server Drive Query Directory Request
|
* See [MS-RDPEFS] 2.2.3.3.10 (DR_DRIVE_QUERY_DIRECTORY_REQ)
|
||||||
* DR_DRIVE_QUERY_DIRECTORY_REQ
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
// LK_TODO Path needs to be Unicode
|
|
||||||
static void
|
static void
|
||||||
devredir_send_drive_dir_request(IRP *irp, tui32 device_id,
|
devredir_send_drive_dir_request(IRP *irp, tui32 device_id,
|
||||||
tui32 InitialQuery, char *Path)
|
tui32 InitialQuery, char *Path)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int bytes;
|
int bytes;
|
||||||
char upath[4096]; // LK_TODO need to malloc this
|
unsigned int path_len;
|
||||||
int path_len = 0;
|
unsigned int unicode_byte_count;
|
||||||
|
|
||||||
/* during Initial Query, Path cannot be NULL */
|
/* during Initial Query, Path cannot be NULL */
|
||||||
if (InitialQuery)
|
if (InitialQuery && Path != NULL)
|
||||||
{
|
{
|
||||||
if (Path == NULL)
|
/* Find number of words required for Unicode path */
|
||||||
{
|
path_len = strlen(Path) + 1; // includes terminator
|
||||||
return;
|
unicode_byte_count = utf8_as_utf16_word_count(Path, path_len) * 2;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Path in unicode needs this much space */
|
{
|
||||||
path_len = ((g_mbstowcs(NULL, Path, 0) * sizeof(twchar)) / 2) + 2;
|
path_len = 0;
|
||||||
devredir_cvt_to_unicode(upath, Path);
|
unicode_byte_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
xstream_new(s, 1024 + path_len);
|
xstream_new(s, (int)(64 + unicode_byte_count));
|
||||||
|
|
||||||
irp->completion_type = CID_DIRECTORY_CONTROL;
|
irp->completion_type = CID_DIRECTORY_CONTROL;
|
||||||
devredir_insert_DeviceIoRequest(s,
|
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_u32_le(s, FileDirectoryInformation); /* FsInformationClass */
|
||||||
xstream_wr_u8(s, InitialQuery); /* InitialQuery */
|
xstream_wr_u8(s, InitialQuery); /* InitialQuery */
|
||||||
|
|
||||||
if (!InitialQuery)
|
xstream_wr_u32_le(s, unicode_byte_count); /* PathLength */
|
||||||
{
|
xstream_seek(s, 23); /* Padding */
|
||||||
xstream_wr_u32_le(s, 0); /* PathLength */
|
out_utf8_as_utf16_le(s, Path, path_len); /* Path */
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send to client */
|
/* send to client */
|
||||||
bytes = xstream_len(s);
|
bytes = xstream_len(s);
|
||||||
@ -1191,6 +1182,7 @@ devredir_proc_query_dir_response(IRP *irp,
|
|||||||
tui32 FileAttributes;
|
tui32 FileAttributes;
|
||||||
tui32 FileNameLength;
|
tui32 FileNameLength;
|
||||||
struct file_attr fattr;
|
struct file_attr fattr;
|
||||||
|
unsigned int flen;
|
||||||
|
|
||||||
xstream_rd_u32_le(s_in, NextEntryOffset);
|
xstream_rd_u32_le(s_in, NextEntryOffset);
|
||||||
xstream_seek(s_in, 4); /* FileIndex */
|
xstream_seek(s_in, 4); /* FileIndex */
|
||||||
@ -1208,8 +1200,14 @@ devredir_proc_query_dir_response(IRP *irp,
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
flen = in_utf16_le_fixed_as_utf8(s_in, FileNameLength / 2,
|
||||||
devredir_cvt_from_unicode_len(filename, s_in->p, FileNameLength);
|
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, "LastAccessTime: 0x%llx", LastAccessTime);
|
||||||
//LOG_DEVEL(LOG_LEVEL_DEBUG, "LastWriteTime: 0x%llx", LastWriteTime);
|
//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
|
static int
|
||||||
devredir_string_ends_with(const char *string, char c)
|
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);
|
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
|
static void
|
||||||
devredir_proc_cid_rename_file(IRP *irp, enum NTSTATUS IoStatus)
|
devredir_proc_cid_rename_file(IRP *irp, enum NTSTATUS IoStatus)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int bytes;
|
int bytes;
|
||||||
int sblen; /* SetBuffer length */
|
unsigned int flen; /* FileNameLength */
|
||||||
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)
|
if (IoStatus != STATUS_SUCCESS)
|
||||||
@ -2021,12 +1964,13 @@ devredir_proc_cid_rename_file(IRP *irp, enum NTSTATUS IoStatus)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Path in unicode needs this much space */
|
/* Find number of words required for Unicode path */
|
||||||
flen = ((g_mbstowcs(NULL, irp->gen.rename.new_name, 0)
|
flen = strlen(irp->gen.rename.new_name) + 1; // includes terminator
|
||||||
* sizeof(twchar)) / 2) + 2;
|
unicode_byte_count = utf8_as_utf16_word_count(irp->gen.rename.new_name, flen) * 2;
|
||||||
sblen = 6 + flen;
|
/* 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;
|
irp->completion_type = CID_RENAME_FILE_RESP;
|
||||||
devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId,
|
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_seek(s, 24); /* padding */
|
||||||
xstream_wr_u8(s, 1); /* ReplaceIfExists */
|
xstream_wr_u8(s, 1); /* ReplaceIfExists */
|
||||||
xstream_wr_u8(s, 0); /* RootDirectory */
|
xstream_wr_u8(s, 0); /* RootDirectory */
|
||||||
xstream_wr_u32_le(s, flen); /* FileNameLength */
|
xstream_wr_u32_le(s, unicode_byte_count); /* FileNameLength */
|
||||||
|
/* filename in Unicode */
|
||||||
/* filename in unicode */
|
out_utf8_as_utf16_le(s, irp->gen.rename.new_name, flen);
|
||||||
devredir_cvt_to_unicode(s->p, irp->gen.rename.new_name); /* UNICODE_TODO */
|
|
||||||
xstream_seek(s, flen);
|
|
||||||
|
|
||||||
/* send to client */
|
/* send to client */
|
||||||
bytes = xstream_len(s);
|
bytes = xstream_len(s);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user