Fix problems with transferring large files

The entire device redirection framework is documented to use 64-bit
offsets rather than 32-bit offsets. This should fix any problems
transfering large files with rdesktop.

Co-Authored-By: gpatel-fr <44170243+gpatel-fr@users.noreply.github.com>
This commit is contained in:
Karl Mikaelsson 2019-01-29 15:58:33 +01:00
parent 4e6787c889
commit 5351182410
7 changed files with 34 additions and 30 deletions

4
disk.c
View File

@ -582,7 +582,7 @@ disk_close(RD_NTHANDLE handle)
} }
static RD_NTSTATUS static RD_NTSTATUS
disk_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) disk_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
int n; int n;
@ -623,7 +623,7 @@ disk_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32
} }
static RD_NTSTATUS static RD_NTSTATUS
disk_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) disk_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
int n; int n;

View File

@ -119,17 +119,17 @@ parallel_close(RD_NTHANDLE handle)
} }
static RD_NTSTATUS static RD_NTSTATUS
parallel_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) parallel_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
UNUSED(offset); UNUSED(offset); /* Offset must always be zero according to MS-RDPESP */
*result = read(handle, data, length); *result = read(handle, data, length);
return RD_STATUS_SUCCESS; return RD_STATUS_SUCCESS;
} }
static RD_NTSTATUS static RD_NTSTATUS
parallel_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) parallel_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
UNUSED(offset); UNUSED(offset); /* Offset must always be zero according to MS-RDPESP */
int rc = RD_STATUS_SUCCESS; int rc = RD_STATUS_SUCCESS;
int n = write(handle, data, length); int n = write(handle, data, length);

View File

@ -144,9 +144,9 @@ printer_close(RD_NTHANDLE handle)
} }
static RD_NTSTATUS static RD_NTSTATUS
printer_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) printer_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
UNUSED(offset); UNUSED(offset); /* Currently unused, MS-RDPEPC reserves for later use */
PRINTER *pprinter_data; PRINTER *pprinter_data;
pprinter_data = get_printer_data(handle); pprinter_data = get_printer_data(handle);

30
rdpdr.c
View File

@ -3,7 +3,7 @@
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008 Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2004-2011 Peter Astrand <astrand@cendio.se> for Cendio AB Copyright 2004-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
Copyright 2010-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB Copyright 2010-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
Copyright 2017 Karl Mikaelsson <derfian@cendio.se> for Cendio AB Copyright 2017-2019 Karl Mikaelsson <derfian@cendio.se> for Cendio AB
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -86,7 +86,8 @@ char *g_rdpdr_clientname = NULL;
/* if multiple IOs are being done on the same FD */ /* if multiple IOs are being done on the same FD */
struct async_iorequest struct async_iorequest
{ {
uint32 fd, major, minor, offset, device, id, length, partial_len; uint32 fd, major, minor, device, id, length, partial_len;
uint64 offset;
long timeout, /* Total timeout */ long timeout, /* Total timeout */
itv_timeout; /* Interval timeout (between serial characters) */ itv_timeout; /* Interval timeout (between serial characters) */
uint8 *buffer; uint8 *buffer;
@ -146,7 +147,7 @@ rdpdr_handle_ok(uint32 device, RD_NTHANDLE handle)
static RD_BOOL static RD_BOOL
add_async_iorequest(uint32 device, uint32 file, uint32 id, uint32 major, uint32 length, add_async_iorequest(uint32 device, uint32 file, uint32 id, uint32 major, uint32 length,
DEVICE_FNS * fns, uint32 total_timeout, uint32 interval_timeout, uint8 * buffer, DEVICE_FNS * fns, uint32 total_timeout, uint32 interval_timeout, uint8 * buffer,
uint32 offset) uint64 offset)
{ {
struct async_iorequest *iorq; struct async_iorequest *iorq;
@ -395,6 +396,7 @@ rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, ui
#endif #endif
} }
/* Processes a DR_DEVICE_IOREQUEST (minus the leading header field) */
static void static void
rdpdr_process_irp(STREAM s) rdpdr_process_irp(STREAM s)
{ {
@ -409,10 +411,11 @@ rdpdr_process_irp(STREAM s)
major, major,
minor, minor,
device, device,
offset,
bytes_out, bytes_out,
share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0; share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0;
uint64 offset;
char *filename; char *filename;
uint32 filename_len; uint32 filename_len;
@ -534,11 +537,12 @@ rdpdr_process_irp(STREAM s)
} }
in_uint32_le(s, length); in_uint32_le(s, length);
in_uint32_le(s, offset); in_uint64_le(s, offset);
in_uint8s(s, 20); /* 20 bytes of padding */
logger(Protocol, Debug, logger(Protocol, Debug,
"rdpdr_process_irp(), IRP Read length=%d, offset=%d", length, "rdpdr_process_irp(), IRP Read length=%d, offset=%ld",
offset); length, offset);
if (!rdpdr_handle_ok(device, file)) if (!rdpdr_handle_ok(device, file))
{ {
@ -588,10 +592,12 @@ rdpdr_process_irp(STREAM s)
} }
in_uint32_le(s, length); in_uint32_le(s, length);
in_uint32_le(s, offset); in_uint64_le(s, offset);
in_uint8s(s, 0x18); in_uint8s(s, 20); /* 20 bytes of padding before WriteData */
logger(Protocol, Debug, "rdpdr_process_irp(), IRP Write length=%d", result); logger(Protocol, Debug,
"rdpdr_process_irp(), IRP Write length=%d, offset=%ld",
result, offset);
if (!rdpdr_handle_ok(device, file)) if (!rdpdr_handle_ok(device, file))
{ {
@ -875,8 +881,8 @@ rdpdr_process(STREAM s)
logger(Protocol, Debug, "rdpdr_process()"); logger(Protocol, Debug, "rdpdr_process()");
/* hexdump(s->p, s->end - s->p); */ /* hexdump(s->p, s->end - s->p); */
in_uint16(s, component); in_uint16(s, component); /* RDPDR_HEADER.Component */
in_uint16(s, pakid); in_uint16(s, pakid); /* RDPDR_HEADER.PacketId */
if (component == RDPDR_CTYP_CORE) if (component == RDPDR_CTYP_CORE)
{ {

View File

@ -120,7 +120,7 @@ scard_close(RD_NTHANDLE handle)
} }
static RD_NTSTATUS static RD_NTSTATUS
scard_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) scard_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
UNUSED(handle); UNUSED(handle);
UNUSED(data); UNUSED(data);
@ -131,7 +131,7 @@ scard_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint3
} }
static RD_NTSTATUS static RD_NTSTATUS
scard_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) scard_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
UNUSED(handle); UNUSED(handle);
UNUSED(data); UNUSED(data);

View File

@ -628,9 +628,9 @@ serial_close(RD_NTHANDLE handle)
} }
static RD_NTSTATUS static RD_NTSTATUS
serial_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) serial_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
UNUSED(offset); UNUSED(offset); /* Offset must always be zero according to MS-RDPESP */
long timeout; long timeout;
SERIAL_DEVICE *pser_inf; SERIAL_DEVICE *pser_inf;
struct termios *ptermios; struct termios *ptermios;
@ -684,13 +684,11 @@ serial_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint
} }
static RD_NTSTATUS static RD_NTSTATUS
serial_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) serial_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset, uint32 * result)
{ {
UNUSED(offset); UNUSED(offset); /* Offset must always be zero according to MS-RDPESP */
SERIAL_DEVICE *pser_inf; SERIAL_DEVICE *pser_inf;
/* FIXME: offset is not used ? */
pser_inf = get_serial_info(handle); pser_inf = get_serial_info(handle);
*result = write(handle, data, length); *result = write(handle, data, length);

View File

@ -219,9 +219,9 @@ typedef struct _DEVICE_FNS
uint32 create_disposition, uint32 flags_and_attributes, uint32 create_disposition, uint32 flags_and_attributes,
char *filename, RD_NTHANDLE * handle); char *filename, RD_NTHANDLE * handle);
RD_NTSTATUS(*close) (RD_NTHANDLE handle); RD_NTSTATUS(*close) (RD_NTHANDLE handle);
RD_NTSTATUS(*read) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, RD_NTSTATUS(*read) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset,
uint32 * result); uint32 * result);
RD_NTSTATUS(*write) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, RD_NTSTATUS(*write) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint64 offset,
uint32 * result); uint32 * result);
RD_NTSTATUS(*device_control) (RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out); RD_NTSTATUS(*device_control) (RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out);
} }