diff --git a/disk.c b/disk.c index 4cff552..5ebede6 100644 --- a/disk.c +++ b/disk.c @@ -582,7 +582,7 @@ disk_close(RD_NTHANDLE handle) } 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; @@ -623,7 +623,7 @@ disk_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 } 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; diff --git a/parallel.c b/parallel.c index 0f7874d..8b95fc1 100644 --- a/parallel.c +++ b/parallel.c @@ -119,17 +119,17 @@ parallel_close(RD_NTHANDLE handle) } 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); return RD_STATUS_SUCCESS; } 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 n = write(handle, data, length); diff --git a/printer.c b/printer.c index 6b77d5a..eba1de2 100644 --- a/printer.c +++ b/printer.c @@ -144,9 +144,9 @@ printer_close(RD_NTHANDLE handle) } 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; pprinter_data = get_printer_data(handle); diff --git a/rdpdr.c b/rdpdr.c index a271b49..df53746 100644 --- a/rdpdr.c +++ b/rdpdr.c @@ -3,7 +3,7 @@ Copyright (C) Matthew Chapman 1999-2008 Copyright 2004-2011 Peter Astrand for Cendio AB Copyright 2010-2017 Henrik Andersson for Cendio AB - Copyright 2017 Karl Mikaelsson for Cendio AB + Copyright 2017-2019 Karl Mikaelsson for Cendio AB 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 @@ -86,7 +86,8 @@ char *g_rdpdr_clientname = NULL; /* if multiple IOs are being done on the same FD */ 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 */ itv_timeout; /* Interval timeout (between serial characters) */ uint8 *buffer; @@ -146,7 +147,7 @@ rdpdr_handle_ok(uint32 device, RD_NTHANDLE handle) static RD_BOOL add_async_iorequest(uint32 device, uint32 file, uint32 id, uint32 major, uint32 length, DEVICE_FNS * fns, uint32 total_timeout, uint32 interval_timeout, uint8 * buffer, - uint32 offset) + uint64 offset) { struct async_iorequest *iorq; @@ -395,6 +396,7 @@ rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, ui #endif } +/* Processes a DR_DEVICE_IOREQUEST (minus the leading header field) */ static void rdpdr_process_irp(STREAM s) { @@ -409,10 +411,11 @@ rdpdr_process_irp(STREAM s) major, minor, device, - offset, bytes_out, share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0; + uint64 offset; + char *filename; uint32 filename_len; @@ -534,11 +537,12 @@ rdpdr_process_irp(STREAM s) } 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, - "rdpdr_process_irp(), IRP Read length=%d, offset=%d", length, - offset); + "rdpdr_process_irp(), IRP Read length=%d, offset=%ld", + length, offset); if (!rdpdr_handle_ok(device, file)) { @@ -588,10 +592,12 @@ rdpdr_process_irp(STREAM s) } in_uint32_le(s, length); - in_uint32_le(s, offset); - in_uint8s(s, 0x18); + in_uint64_le(s, offset); + 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)) { @@ -875,8 +881,8 @@ rdpdr_process(STREAM s) logger(Protocol, Debug, "rdpdr_process()"); /* hexdump(s->p, s->end - s->p); */ - in_uint16(s, component); - in_uint16(s, pakid); + in_uint16(s, component); /* RDPDR_HEADER.Component */ + in_uint16(s, pakid); /* RDPDR_HEADER.PacketId */ if (component == RDPDR_CTYP_CORE) { diff --git a/scard.c b/scard.c index d7b1e96..1a268fc 100644 --- a/scard.c +++ b/scard.c @@ -120,7 +120,7 @@ scard_close(RD_NTHANDLE handle) } 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(data); @@ -131,7 +131,7 @@ scard_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint3 } 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(data); diff --git a/serial.c b/serial.c index d13a1a1..700f3f3 100644 --- a/serial.c +++ b/serial.c @@ -628,9 +628,9 @@ serial_close(RD_NTHANDLE handle) } 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; SERIAL_DEVICE *pser_inf; struct termios *ptermios; @@ -684,13 +684,11 @@ serial_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint } 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; - /* FIXME: offset is not used ? */ - pser_inf = get_serial_info(handle); *result = write(handle, data, length); diff --git a/stream.h b/stream.h index a9196e5..3058b59 100644 --- a/stream.h +++ b/stream.h @@ -3,6 +3,7 @@ Parsing primitives Copyright (C) Matthew Chapman 1999-2008 Copyright 2012-2017 Henrik Andersson for Cendio AB + Copyright 2019 Karl Mikaelsson for Cendio AB 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 @@ -62,42 +63,56 @@ size_t in_ansi_string(STREAM s, char *string, size_t len); #if defined(L_ENDIAN) && !defined(NEED_ALIGN) #define in_uint16_le(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; } #define in_uint32_le(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; } +#define in_uint64_le(s,v) { v = *(uint64 *)((s)->p); (s)->p += 8; } #define out_uint16_le(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; } #define out_uint32_le(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; } +#define out_uint64_le(s,v) { *(uint64 *)((s)->p) = v; (s)->p += 8; } #else #define in_uint16_le(s,v) { v = *((s)->p++); v += *((s)->p++) << 8; } #define in_uint32_le(s,v) { in_uint16_le(s,v) \ v += *((s)->p++) << 16; v += *((s)->p++) << 24; } +#define in_uint64_le(s,v) { in_uint32_le(s,v) \ + v += *((s)->p++) << 32; v += *((s)->p++) << 40; \ + v += *((s)->p++) << 48; v += *((s)->p++) << 56; } #define out_uint16_le(s,v) { *((s)->p++) = (v) & 0xff; *((s)->p++) = ((v) >> 8) & 0xff; } #define out_uint32_le(s,v) { out_uint16_le(s, (v) & 0xffff); out_uint16_le(s, ((v) >> 16) & 0xffff); } +#define out_uint64_le(s,v) { out_uint32_le(s, (v) & 0xffffffff); out_uint32_le(s, ((v) >> 32) & 0xffffffff); } #endif -#define out_uint64_le(s,v) { out_uint32_le(s, (v) & 0xffffffff); out_uint32_le(s, ((v) >> 32) & 0xffffffff); } #if defined(B_ENDIAN) && !defined(NEED_ALIGN) #define in_uint16_be(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; } #define in_uint32_be(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; } +#define in_uint64_be(s,v) { v = *(uint64 *)((s)->p); (s)->p += 8; } #define out_uint16_be(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; } #define out_uint32_be(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; } +#define out_uint64_be(s,v) { *(uint64 *)((s)->p) = v; (s)->p += 8; } #define B_ENDIAN_PREFERRED #define in_uint16(s,v) in_uint16_be(s,v) #define in_uint32(s,v) in_uint32_be(s,v) +#define in_uint64(s,v) in_uint64_be(s,v) + #define out_uint16(s,v) out_uint16_be(s,v) #define out_uint32(s,v) out_uint32_be(s,v) +#define out_uint64(s,v) out_uint64_be(s,v) #else #define in_uint16_be(s,v) { v = *((s)->p++); next_be(s,v); } #define in_uint32_be(s,v) { in_uint16_be(s,v); next_be(s,v); next_be(s,v); } +#define in_uint64_be(s,v) { in_uint32_be(s,v); next_be(s,v); next_be(s,v); next_be(s,v); next_be(s,v); } #define out_uint16_be(s,v) { *((s)->p++) = ((v) >> 8) & 0xff; *((s)->p++) = (v) & 0xff; } #define out_uint32_be(s,v) { out_uint16_be(s, ((v) >> 16) & 0xffff); out_uint16_be(s, (v) & 0xffff); } +#define out_uint64_be(s,v) { out_uint32_be(s, ((v) >> 32) & 0xffffffff); out_uint32_be(s, (v) & 0xffffffff); } #endif #ifndef B_ENDIAN_PREFERRED #define in_uint16(s,v) in_uint16_le(s,v) #define in_uint32(s,v) in_uint32_le(s,v) +#define in_uint64(s,v) in_uint64_le(s,v) #define out_uint16(s,v) out_uint16_le(s,v) #define out_uint32(s,v) out_uint32_le(s,v) +#define out_uint64(s,v) out_uint64_le(s,v) #endif #define in_uint8(s,v) v = *((s)->p++); diff --git a/types.h b/types.h index 4556ab4..67e3edb 100644 --- a/types.h +++ b/types.h @@ -22,6 +22,7 @@ #ifndef _TYPES_H #define _TYPES_H +#include #include "constants.h" #include "stream.h" @@ -42,6 +43,8 @@ typedef unsigned short uint16; typedef signed short sint16; typedef unsigned int uint32; typedef signed int sint32; +typedef uint64_t uint64; +typedef int64_t sint64; #define RD_UINT32_MAX (uint32)(-1) @@ -216,9 +219,9 @@ typedef struct _DEVICE_FNS uint32 create_disposition, uint32 flags_and_attributes, char *filename, 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); - 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); RD_NTSTATUS(*device_control) (RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out); }