usb-mtp: fix sending files larger than 4gb

MTP requires that if a file is larger than 4gb or if sending data larger
than 4gb, that the length field be set to 0xFFFFFFFF.

Also widened a couple variables to prevent overflow errors.

Signed-off-by: Isaac Lozano <109lozanoi@gmail.com>
Message-id: 01ad8ec7775f58575801ac3f13716f553a16815e.1470477265.git.109lozanoi@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Isaac Lozano 2016-08-06 03:06:01 -07:00 committed by Gerd Hoffmann
parent b53dd4495c
commit 8a5865f331

View File

@ -115,8 +115,8 @@ struct MTPControl {
struct MTPData {
uint16_t code;
uint32_t trans;
uint32_t offset;
uint32_t length;
uint64_t offset;
uint64_t length;
uint32_t alloc;
uint8_t *data;
bool first;
@ -883,7 +883,12 @@ static MTPData *usb_mtp_get_object_info(MTPState *s, MTPControl *c,
usb_mtp_add_u32(d, QEMU_STORAGE_ID);
usb_mtp_add_u16(d, o->format);
usb_mtp_add_u16(d, 0);
usb_mtp_add_u32(d, o->stat.st_size);
if (o->stat.st_size > 0xFFFFFFFF) {
usb_mtp_add_u32(d, 0xFFFFFFFF);
} else {
usb_mtp_add_u32(d, o->stat.st_size);
}
usb_mtp_add_u16(d, 0);
usb_mtp_add_u32(d, 0);
@ -1193,10 +1198,15 @@ static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p)
}
if (s->data_in != NULL) {
MTPData *d = s->data_in;
int dlen = d->length - d->offset;
uint64_t dlen = d->length - d->offset;
if (d->first) {
trace_usb_mtp_data_in(s->dev.addr, d->trans, d->length);
container.length = cpu_to_le32(d->length + sizeof(container));
if (d->length + sizeof(container) > 0xFFFFFFFF) {
container.length = cpu_to_le32(0xFFFFFFFF);
} else {
container.length =
cpu_to_le32(d->length + sizeof(container));
}
container.type = cpu_to_le16(TYPE_DATA);
container.code = cpu_to_le16(d->code);
container.trans = cpu_to_le32(d->trans);