diff --git a/disk.c b/disk.c index 223d64b..81d3cdb 100644 --- a/disk.c +++ b/disk.c @@ -3,6 +3,7 @@ Disk Redirection Copyright (C) Jeroen Meijer 2003-2008 Copyright 2003-2011 Peter Astrand for Cendio AB + Copyright 2017 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 @@ -315,6 +316,7 @@ disk_enum_devices(uint32 * id, char *optarg) char *pos = optarg; char *pos2; int count = 0; + DISK_DEVICE *pdisk_data; /* skip the first colon */ optarg++; @@ -322,14 +324,16 @@ disk_enum_devices(uint32 * id, char *optarg) { pos2 = next_arg(optarg, '='); + pdisk_data = (DISK_DEVICE *) xmalloc(sizeof(DISK_DEVICE)); + memset(pdisk_data, 0, sizeof(DISK_DEVICE)); + strncpy(pdisk_data->name, optarg, sizeof(pdisk_data->name) - 1); strncpy(g_rdpdr_device[*id].name, optarg, sizeof(g_rdpdr_device[*id].name) - 1); - if (strlen(optarg) > (sizeof(g_rdpdr_device[*id].name) - 1)) - fprintf(stderr, "share name %s truncated to %s\n", optarg, - g_rdpdr_device[*id].name); g_rdpdr_device[*id].local_path = (char *) xmalloc(strlen(pos2) + 1); strcpy(g_rdpdr_device[*id].local_path, pos2); g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK; + g_rdpdr_device[*id].pdevice_data = (void *) pdisk_data; + count++; (*id)++; diff --git a/rdpdr.c b/rdpdr.c index 92f6078..ad2cb56 100644 --- a/rdpdr.c +++ b/rdpdr.c @@ -235,22 +235,35 @@ announcedata_size() { int size, i; PRINTER *printerinfo; + DISK_DEVICE *diskinfo; - size = 8; /* static announce size */ - size += g_num_devices * 0x14; + size = 8; /* Header + DeviceCount */ for (i = 0; i < g_num_devices; i++) { - if (g_rdpdr_device[i].device_type == DEVICE_TYPE_PRINTER) - { - printerinfo = (PRINTER *) g_rdpdr_device[i].pdevice_data; - printerinfo->bloblen = - printercache_load_blob(printerinfo->printer, &(printerinfo->blob)); + size += 4; /* DeviceType */ + size += 4; /* DeviceId */ + size += 8; /* PreferredDosName */ + size += 4; /* DeviceDataLength */ - size += 0x18; - size += 2 * strlen(printerinfo->driver) + 2; - size += 2 * strlen(printerinfo->printer) + 2; - size += printerinfo->bloblen; + switch (g_rdpdr_device[i].device_type) + { + case DEVICE_TYPE_DISK: + diskinfo = (DISK_DEVICE *) g_rdpdr_device[i].pdevice_data; + size += 2 * strlen(diskinfo->name) + 2; + break; + case DEVICE_TYPE_PRINTER: + printerinfo = (PRINTER *) g_rdpdr_device[i].pdevice_data; + printerinfo->bloblen = + printercache_load_blob(printerinfo->printer, &(printerinfo->blob)); + + size += 0x18; + size += 2 * strlen(printerinfo->driver) + 2; + size += 2 * strlen(printerinfo->printer) + 2; + size += printerinfo->bloblen; + break; + default: + break; } } @@ -261,10 +274,11 @@ static void rdpdr_send_client_device_list_announce(void) { /* DR_CORE_CLIENT_ANNOUNCE_RSP */ - uint32 driverlen, printerlen, bloblen; + uint32 driverlen, printerlen, bloblen, disklen; int i; STREAM s; PRINTER *printerinfo; + DISK_DEVICE *diskinfo; s = channel_init(rdpdr_channel, announcedata_size()); out_uint16_le(s, RDPDR_CTYP_CORE); @@ -272,16 +286,27 @@ rdpdr_send_client_device_list_announce(void) out_uint32_le(s, g_num_devices); - for (i = 0; i < g_num_devices; i++) + for (i = 0; i < g_num_devices; i++) /* DEVICE_ANNOUNCE */ { out_uint32_le(s, g_rdpdr_device[i].device_type); out_uint32_le(s, i); /* RDP Device ID */ - /* Is it possible to use share names longer than 8 chars? - /astrand */ - out_uint8p(s, g_rdpdr_device[i].name, 8); - + out_uint8p(s, g_rdpdr_device[i].name, 8); /* preferredDosName, limited to 8 characters */ switch (g_rdpdr_device[i].device_type) { + case DEVICE_TYPE_DISK: + diskinfo = (DISK_DEVICE *) g_rdpdr_device[i].pdevice_data; + + /* The RDP specification says that the DeviceData is supposed to be + a null-terminated Unicode string, but that does not work. In + practice the string is expected to be an ASCII string, like a + variable-length preferredDosName. */ + + disklen = strlen(diskinfo->name) + 1; + + out_uint32_le(s, disklen); /* DeviceDataLength */ + out_uint8p(s, diskinfo->name, disklen); /* DeviceData */ + break; + case DEVICE_TYPE_PRINTER: printerinfo = (PRINTER *) g_rdpdr_device[i].pdevice_data; @@ -786,7 +811,7 @@ rdpdr_send_client_capability_response(void) out_uint16_le(s, CAP_DRIVE_TYPE); /* CapabilityType */ out_uint16_le(s, 8); /* CapabilityLength */ - out_uint32_le(s, DRIVE_CAPABILITY_VERSION_01); /* Version */ + out_uint32_le(s, DRIVE_CAPABILITY_VERSION_02); /* Version */ out_uint16_le(s, CAP_SMARTCARD_TYPE); /* CapabilityType */ out_uint16_le(s, 8); /* CapabilityLength */ diff --git a/types.h b/types.h index c78d0e4..3e8089d 100644 --- a/types.h +++ b/types.h @@ -3,6 +3,7 @@ Common data types Copyright (C) Matthew Chapman 1999-2008 Copyright 2014 Henrik Andersson for Cendio AB + Copyright 2017 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 @@ -25,6 +26,10 @@ typedef int RD_BOOL; #define False (0) #endif +#ifndef PATH_MAX +#define PATH_MAX 256 +#endif + typedef unsigned char uint8; typedef signed char sint8; typedef unsigned short uint16; @@ -222,6 +227,12 @@ typedef struct rdpdr_device_info } RDPDR_DEVICE; +typedef struct rdpdr_disk_device_info +{ + char name[PATH_MAX]; +} +DISK_DEVICE; + typedef struct rdpdr_serial_device_info { int dtr; @@ -276,10 +287,6 @@ typedef struct notify_data } NOTIFY; -#ifndef PATH_MAX -#define PATH_MAX 256 -#endif - typedef struct fileinfo { uint32 device_id, flags_and_attributes, accessmask;