diff options
author | Isaac Lozano <109lozanoi@gmail.com> | 2016-08-06 03:06:01 -0700 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2016-09-14 11:17:06 +0200 |
commit | 8a5865f331028e66b4ed233129d7a914c2d5bfc7 (patch) | |
tree | 86d156bbf9942457f33b9784df7bfc8232bc5ee0 /hw/usb | |
parent | b53dd4495ced2432a0b652ea895e651d07336f7e (diff) | |
download | qemu-8a5865f331028e66b4ed233129d7a914c2d5bfc7.zip qemu-8a5865f331028e66b4ed233129d7a914c2d5bfc7.tar.gz qemu-8a5865f331028e66b4ed233129d7a914c2d5bfc7.tar.bz2 |
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>
Diffstat (limited to 'hw/usb')
-rw-r--r-- | hw/usb/dev-mtp.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 1be85ae..869d244 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -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); |