1 /* 2 * Media Transfer Protocol implementation, backed by host filesystem. 3 * 4 * Copyright Red Hat, Inc 2014 5 * 6 * Author: 7 * Gerd Hoffmann <kraxel@redhat.com> 8 * 9 * This code is licensed under the GPL v2 or later. 10 */ 11 12 #include "qemu/osdep.h" 13 #include "qapi/error.h" 14 #include <wchar.h> 15 #include <dirent.h> 16 17 #include <sys/statvfs.h> 18 #ifdef CONFIG_INOTIFY1 19 #include <sys/inotify.h> 20 #include "qemu/main-loop.h" 21 #endif 22 23 #include "qemu-common.h" 24 #include "qemu/iov.h" 25 #include "trace.h" 26 #include "hw/usb.h" 27 #include "desc.h" 28 29 /* ----------------------------------------------------------------------- */ 30 31 enum mtp_container_type { 32 TYPE_COMMAND = 1, 33 TYPE_DATA = 2, 34 TYPE_RESPONSE = 3, 35 TYPE_EVENT = 4, 36 }; 37 38 enum mtp_code { 39 /* command codes */ 40 CMD_GET_DEVICE_INFO = 0x1001, 41 CMD_OPEN_SESSION = 0x1002, 42 CMD_CLOSE_SESSION = 0x1003, 43 CMD_GET_STORAGE_IDS = 0x1004, 44 CMD_GET_STORAGE_INFO = 0x1005, 45 CMD_GET_NUM_OBJECTS = 0x1006, 46 CMD_GET_OBJECT_HANDLES = 0x1007, 47 CMD_GET_OBJECT_INFO = 0x1008, 48 CMD_GET_OBJECT = 0x1009, 49 CMD_DELETE_OBJECT = 0x100b, 50 CMD_SEND_OBJECT_INFO = 0x100c, 51 CMD_SEND_OBJECT = 0x100d, 52 CMD_GET_PARTIAL_OBJECT = 0x101b, 53 CMD_GET_OBJECT_PROPS_SUPPORTED = 0x9801, 54 CMD_GET_OBJECT_PROP_DESC = 0x9802, 55 CMD_GET_OBJECT_PROP_VALUE = 0x9803, 56 57 /* response codes */ 58 RES_OK = 0x2001, 59 RES_GENERAL_ERROR = 0x2002, 60 RES_SESSION_NOT_OPEN = 0x2003, 61 RES_INVALID_TRANSACTION_ID = 0x2004, 62 RES_OPERATION_NOT_SUPPORTED = 0x2005, 63 RES_PARAMETER_NOT_SUPPORTED = 0x2006, 64 RES_INCOMPLETE_TRANSFER = 0x2007, 65 RES_INVALID_STORAGE_ID = 0x2008, 66 RES_INVALID_OBJECT_HANDLE = 0x2009, 67 RES_INVALID_OBJECT_FORMAT_CODE = 0x200b, 68 RES_STORE_FULL = 0x200c, 69 RES_STORE_READ_ONLY = 0x200e, 70 RES_PARTIAL_DELETE = 0x2012, 71 RES_STORE_NOT_AVAILABLE = 0x2013, 72 RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014, 73 RES_INVALID_OBJECTINFO = 0x2015, 74 RES_DESTINATION_UNSUPPORTED = 0x2020, 75 RES_INVALID_PARENT_OBJECT = 0x201a, 76 RES_INVALID_PARAMETER = 0x201d, 77 RES_SESSION_ALREADY_OPEN = 0x201e, 78 RES_INVALID_OBJECT_PROP_CODE = 0xA801, 79 80 /* format codes */ 81 FMT_UNDEFINED_OBJECT = 0x3000, 82 FMT_ASSOCIATION = 0x3001, 83 84 /* event codes */ 85 EVT_OBJ_ADDED = 0x4002, 86 EVT_OBJ_REMOVED = 0x4003, 87 EVT_OBJ_INFO_CHANGED = 0x4007, 88 89 /* object properties */ 90 PROP_STORAGE_ID = 0xDC01, 91 PROP_OBJECT_FORMAT = 0xDC02, 92 PROP_OBJECT_COMPRESSED_SIZE = 0xDC04, 93 PROP_PARENT_OBJECT = 0xDC0B, 94 PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER = 0xDC41, 95 PROP_NAME = 0xDC44, 96 }; 97 98 enum mtp_data_type { 99 DATA_TYPE_UINT16 = 0x0004, 100 DATA_TYPE_UINT32 = 0x0006, 101 DATA_TYPE_UINT64 = 0x0008, 102 DATA_TYPE_UINT128 = 0x000a, 103 DATA_TYPE_STRING = 0xffff, 104 }; 105 106 typedef struct { 107 uint32_t length; 108 uint16_t type; 109 uint16_t code; 110 uint32_t trans; 111 } QEMU_PACKED mtp_container; 112 113 /* ----------------------------------------------------------------------- */ 114 115 typedef struct MTPState MTPState; 116 typedef struct MTPControl MTPControl; 117 typedef struct MTPData MTPData; 118 typedef struct MTPObject MTPObject; 119 120 enum { 121 EP_DATA_IN = 1, 122 EP_DATA_OUT, 123 EP_EVENT, 124 }; 125 126 #ifdef CONFIG_INOTIFY1 127 typedef struct MTPMonEntry MTPMonEntry; 128 129 struct MTPMonEntry { 130 uint32_t event; 131 uint32_t handle; 132 133 QTAILQ_ENTRY(MTPMonEntry) next; 134 }; 135 #endif 136 137 struct MTPControl { 138 uint16_t code; 139 uint32_t trans; 140 int argc; 141 uint32_t argv[5]; 142 }; 143 144 struct MTPData { 145 uint16_t code; 146 uint32_t trans; 147 uint64_t offset; 148 uint64_t length; 149 uint32_t alloc; 150 uint8_t *data; 151 bool first; 152 int fd; 153 }; 154 155 struct MTPObject { 156 uint32_t handle; 157 uint16_t format; 158 char *name; 159 char *path; 160 struct stat stat; 161 #ifdef CONFIG_INOTIFY1 162 /* inotify watch cookie */ 163 int watchfd; 164 #endif 165 MTPObject *parent; 166 uint32_t nchildren; 167 QLIST_HEAD(, MTPObject) children; 168 QLIST_ENTRY(MTPObject) list; 169 bool have_children; 170 QTAILQ_ENTRY(MTPObject) next; 171 }; 172 173 struct MTPState { 174 USBDevice dev; 175 char *root; 176 char *desc; 177 uint32_t flags; 178 179 MTPData *data_in; 180 MTPData *data_out; 181 MTPControl *result; 182 uint32_t session; 183 uint32_t next_handle; 184 bool readonly; 185 186 QTAILQ_HEAD(, MTPObject) objects; 187 #ifdef CONFIG_INOTIFY1 188 /* inotify descriptor */ 189 int inotifyfd; 190 QTAILQ_HEAD(events, MTPMonEntry) events; 191 #endif 192 /* Responder is expecting a write operation */ 193 bool write_pending; 194 struct { 195 uint32_t parent_handle; 196 uint16_t format; 197 uint32_t size; 198 char *filename; 199 } dataset; 200 }; 201 202 /* 203 * ObjectInfo dataset received from initiator 204 * Fields we don't care about are ignored 205 */ 206 typedef struct { 207 uint32_t storage_id; /*unused*/ 208 uint16_t format; 209 uint16_t protection_status; /*unused*/ 210 uint32_t size; 211 uint16_t thumb_format; /*unused*/ 212 uint32_t thumb_comp_sz; /*unused*/ 213 uint32_t thumb_pix_width; /*unused*/ 214 uint32_t thumb_pix_height; /*unused*/ 215 uint32_t image_pix_width; /*unused*/ 216 uint32_t image_pix_height; /*unused*/ 217 uint32_t image_bit_depth; /*unused*/ 218 uint32_t parent; /*unused*/ 219 uint16_t assoc_type; 220 uint32_t assoc_desc; 221 uint32_t seq_no; /*unused*/ 222 uint8_t length; /*part of filename field*/ 223 uint16_t filename[0]; 224 char date_created[0]; /*unused*/ 225 char date_modified[0]; /*unused*/ 226 char keywords[0]; /*unused*/ 227 /* string and other data follows */ 228 } QEMU_PACKED ObjectInfo; 229 230 #define TYPE_USB_MTP "usb-mtp" 231 #define USB_MTP(obj) OBJECT_CHECK(MTPState, (obj), TYPE_USB_MTP) 232 233 #define QEMU_STORAGE_ID 0x00010001 234 235 #define MTP_FLAG_WRITABLE 0 236 237 #define FLAG_SET(_mtp, _flag) ((_mtp)->flags & (1 << (_flag))) 238 239 /* ----------------------------------------------------------------------- */ 240 241 #define MTP_MANUFACTURER "QEMU" 242 #define MTP_PRODUCT "QEMU filesharing" 243 244 enum { 245 STR_MANUFACTURER = 1, 246 STR_PRODUCT, 247 STR_SERIALNUMBER, 248 STR_MTP, 249 STR_CONFIG_FULL, 250 STR_CONFIG_HIGH, 251 STR_CONFIG_SUPER, 252 }; 253 254 static const USBDescStrings desc_strings = { 255 [STR_MANUFACTURER] = MTP_MANUFACTURER, 256 [STR_PRODUCT] = MTP_PRODUCT, 257 [STR_SERIALNUMBER] = "34617", 258 [STR_MTP] = "MTP", 259 [STR_CONFIG_FULL] = "Full speed config (usb 1.1)", 260 [STR_CONFIG_HIGH] = "High speed config (usb 2.0)", 261 [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)", 262 }; 263 264 static const USBDescIface desc_iface_full = { 265 .bInterfaceNumber = 0, 266 .bNumEndpoints = 3, 267 .bInterfaceClass = USB_CLASS_STILL_IMAGE, 268 .bInterfaceSubClass = 0x01, 269 .bInterfaceProtocol = 0x01, 270 .iInterface = STR_MTP, 271 .eps = (USBDescEndpoint[]) { 272 { 273 .bEndpointAddress = USB_DIR_IN | EP_DATA_IN, 274 .bmAttributes = USB_ENDPOINT_XFER_BULK, 275 .wMaxPacketSize = 64, 276 },{ 277 .bEndpointAddress = USB_DIR_OUT | EP_DATA_OUT, 278 .bmAttributes = USB_ENDPOINT_XFER_BULK, 279 .wMaxPacketSize = 64, 280 },{ 281 .bEndpointAddress = USB_DIR_IN | EP_EVENT, 282 .bmAttributes = USB_ENDPOINT_XFER_INT, 283 .wMaxPacketSize = 64, 284 .bInterval = 0x0a, 285 }, 286 } 287 }; 288 289 static const USBDescDevice desc_device_full = { 290 .bcdUSB = 0x0200, 291 .bMaxPacketSize0 = 8, 292 .bNumConfigurations = 1, 293 .confs = (USBDescConfig[]) { 294 { 295 .bNumInterfaces = 1, 296 .bConfigurationValue = 1, 297 .iConfiguration = STR_CONFIG_FULL, 298 .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP, 299 .bMaxPower = 2, 300 .nif = 1, 301 .ifs = &desc_iface_full, 302 }, 303 }, 304 }; 305 306 static const USBDescIface desc_iface_high = { 307 .bInterfaceNumber = 0, 308 .bNumEndpoints = 3, 309 .bInterfaceClass = USB_CLASS_STILL_IMAGE, 310 .bInterfaceSubClass = 0x01, 311 .bInterfaceProtocol = 0x01, 312 .iInterface = STR_MTP, 313 .eps = (USBDescEndpoint[]) { 314 { 315 .bEndpointAddress = USB_DIR_IN | EP_DATA_IN, 316 .bmAttributes = USB_ENDPOINT_XFER_BULK, 317 .wMaxPacketSize = 512, 318 },{ 319 .bEndpointAddress = USB_DIR_OUT | EP_DATA_OUT, 320 .bmAttributes = USB_ENDPOINT_XFER_BULK, 321 .wMaxPacketSize = 512, 322 },{ 323 .bEndpointAddress = USB_DIR_IN | EP_EVENT, 324 .bmAttributes = USB_ENDPOINT_XFER_INT, 325 .wMaxPacketSize = 64, 326 .bInterval = 0x0a, 327 }, 328 } 329 }; 330 331 static const USBDescDevice desc_device_high = { 332 .bcdUSB = 0x0200, 333 .bMaxPacketSize0 = 64, 334 .bNumConfigurations = 1, 335 .confs = (USBDescConfig[]) { 336 { 337 .bNumInterfaces = 1, 338 .bConfigurationValue = 1, 339 .iConfiguration = STR_CONFIG_HIGH, 340 .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP, 341 .bMaxPower = 2, 342 .nif = 1, 343 .ifs = &desc_iface_high, 344 }, 345 }, 346 }; 347 348 static const USBDescMSOS desc_msos = { 349 .CompatibleID = "MTP", 350 .SelectiveSuspendEnabled = true, 351 }; 352 353 static const USBDesc desc = { 354 .id = { 355 .idVendor = 0x46f4, /* CRC16() of "QEMU" */ 356 .idProduct = 0x0004, 357 .bcdDevice = 0, 358 .iManufacturer = STR_MANUFACTURER, 359 .iProduct = STR_PRODUCT, 360 .iSerialNumber = STR_SERIALNUMBER, 361 }, 362 .full = &desc_device_full, 363 .high = &desc_device_high, 364 .str = desc_strings, 365 .msos = &desc_msos, 366 }; 367 368 /* ----------------------------------------------------------------------- */ 369 370 static MTPObject *usb_mtp_object_alloc(MTPState *s, uint32_t handle, 371 MTPObject *parent, char *name) 372 { 373 MTPObject *o = g_new0(MTPObject, 1); 374 375 if (name[0] == '.') { 376 goto ignore; 377 } 378 379 o->handle = handle; 380 o->parent = parent; 381 o->name = g_strdup(name); 382 if (parent == NULL) { 383 o->path = g_strdup(name); 384 } else { 385 o->path = g_strdup_printf("%s/%s", parent->path, name); 386 } 387 388 if (lstat(o->path, &o->stat) != 0) { 389 goto ignore; 390 } 391 if (S_ISREG(o->stat.st_mode)) { 392 o->format = FMT_UNDEFINED_OBJECT; 393 } else if (S_ISDIR(o->stat.st_mode)) { 394 o->format = FMT_ASSOCIATION; 395 } else { 396 goto ignore; 397 } 398 399 if (access(o->path, R_OK) != 0) { 400 goto ignore; 401 } 402 403 trace_usb_mtp_object_alloc(s->dev.addr, o->handle, o->path); 404 405 QTAILQ_INSERT_TAIL(&s->objects, o, next); 406 return o; 407 408 ignore: 409 g_free(o->name); 410 g_free(o->path); 411 g_free(o); 412 return NULL; 413 } 414 415 static void usb_mtp_object_free(MTPState *s, MTPObject *o) 416 { 417 MTPObject *iter; 418 419 if (!o) { 420 return; 421 } 422 423 trace_usb_mtp_object_free(s->dev.addr, o->handle, o->path); 424 425 QTAILQ_REMOVE(&s->objects, o, next); 426 if (o->parent) { 427 QLIST_REMOVE(o, list); 428 o->parent->nchildren--; 429 } 430 431 while (!QLIST_EMPTY(&o->children)) { 432 iter = QLIST_FIRST(&o->children); 433 usb_mtp_object_free(s, iter); 434 } 435 g_free(o->name); 436 g_free(o->path); 437 g_free(o); 438 } 439 440 static MTPObject *usb_mtp_object_lookup(MTPState *s, uint32_t handle) 441 { 442 MTPObject *o; 443 444 QTAILQ_FOREACH(o, &s->objects, next) { 445 if (o->handle == handle) { 446 return o; 447 } 448 } 449 return NULL; 450 } 451 452 static MTPObject *usb_mtp_add_child(MTPState *s, MTPObject *o, 453 char *name) 454 { 455 MTPObject *child = 456 usb_mtp_object_alloc(s, s->next_handle++, o, name); 457 458 if (child) { 459 trace_usb_mtp_add_child(s->dev.addr, child->handle, child->path); 460 QLIST_INSERT_HEAD(&o->children, child, list); 461 o->nchildren++; 462 463 if (child->format == FMT_ASSOCIATION) { 464 QLIST_INIT(&child->children); 465 } 466 } 467 468 return child; 469 } 470 471 static MTPObject *usb_mtp_object_lookup_name(MTPObject *parent, 472 char *name, int len) 473 { 474 MTPObject *iter; 475 476 QLIST_FOREACH(iter, &parent->children, list) { 477 if (strncmp(iter->name, name, len) == 0) { 478 return iter; 479 } 480 } 481 482 return NULL; 483 } 484 485 #ifdef CONFIG_INOTIFY1 486 static MTPObject *usb_mtp_object_lookup_wd(MTPState *s, int wd) 487 { 488 MTPObject *iter; 489 490 QTAILQ_FOREACH(iter, &s->objects, next) { 491 if (iter->watchfd == wd) { 492 return iter; 493 } 494 } 495 496 return NULL; 497 } 498 499 static void inotify_watchfn(void *arg) 500 { 501 MTPState *s = arg; 502 ssize_t bytes; 503 /* From the man page: atleast one event can be read */ 504 int pos; 505 char buf[sizeof(struct inotify_event) + NAME_MAX + 1]; 506 507 for (;;) { 508 bytes = read(s->inotifyfd, buf, sizeof(buf)); 509 pos = 0; 510 511 if (bytes <= 0) { 512 /* Better luck next time */ 513 return; 514 } 515 516 /* 517 * TODO: Ignore initiator initiated events. 518 * For now we are good because the store is RO 519 */ 520 while (bytes > 0) { 521 char *p = buf + pos; 522 struct inotify_event *event = (struct inotify_event *)p; 523 int watchfd = 0; 524 uint32_t mask = event->mask & (IN_CREATE | IN_DELETE | 525 IN_MODIFY | IN_IGNORED); 526 MTPObject *parent = usb_mtp_object_lookup_wd(s, event->wd); 527 MTPMonEntry *entry = NULL; 528 MTPObject *o; 529 530 pos = pos + sizeof(struct inotify_event) + event->len; 531 bytes = bytes - pos; 532 533 if (!parent) { 534 continue; 535 } 536 537 switch (mask) { 538 case IN_CREATE: 539 if (usb_mtp_object_lookup_name 540 (parent, event->name, event->len)) { 541 /* Duplicate create event */ 542 continue; 543 } 544 entry = g_new0(MTPMonEntry, 1); 545 entry->handle = s->next_handle; 546 entry->event = EVT_OBJ_ADDED; 547 o = usb_mtp_add_child(s, parent, event->name); 548 if (!o) { 549 g_free(entry); 550 continue; 551 } 552 o->watchfd = watchfd; 553 trace_usb_mtp_inotify_event(s->dev.addr, event->name, 554 event->mask, "Obj Added"); 555 break; 556 557 case IN_DELETE: 558 /* 559 * The kernel issues a IN_IGNORED event 560 * when a dir containing a watchpoint is 561 * deleted, so we don't have to delete the 562 * watchpoint 563 */ 564 o = usb_mtp_object_lookup_name(parent, event->name, event->len); 565 if (!o) { 566 continue; 567 } 568 entry = g_new0(MTPMonEntry, 1); 569 entry->handle = o->handle; 570 entry->event = EVT_OBJ_REMOVED; 571 trace_usb_mtp_inotify_event(s->dev.addr, o->path, 572 event->mask, "Obj Deleted"); 573 usb_mtp_object_free(s, o); 574 break; 575 576 case IN_MODIFY: 577 o = usb_mtp_object_lookup_name(parent, event->name, event->len); 578 if (!o) { 579 continue; 580 } 581 entry = g_new0(MTPMonEntry, 1); 582 entry->handle = o->handle; 583 entry->event = EVT_OBJ_INFO_CHANGED; 584 trace_usb_mtp_inotify_event(s->dev.addr, o->path, 585 event->mask, "Obj Modified"); 586 break; 587 588 case IN_IGNORED: 589 trace_usb_mtp_inotify_event(s->dev.addr, parent->path, 590 event->mask, "Obj parent dir ignored"); 591 break; 592 593 default: 594 fprintf(stderr, "usb-mtp: failed to parse inotify event\n"); 595 continue; 596 } 597 598 if (entry) { 599 QTAILQ_INSERT_HEAD(&s->events, entry, next); 600 } 601 } 602 } 603 } 604 605 static int usb_mtp_inotify_init(MTPState *s) 606 { 607 int fd; 608 609 fd = inotify_init1(IN_NONBLOCK); 610 if (fd == -1) { 611 return 1; 612 } 613 614 QTAILQ_INIT(&s->events); 615 s->inotifyfd = fd; 616 617 qemu_set_fd_handler(fd, inotify_watchfn, NULL, s); 618 619 return 0; 620 } 621 622 static void usb_mtp_inotify_cleanup(MTPState *s) 623 { 624 MTPMonEntry *e, *p; 625 626 if (!s->inotifyfd) { 627 return; 628 } 629 630 qemu_set_fd_handler(s->inotifyfd, NULL, NULL, s); 631 close(s->inotifyfd); 632 633 QTAILQ_FOREACH_SAFE(e, &s->events, next, p) { 634 QTAILQ_REMOVE(&s->events, e, next); 635 g_free(e); 636 } 637 } 638 639 static int usb_mtp_add_watch(int inotifyfd, char *path) 640 { 641 uint32_t mask = IN_CREATE | IN_DELETE | IN_MODIFY | 642 IN_ISDIR; 643 644 return inotify_add_watch(inotifyfd, path, mask); 645 } 646 #endif 647 648 static void usb_mtp_object_readdir(MTPState *s, MTPObject *o) 649 { 650 struct dirent *entry; 651 DIR *dir; 652 653 if (o->have_children) { 654 return; 655 } 656 o->have_children = true; 657 658 dir = opendir(o->path); 659 if (!dir) { 660 return; 661 } 662 #ifdef CONFIG_INOTIFY1 663 int watchfd = usb_mtp_add_watch(s->inotifyfd, o->path); 664 if (watchfd == -1) { 665 fprintf(stderr, "usb-mtp: failed to add watch for %s\n", o->path); 666 } else { 667 trace_usb_mtp_inotify_event(s->dev.addr, o->path, 668 0, "Watch Added"); 669 o->watchfd = watchfd; 670 } 671 #endif 672 while ((entry = readdir(dir)) != NULL) { 673 usb_mtp_add_child(s, o, entry->d_name); 674 } 675 closedir(dir); 676 } 677 678 /* ----------------------------------------------------------------------- */ 679 680 static MTPData *usb_mtp_data_alloc(MTPControl *c) 681 { 682 MTPData *data = g_new0(MTPData, 1); 683 684 data->code = c->code; 685 data->trans = c->trans; 686 data->fd = -1; 687 data->first = true; 688 return data; 689 } 690 691 static void usb_mtp_data_free(MTPData *data) 692 { 693 if (data == NULL) { 694 return; 695 } 696 if (data->fd != -1) { 697 close(data->fd); 698 } 699 g_free(data->data); 700 g_free(data); 701 } 702 703 static void usb_mtp_realloc(MTPData *data, uint32_t bytes) 704 { 705 if (data->length + bytes <= data->alloc) { 706 return; 707 } 708 data->alloc = (data->length + bytes + 0xff) & ~0xff; 709 data->data = g_realloc(data->data, data->alloc); 710 } 711 712 static void usb_mtp_add_u8(MTPData *data, uint8_t val) 713 { 714 usb_mtp_realloc(data, 1); 715 data->data[data->length++] = val; 716 } 717 718 static void usb_mtp_add_u16(MTPData *data, uint16_t val) 719 { 720 usb_mtp_realloc(data, 2); 721 data->data[data->length++] = (val >> 0) & 0xff; 722 data->data[data->length++] = (val >> 8) & 0xff; 723 } 724 725 static void usb_mtp_add_u32(MTPData *data, uint32_t val) 726 { 727 usb_mtp_realloc(data, 4); 728 data->data[data->length++] = (val >> 0) & 0xff; 729 data->data[data->length++] = (val >> 8) & 0xff; 730 data->data[data->length++] = (val >> 16) & 0xff; 731 data->data[data->length++] = (val >> 24) & 0xff; 732 } 733 734 static void usb_mtp_add_u64(MTPData *data, uint64_t val) 735 { 736 usb_mtp_realloc(data, 8); 737 data->data[data->length++] = (val >> 0) & 0xff; 738 data->data[data->length++] = (val >> 8) & 0xff; 739 data->data[data->length++] = (val >> 16) & 0xff; 740 data->data[data->length++] = (val >> 24) & 0xff; 741 data->data[data->length++] = (val >> 32) & 0xff; 742 data->data[data->length++] = (val >> 40) & 0xff; 743 data->data[data->length++] = (val >> 48) & 0xff; 744 data->data[data->length++] = (val >> 56) & 0xff; 745 } 746 747 static void usb_mtp_add_u16_array(MTPData *data, uint32_t len, 748 const uint16_t *vals) 749 { 750 int i; 751 752 usb_mtp_add_u32(data, len); 753 for (i = 0; i < len; i++) { 754 usb_mtp_add_u16(data, vals[i]); 755 } 756 } 757 758 static void usb_mtp_add_u32_array(MTPData *data, uint32_t len, 759 const uint32_t *vals) 760 { 761 int i; 762 763 usb_mtp_add_u32(data, len); 764 for (i = 0; i < len; i++) { 765 usb_mtp_add_u32(data, vals[i]); 766 } 767 } 768 769 static void usb_mtp_add_wstr(MTPData *data, const wchar_t *str) 770 { 771 uint32_t len = wcslen(str); 772 int i; 773 774 if (len > 0) { 775 len++; /* include terminating L'\0' */ 776 } 777 778 usb_mtp_add_u8(data, len); 779 for (i = 0; i < len; i++) { 780 usb_mtp_add_u16(data, str[i]); 781 } 782 } 783 784 static void usb_mtp_add_str(MTPData *data, const char *str) 785 { 786 uint32_t len = strlen(str)+1; 787 wchar_t *wstr = g_new(wchar_t, len); 788 size_t ret; 789 790 ret = mbstowcs(wstr, str, len); 791 if (ret == -1) { 792 usb_mtp_add_wstr(data, L"Oops"); 793 } else { 794 usb_mtp_add_wstr(data, wstr); 795 } 796 797 g_free(wstr); 798 } 799 800 static void usb_mtp_add_time(MTPData *data, time_t time) 801 { 802 char buf[16]; 803 struct tm tm; 804 805 gmtime_r(&time, &tm); 806 strftime(buf, sizeof(buf), "%Y%m%dT%H%M%S", &tm); 807 usb_mtp_add_str(data, buf); 808 } 809 810 /* ----------------------------------------------------------------------- */ 811 812 static void usb_mtp_queue_result(MTPState *s, uint16_t code, uint32_t trans, 813 int argc, uint32_t arg0, uint32_t arg1, 814 uint32_t arg2) 815 { 816 MTPControl *c = g_new0(MTPControl, 1); 817 818 c->code = code; 819 c->trans = trans; 820 c->argc = argc; 821 if (argc > 0) { 822 c->argv[0] = arg0; 823 } 824 if (argc > 1) { 825 c->argv[1] = arg1; 826 } 827 if (argc > 2) { 828 c->argv[2] = arg2; 829 } 830 831 assert(s->result == NULL); 832 s->result = c; 833 } 834 835 /* ----------------------------------------------------------------------- */ 836 837 static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c) 838 { 839 static const uint16_t ops[] = { 840 CMD_GET_DEVICE_INFO, 841 CMD_OPEN_SESSION, 842 CMD_CLOSE_SESSION, 843 CMD_GET_STORAGE_IDS, 844 CMD_GET_STORAGE_INFO, 845 CMD_GET_NUM_OBJECTS, 846 CMD_GET_OBJECT_HANDLES, 847 CMD_GET_OBJECT_INFO, 848 CMD_DELETE_OBJECT, 849 CMD_SEND_OBJECT_INFO, 850 CMD_SEND_OBJECT, 851 CMD_GET_OBJECT, 852 CMD_GET_PARTIAL_OBJECT, 853 CMD_GET_OBJECT_PROPS_SUPPORTED, 854 CMD_GET_OBJECT_PROP_DESC, 855 CMD_GET_OBJECT_PROP_VALUE, 856 }; 857 static const uint16_t fmt[] = { 858 FMT_UNDEFINED_OBJECT, 859 FMT_ASSOCIATION, 860 }; 861 MTPData *d = usb_mtp_data_alloc(c); 862 863 trace_usb_mtp_op_get_device_info(s->dev.addr); 864 865 usb_mtp_add_u16(d, 100); 866 usb_mtp_add_u32(d, 0x00000006); 867 usb_mtp_add_u16(d, 0x0064); 868 usb_mtp_add_wstr(d, L""); 869 usb_mtp_add_u16(d, 0x0000); 870 871 usb_mtp_add_u16_array(d, ARRAY_SIZE(ops), ops); 872 usb_mtp_add_u16_array(d, 0, NULL); 873 usb_mtp_add_u16_array(d, 0, NULL); 874 usb_mtp_add_u16_array(d, 0, NULL); 875 usb_mtp_add_u16_array(d, ARRAY_SIZE(fmt), fmt); 876 877 usb_mtp_add_wstr(d, L"" MTP_MANUFACTURER); 878 usb_mtp_add_wstr(d, L"" MTP_PRODUCT); 879 usb_mtp_add_wstr(d, L"0.1"); 880 usb_mtp_add_wstr(d, L"0123456789abcdef0123456789abcdef"); 881 882 return d; 883 } 884 885 static MTPData *usb_mtp_get_storage_ids(MTPState *s, MTPControl *c) 886 { 887 static const uint32_t ids[] = { 888 QEMU_STORAGE_ID, 889 }; 890 MTPData *d = usb_mtp_data_alloc(c); 891 892 trace_usb_mtp_op_get_storage_ids(s->dev.addr); 893 894 usb_mtp_add_u32_array(d, ARRAY_SIZE(ids), ids); 895 896 return d; 897 } 898 899 static MTPData *usb_mtp_get_storage_info(MTPState *s, MTPControl *c) 900 { 901 MTPData *d = usb_mtp_data_alloc(c); 902 struct statvfs buf; 903 int rc; 904 905 trace_usb_mtp_op_get_storage_info(s->dev.addr); 906 907 if (FLAG_SET(s, MTP_FLAG_WRITABLE)) { 908 usb_mtp_add_u16(d, 0x0003); 909 usb_mtp_add_u16(d, 0x0002); 910 usb_mtp_add_u16(d, 0x0000); 911 } else { 912 usb_mtp_add_u16(d, 0x0001); 913 usb_mtp_add_u16(d, 0x0002); 914 usb_mtp_add_u16(d, 0x0001); 915 } 916 917 rc = statvfs(s->root, &buf); 918 if (rc == 0) { 919 usb_mtp_add_u64(d, (uint64_t)buf.f_frsize * buf.f_blocks); 920 usb_mtp_add_u64(d, (uint64_t)buf.f_bavail * buf.f_blocks); 921 usb_mtp_add_u32(d, buf.f_ffree); 922 } else { 923 usb_mtp_add_u64(d, 0xffffffff); 924 usb_mtp_add_u64(d, 0xffffffff); 925 usb_mtp_add_u32(d, 0xffffffff); 926 } 927 928 usb_mtp_add_str(d, s->desc); 929 usb_mtp_add_wstr(d, L"123456789abcdef"); 930 return d; 931 } 932 933 static MTPData *usb_mtp_get_object_handles(MTPState *s, MTPControl *c, 934 MTPObject *o) 935 { 936 MTPData *d = usb_mtp_data_alloc(c); 937 uint32_t i = 0, handles[o->nchildren]; 938 MTPObject *iter; 939 940 trace_usb_mtp_op_get_object_handles(s->dev.addr, o->handle, o->path); 941 942 QLIST_FOREACH(iter, &o->children, list) { 943 handles[i++] = iter->handle; 944 } 945 assert(i == o->nchildren); 946 usb_mtp_add_u32_array(d, o->nchildren, handles); 947 948 return d; 949 } 950 951 static MTPData *usb_mtp_get_object_info(MTPState *s, MTPControl *c, 952 MTPObject *o) 953 { 954 MTPData *d = usb_mtp_data_alloc(c); 955 956 trace_usb_mtp_op_get_object_info(s->dev.addr, o->handle, o->path); 957 958 usb_mtp_add_u32(d, QEMU_STORAGE_ID); 959 usb_mtp_add_u16(d, o->format); 960 usb_mtp_add_u16(d, 0); 961 962 if (o->stat.st_size > 0xFFFFFFFF) { 963 usb_mtp_add_u32(d, 0xFFFFFFFF); 964 } else { 965 usb_mtp_add_u32(d, o->stat.st_size); 966 } 967 968 usb_mtp_add_u16(d, 0); 969 usb_mtp_add_u32(d, 0); 970 usb_mtp_add_u32(d, 0); 971 usb_mtp_add_u32(d, 0); 972 usb_mtp_add_u32(d, 0); 973 usb_mtp_add_u32(d, 0); 974 usb_mtp_add_u32(d, 0); 975 976 if (o->parent) { 977 usb_mtp_add_u32(d, o->parent->handle); 978 } else { 979 usb_mtp_add_u32(d, 0); 980 } 981 if (o->format == FMT_ASSOCIATION) { 982 usb_mtp_add_u16(d, 0x0001); 983 usb_mtp_add_u32(d, 0x00000001); 984 usb_mtp_add_u32(d, 0); 985 } else { 986 usb_mtp_add_u16(d, 0); 987 usb_mtp_add_u32(d, 0); 988 usb_mtp_add_u32(d, 0); 989 } 990 991 usb_mtp_add_str(d, o->name); 992 usb_mtp_add_time(d, o->stat.st_ctime); 993 usb_mtp_add_time(d, o->stat.st_mtime); 994 usb_mtp_add_wstr(d, L""); 995 996 return d; 997 } 998 999 static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c, 1000 MTPObject *o) 1001 { 1002 MTPData *d = usb_mtp_data_alloc(c); 1003 1004 trace_usb_mtp_op_get_object(s->dev.addr, o->handle, o->path); 1005 1006 d->fd = open(o->path, O_RDONLY); 1007 if (d->fd == -1) { 1008 usb_mtp_data_free(d); 1009 return NULL; 1010 } 1011 d->length = o->stat.st_size; 1012 d->alloc = 512; 1013 d->data = g_malloc(d->alloc); 1014 return d; 1015 } 1016 1017 static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c, 1018 MTPObject *o) 1019 { 1020 MTPData *d; 1021 off_t offset; 1022 1023 if (c->argc <= 2) { 1024 return NULL; 1025 } 1026 trace_usb_mtp_op_get_partial_object(s->dev.addr, o->handle, o->path, 1027 c->argv[1], c->argv[2]); 1028 1029 d = usb_mtp_data_alloc(c); 1030 d->fd = open(o->path, O_RDONLY); 1031 if (d->fd == -1) { 1032 usb_mtp_data_free(d); 1033 return NULL; 1034 } 1035 1036 offset = c->argv[1]; 1037 if (offset > o->stat.st_size) { 1038 offset = o->stat.st_size; 1039 } 1040 if (lseek(d->fd, offset, SEEK_SET) < 0) { 1041 usb_mtp_data_free(d); 1042 return NULL; 1043 } 1044 1045 d->length = c->argv[2]; 1046 if (d->length > o->stat.st_size - offset) { 1047 d->length = o->stat.st_size - offset; 1048 } 1049 1050 return d; 1051 } 1052 1053 static MTPData *usb_mtp_get_object_props_supported(MTPState *s, MTPControl *c) 1054 { 1055 static const uint16_t props[] = { 1056 PROP_STORAGE_ID, 1057 PROP_OBJECT_FORMAT, 1058 PROP_OBJECT_COMPRESSED_SIZE, 1059 PROP_PARENT_OBJECT, 1060 PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER, 1061 PROP_NAME, 1062 }; 1063 MTPData *d = usb_mtp_data_alloc(c); 1064 usb_mtp_add_u16_array(d, ARRAY_SIZE(props), props); 1065 1066 return d; 1067 } 1068 1069 static MTPData *usb_mtp_get_object_prop_desc(MTPState *s, MTPControl *c) 1070 { 1071 MTPData *d = usb_mtp_data_alloc(c); 1072 switch (c->argv[0]) { 1073 case PROP_STORAGE_ID: 1074 usb_mtp_add_u16(d, PROP_STORAGE_ID); 1075 usb_mtp_add_u16(d, DATA_TYPE_UINT32); 1076 usb_mtp_add_u8(d, 0x00); 1077 usb_mtp_add_u32(d, 0x00000000); 1078 usb_mtp_add_u32(d, 0x00000000); 1079 usb_mtp_add_u8(d, 0x00); 1080 break; 1081 case PROP_OBJECT_FORMAT: 1082 usb_mtp_add_u16(d, PROP_OBJECT_FORMAT); 1083 usb_mtp_add_u16(d, DATA_TYPE_UINT16); 1084 usb_mtp_add_u8(d, 0x00); 1085 usb_mtp_add_u16(d, 0x0000); 1086 usb_mtp_add_u32(d, 0x00000000); 1087 usb_mtp_add_u8(d, 0x00); 1088 break; 1089 case PROP_OBJECT_COMPRESSED_SIZE: 1090 usb_mtp_add_u16(d, PROP_OBJECT_COMPRESSED_SIZE); 1091 usb_mtp_add_u16(d, DATA_TYPE_UINT64); 1092 usb_mtp_add_u8(d, 0x00); 1093 usb_mtp_add_u64(d, 0x0000000000000000); 1094 usb_mtp_add_u32(d, 0x00000000); 1095 usb_mtp_add_u8(d, 0x00); 1096 break; 1097 case PROP_PARENT_OBJECT: 1098 usb_mtp_add_u16(d, PROP_PARENT_OBJECT); 1099 usb_mtp_add_u16(d, DATA_TYPE_UINT32); 1100 usb_mtp_add_u8(d, 0x00); 1101 usb_mtp_add_u32(d, 0x00000000); 1102 usb_mtp_add_u32(d, 0x00000000); 1103 usb_mtp_add_u8(d, 0x00); 1104 break; 1105 case PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER: 1106 usb_mtp_add_u16(d, PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER); 1107 usb_mtp_add_u16(d, DATA_TYPE_UINT128); 1108 usb_mtp_add_u8(d, 0x00); 1109 usb_mtp_add_u64(d, 0x0000000000000000); 1110 usb_mtp_add_u64(d, 0x0000000000000000); 1111 usb_mtp_add_u32(d, 0x00000000); 1112 usb_mtp_add_u8(d, 0x00); 1113 break; 1114 case PROP_NAME: 1115 usb_mtp_add_u16(d, PROP_NAME); 1116 usb_mtp_add_u16(d, DATA_TYPE_STRING); 1117 usb_mtp_add_u8(d, 0x00); 1118 usb_mtp_add_u8(d, 0x00); 1119 usb_mtp_add_u32(d, 0x00000000); 1120 usb_mtp_add_u8(d, 0x00); 1121 break; 1122 default: 1123 usb_mtp_data_free(d); 1124 return NULL; 1125 } 1126 1127 return d; 1128 } 1129 1130 static MTPData *usb_mtp_get_object_prop_value(MTPState *s, MTPControl *c, 1131 MTPObject *o) 1132 { 1133 MTPData *d = usb_mtp_data_alloc(c); 1134 switch (c->argv[1]) { 1135 case PROP_STORAGE_ID: 1136 usb_mtp_add_u32(d, QEMU_STORAGE_ID); 1137 break; 1138 case PROP_OBJECT_FORMAT: 1139 usb_mtp_add_u16(d, o->format); 1140 break; 1141 case PROP_OBJECT_COMPRESSED_SIZE: 1142 usb_mtp_add_u64(d, o->stat.st_size); 1143 break; 1144 case PROP_PARENT_OBJECT: 1145 if (o->parent == NULL) { 1146 usb_mtp_add_u32(d, 0x00000000); 1147 } else { 1148 usb_mtp_add_u32(d, o->parent->handle); 1149 } 1150 break; 1151 case PROP_PERSISTENT_UNIQUE_OBJECT_IDENTIFIER: 1152 /* Should be persistent between sessions, 1153 * but using our objedt ID is "good enough" 1154 * for now */ 1155 usb_mtp_add_u64(d, 0x0000000000000000); 1156 usb_mtp_add_u64(d, o->handle); 1157 break; 1158 case PROP_NAME: 1159 usb_mtp_add_str(d, o->name); 1160 break; 1161 default: 1162 usb_mtp_data_free(d); 1163 return NULL; 1164 } 1165 1166 return d; 1167 } 1168 1169 /* Return correct return code for a delete event */ 1170 enum { 1171 ALL_DELETE, 1172 PARTIAL_DELETE, 1173 READ_ONLY, 1174 }; 1175 1176 /* Assumes that children, if any, have been already freed */ 1177 static void usb_mtp_object_free_one(MTPState *s, MTPObject *o) 1178 { 1179 #ifndef CONFIG_INOTIFY1 1180 assert(o->nchildren == 0); 1181 QTAILQ_REMOVE(&s->objects, o, next); 1182 g_free(o->name); 1183 g_free(o->path); 1184 g_free(o); 1185 #endif 1186 } 1187 1188 static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans) 1189 { 1190 MTPObject *iter, *iter2; 1191 bool partial_delete = false; 1192 bool success = false; 1193 1194 /* 1195 * TODO: Add support for Protection Status 1196 */ 1197 1198 QLIST_FOREACH(iter, &o->children, list) { 1199 if (iter->format == FMT_ASSOCIATION) { 1200 QLIST_FOREACH(iter2, &iter->children, list) { 1201 usb_mtp_deletefn(s, iter2, trans); 1202 } 1203 } 1204 } 1205 1206 if (o->format == FMT_UNDEFINED_OBJECT) { 1207 if (remove(o->path)) { 1208 partial_delete = true; 1209 } else { 1210 usb_mtp_object_free_one(s, o); 1211 success = true; 1212 } 1213 } 1214 1215 if (o->format == FMT_ASSOCIATION) { 1216 if (rmdir(o->path)) { 1217 partial_delete = true; 1218 } else { 1219 usb_mtp_object_free_one(s, o); 1220 success = true; 1221 } 1222 } 1223 1224 if (success && partial_delete) { 1225 return PARTIAL_DELETE; 1226 } 1227 if (!success && partial_delete) { 1228 return READ_ONLY; 1229 } 1230 return ALL_DELETE; 1231 } 1232 1233 static void usb_mtp_object_delete(MTPState *s, uint32_t handle, 1234 uint32_t format_code, uint32_t trans) 1235 { 1236 MTPObject *o; 1237 int ret; 1238 1239 /* Return error if store is read-only */ 1240 if (!FLAG_SET(s, MTP_FLAG_WRITABLE)) { 1241 usb_mtp_queue_result(s, RES_STORE_READ_ONLY, 1242 trans, 0, 0, 0, 0); 1243 return; 1244 } 1245 1246 if (format_code != 0) { 1247 usb_mtp_queue_result(s, RES_SPEC_BY_FORMAT_UNSUPPORTED, 1248 trans, 0, 0, 0, 0); 1249 return; 1250 } 1251 1252 if (handle == 0xFFFFFFF) { 1253 o = QTAILQ_FIRST(&s->objects); 1254 } else { 1255 o = usb_mtp_object_lookup(s, handle); 1256 } 1257 if (o == NULL) { 1258 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, 1259 trans, 0, 0, 0, 0); 1260 return; 1261 } 1262 1263 ret = usb_mtp_deletefn(s, o, trans); 1264 if (ret == PARTIAL_DELETE) { 1265 usb_mtp_queue_result(s, RES_PARTIAL_DELETE, 1266 trans, 0, 0, 0, 0); 1267 return; 1268 } else if (ret == READ_ONLY) { 1269 usb_mtp_queue_result(s, RES_STORE_READ_ONLY, trans, 1270 0, 0, 0, 0); 1271 return; 1272 } else { 1273 usb_mtp_queue_result(s, RES_OK, trans, 1274 0, 0, 0, 0); 1275 return; 1276 } 1277 } 1278 1279 static void usb_mtp_command(MTPState *s, MTPControl *c) 1280 { 1281 MTPData *data_in = NULL; 1282 MTPObject *o = NULL; 1283 uint32_t nres = 0, res0 = 0; 1284 1285 /* sanity checks */ 1286 if (c->code >= CMD_CLOSE_SESSION && s->session == 0) { 1287 usb_mtp_queue_result(s, RES_SESSION_NOT_OPEN, 1288 c->trans, 0, 0, 0, 0); 1289 return; 1290 } 1291 1292 /* process commands */ 1293 switch (c->code) { 1294 case CMD_GET_DEVICE_INFO: 1295 data_in = usb_mtp_get_device_info(s, c); 1296 break; 1297 case CMD_OPEN_SESSION: 1298 if (s->session) { 1299 usb_mtp_queue_result(s, RES_SESSION_ALREADY_OPEN, 1300 c->trans, 1, s->session, 0, 0); 1301 return; 1302 } 1303 if (c->argv[0] == 0) { 1304 usb_mtp_queue_result(s, RES_INVALID_PARAMETER, 1305 c->trans, 0, 0, 0, 0); 1306 return; 1307 } 1308 trace_usb_mtp_op_open_session(s->dev.addr); 1309 s->session = c->argv[0]; 1310 usb_mtp_object_alloc(s, s->next_handle++, NULL, s->root); 1311 #ifdef CONFIG_INOTIFY1 1312 if (usb_mtp_inotify_init(s)) { 1313 fprintf(stderr, "usb-mtp: file monitoring init failed\n"); 1314 } 1315 #endif 1316 break; 1317 case CMD_CLOSE_SESSION: 1318 trace_usb_mtp_op_close_session(s->dev.addr); 1319 s->session = 0; 1320 s->next_handle = 0; 1321 #ifdef CONFIG_INOTIFY1 1322 usb_mtp_inotify_cleanup(s); 1323 #endif 1324 usb_mtp_object_free(s, QTAILQ_FIRST(&s->objects)); 1325 assert(QTAILQ_EMPTY(&s->objects)); 1326 break; 1327 case CMD_GET_STORAGE_IDS: 1328 data_in = usb_mtp_get_storage_ids(s, c); 1329 break; 1330 case CMD_GET_STORAGE_INFO: 1331 if (c->argv[0] != QEMU_STORAGE_ID && 1332 c->argv[0] != 0xffffffff) { 1333 usb_mtp_queue_result(s, RES_INVALID_STORAGE_ID, 1334 c->trans, 0, 0, 0, 0); 1335 return; 1336 } 1337 data_in = usb_mtp_get_storage_info(s, c); 1338 break; 1339 case CMD_GET_NUM_OBJECTS: 1340 case CMD_GET_OBJECT_HANDLES: 1341 if (c->argv[0] != QEMU_STORAGE_ID && 1342 c->argv[0] != 0xffffffff) { 1343 usb_mtp_queue_result(s, RES_INVALID_STORAGE_ID, 1344 c->trans, 0, 0, 0, 0); 1345 return; 1346 } 1347 if (c->argv[1] != 0x00000000) { 1348 usb_mtp_queue_result(s, RES_SPEC_BY_FORMAT_UNSUPPORTED, 1349 c->trans, 0, 0, 0, 0); 1350 return; 1351 } 1352 if (c->argv[2] == 0x00000000 || 1353 c->argv[2] == 0xffffffff) { 1354 o = QTAILQ_FIRST(&s->objects); 1355 } else { 1356 o = usb_mtp_object_lookup(s, c->argv[2]); 1357 } 1358 if (o == NULL) { 1359 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, 1360 c->trans, 0, 0, 0, 0); 1361 return; 1362 } 1363 if (o->format != FMT_ASSOCIATION) { 1364 usb_mtp_queue_result(s, RES_INVALID_PARENT_OBJECT, 1365 c->trans, 0, 0, 0, 0); 1366 return; 1367 } 1368 usb_mtp_object_readdir(s, o); 1369 if (c->code == CMD_GET_NUM_OBJECTS) { 1370 trace_usb_mtp_op_get_num_objects(s->dev.addr, o->handle, o->path); 1371 nres = 1; 1372 res0 = o->nchildren; 1373 } else { 1374 data_in = usb_mtp_get_object_handles(s, c, o); 1375 } 1376 break; 1377 case CMD_GET_OBJECT_INFO: 1378 o = usb_mtp_object_lookup(s, c->argv[0]); 1379 if (o == NULL) { 1380 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, 1381 c->trans, 0, 0, 0, 0); 1382 return; 1383 } 1384 data_in = usb_mtp_get_object_info(s, c, o); 1385 break; 1386 case CMD_GET_OBJECT: 1387 o = usb_mtp_object_lookup(s, c->argv[0]); 1388 if (o == NULL) { 1389 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, 1390 c->trans, 0, 0, 0, 0); 1391 return; 1392 } 1393 if (o->format == FMT_ASSOCIATION) { 1394 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, 1395 c->trans, 0, 0, 0, 0); 1396 return; 1397 } 1398 data_in = usb_mtp_get_object(s, c, o); 1399 if (data_in == NULL) { 1400 usb_mtp_queue_result(s, RES_GENERAL_ERROR, 1401 c->trans, 0, 0, 0, 0); 1402 return; 1403 } 1404 break; 1405 case CMD_DELETE_OBJECT: 1406 usb_mtp_object_delete(s, c->argv[0], c->argv[1], c->trans); 1407 return; 1408 case CMD_GET_PARTIAL_OBJECT: 1409 o = usb_mtp_object_lookup(s, c->argv[0]); 1410 if (o == NULL) { 1411 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, 1412 c->trans, 0, 0, 0, 0); 1413 return; 1414 } 1415 if (o->format == FMT_ASSOCIATION) { 1416 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, 1417 c->trans, 0, 0, 0, 0); 1418 return; 1419 } 1420 data_in = usb_mtp_get_partial_object(s, c, o); 1421 if (data_in == NULL) { 1422 usb_mtp_queue_result(s, RES_GENERAL_ERROR, 1423 c->trans, 0, 0, 0, 0); 1424 return; 1425 } 1426 nres = 1; 1427 res0 = data_in->length; 1428 break; 1429 case CMD_SEND_OBJECT_INFO: 1430 /* Return error if store is read-only */ 1431 if (!FLAG_SET(s, MTP_FLAG_WRITABLE)) { 1432 usb_mtp_queue_result(s, RES_STORE_READ_ONLY, 1433 c->trans, 0, 0, 0, 0); 1434 } else if (c->argv[0] && (c->argv[0] != QEMU_STORAGE_ID)) { 1435 /* First parameter points to storage id or is 0 */ 1436 usb_mtp_queue_result(s, RES_STORE_NOT_AVAILABLE, c->trans, 1437 0, 0, 0, 0); 1438 } else if (c->argv[1] && !c->argv[0]) { 1439 /* If second parameter is specified, first must also be specified */ 1440 usb_mtp_queue_result(s, RES_DESTINATION_UNSUPPORTED, c->trans, 1441 0, 0, 0, 0); 1442 } else { 1443 uint32_t handle = c->argv[1]; 1444 if (handle == 0xFFFFFFFF || handle == 0) { 1445 /* root object */ 1446 o = QTAILQ_FIRST(&s->objects); 1447 } else { 1448 o = usb_mtp_object_lookup(s, handle); 1449 } 1450 if (o == NULL) { 1451 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, c->trans, 1452 0, 0, 0, 0); 1453 } else if (o->format != FMT_ASSOCIATION) { 1454 usb_mtp_queue_result(s, RES_INVALID_PARENT_OBJECT, c->trans, 1455 0, 0, 0, 0); 1456 } 1457 } 1458 if (o) { 1459 s->dataset.parent_handle = o->handle; 1460 } 1461 s->data_out = usb_mtp_data_alloc(c); 1462 return; 1463 case CMD_SEND_OBJECT: 1464 if (!FLAG_SET(s, MTP_FLAG_WRITABLE)) { 1465 usb_mtp_queue_result(s, RES_STORE_READ_ONLY, 1466 c->trans, 0, 0, 0, 0); 1467 return; 1468 } 1469 if (!s->write_pending) { 1470 usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, 1471 c->trans, 0, 0, 0, 0); 1472 return; 1473 } 1474 s->data_out = usb_mtp_data_alloc(c); 1475 return; 1476 case CMD_GET_OBJECT_PROPS_SUPPORTED: 1477 if (c->argv[0] != FMT_UNDEFINED_OBJECT && 1478 c->argv[0] != FMT_ASSOCIATION) { 1479 usb_mtp_queue_result(s, RES_INVALID_OBJECT_FORMAT_CODE, 1480 c->trans, 0, 0, 0, 0); 1481 return; 1482 } 1483 data_in = usb_mtp_get_object_props_supported(s, c); 1484 break; 1485 case CMD_GET_OBJECT_PROP_DESC: 1486 if (c->argv[1] != FMT_UNDEFINED_OBJECT && 1487 c->argv[1] != FMT_ASSOCIATION) { 1488 usb_mtp_queue_result(s, RES_INVALID_OBJECT_FORMAT_CODE, 1489 c->trans, 0, 0, 0, 0); 1490 return; 1491 } 1492 data_in = usb_mtp_get_object_prop_desc(s, c); 1493 if (data_in == NULL) { 1494 usb_mtp_queue_result(s, RES_INVALID_OBJECT_PROP_CODE, 1495 c->trans, 0, 0, 0, 0); 1496 return; 1497 } 1498 break; 1499 case CMD_GET_OBJECT_PROP_VALUE: 1500 o = usb_mtp_object_lookup(s, c->argv[0]); 1501 if (o == NULL) { 1502 usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, 1503 c->trans, 0, 0, 0, 0); 1504 return; 1505 } 1506 data_in = usb_mtp_get_object_prop_value(s, c, o); 1507 if (data_in == NULL) { 1508 usb_mtp_queue_result(s, RES_INVALID_OBJECT_PROP_CODE, 1509 c->trans, 0, 0, 0, 0); 1510 return; 1511 } 1512 break; 1513 default: 1514 trace_usb_mtp_op_unknown(s->dev.addr, c->code); 1515 usb_mtp_queue_result(s, RES_OPERATION_NOT_SUPPORTED, 1516 c->trans, 0, 0, 0, 0); 1517 return; 1518 } 1519 1520 /* return results on success */ 1521 if (data_in) { 1522 assert(s->data_in == NULL); 1523 s->data_in = data_in; 1524 } 1525 usb_mtp_queue_result(s, RES_OK, c->trans, nres, res0, 0, 0); 1526 } 1527 1528 /* ----------------------------------------------------------------------- */ 1529 1530 static void usb_mtp_handle_reset(USBDevice *dev) 1531 { 1532 MTPState *s = USB_MTP(dev); 1533 1534 trace_usb_mtp_reset(s->dev.addr); 1535 1536 #ifdef CONFIG_INOTIFY1 1537 usb_mtp_inotify_cleanup(s); 1538 #endif 1539 usb_mtp_object_free(s, QTAILQ_FIRST(&s->objects)); 1540 s->session = 0; 1541 usb_mtp_data_free(s->data_in); 1542 s->data_in = NULL; 1543 usb_mtp_data_free(s->data_out); 1544 s->data_out = NULL; 1545 g_free(s->result); 1546 s->result = NULL; 1547 } 1548 1549 static void usb_mtp_handle_control(USBDevice *dev, USBPacket *p, 1550 int request, int value, int index, 1551 int length, uint8_t *data) 1552 { 1553 int ret; 1554 1555 ret = usb_desc_handle_control(dev, p, request, value, index, length, data); 1556 if (ret >= 0) { 1557 return; 1558 } 1559 1560 trace_usb_mtp_stall(dev->addr, "unknown control request"); 1561 p->status = USB_RET_STALL; 1562 } 1563 1564 static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p) 1565 { 1566 /* we don't use async packets, so this should never be called */ 1567 fprintf(stderr, "%s\n", __func__); 1568 } 1569 1570 static void utf16_to_str(uint8_t len, uint16_t *arr, char *name) 1571 { 1572 int count; 1573 wchar_t *wstr = g_new0(wchar_t, len); 1574 1575 for (count = 0; count < len; count++) { 1576 wstr[count] = (wchar_t)arr[count]; 1577 } 1578 1579 wcstombs(name, wstr, len); 1580 g_free(wstr); 1581 } 1582 1583 static void usb_mtp_write_data(MTPState *s) 1584 { 1585 MTPData *d = s->data_out; 1586 MTPObject *parent = 1587 usb_mtp_object_lookup(s, s->dataset.parent_handle); 1588 char *path = NULL; 1589 int rc = -1; 1590 mode_t mask = 0644; 1591 1592 assert(d != NULL); 1593 1594 if (parent == NULL || !s->write_pending) { 1595 usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, d->trans, 1596 0, 0, 0, 0); 1597 return; 1598 } 1599 1600 if (s->dataset.filename) { 1601 path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename); 1602 if (s->dataset.format == FMT_ASSOCIATION) { 1603 d->fd = mkdir(path, mask); 1604 goto free; 1605 } 1606 if (s->dataset.size < d->length) { 1607 usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, 1608 0, 0, 0, 0); 1609 goto done; 1610 } 1611 d->fd = open(path, O_CREAT | O_WRONLY, mask); 1612 if (d->fd == -1) { 1613 usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, 1614 0, 0, 0, 0); 1615 goto done; 1616 } 1617 1618 /* 1619 * Return success if initiator sent 0 sized data 1620 */ 1621 if (!s->dataset.size) { 1622 goto success; 1623 } 1624 1625 rc = write(d->fd, d->data, s->dataset.size); 1626 if (rc == -1) { 1627 usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, 1628 0, 0, 0, 0); 1629 goto done; 1630 } 1631 if (rc != s->dataset.size) { 1632 usb_mtp_queue_result(s, RES_INCOMPLETE_TRANSFER, d->trans, 1633 0, 0, 0, 0); 1634 goto done; 1635 } 1636 } 1637 1638 success: 1639 usb_mtp_queue_result(s, RES_OK, d->trans, 1640 0, 0, 0, 0); 1641 1642 done: 1643 /* 1644 * The write dataset is kept around and freed only 1645 * on success or if another write request comes in 1646 */ 1647 if (d->fd != -1) { 1648 close(d->fd); 1649 } 1650 free: 1651 g_free(s->dataset.filename); 1652 g_free(path); 1653 s->write_pending = false; 1654 } 1655 1656 static void usb_mtp_write_metadata(MTPState *s) 1657 { 1658 MTPData *d = s->data_out; 1659 ObjectInfo *dataset = (ObjectInfo *)d->data; 1660 char *filename = g_new0(char, dataset->length); 1661 MTPObject *o; 1662 MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle); 1663 uint32_t next_handle = s->next_handle; 1664 1665 assert(!s->write_pending); 1666 assert(p != NULL); 1667 1668 utf16_to_str(dataset->length, dataset->filename, filename); 1669 1670 o = usb_mtp_object_lookup_name(p, filename, dataset->length); 1671 if (o != NULL) { 1672 next_handle = o->handle; 1673 } 1674 1675 s->dataset.filename = filename; 1676 s->dataset.format = dataset->format; 1677 s->dataset.size = dataset->size; 1678 s->dataset.filename = filename; 1679 s->write_pending = true; 1680 1681 if (s->dataset.format == FMT_ASSOCIATION) { 1682 usb_mtp_write_data(s); 1683 /* next_handle will be allocated to the newly created dir */ 1684 if (d->fd == -1) { 1685 usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, 1686 0, 0, 0, 0); 1687 return; 1688 } 1689 d->fd = -1; 1690 } 1691 1692 usb_mtp_queue_result(s, RES_OK, d->trans, 3, QEMU_STORAGE_ID, 1693 s->dataset.parent_handle, next_handle); 1694 } 1695 1696 static void usb_mtp_get_data(MTPState *s, mtp_container *container, 1697 USBPacket *p) 1698 { 1699 MTPData *d = s->data_out; 1700 uint64_t dlen; 1701 uint32_t data_len = p->iov.size; 1702 1703 if (!d) { 1704 usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, 0, 1705 0, 0, 0, 0); 1706 return; 1707 } 1708 if (d->first) { 1709 /* Total length of incoming data */ 1710 d->length = cpu_to_le32(container->length) - sizeof(mtp_container); 1711 /* Length of data in this packet */ 1712 data_len -= sizeof(mtp_container); 1713 usb_mtp_realloc(d, d->length); 1714 d->offset = 0; 1715 d->first = false; 1716 } 1717 1718 if (d->length - d->offset > data_len) { 1719 dlen = data_len; 1720 } else { 1721 dlen = d->length - d->offset; 1722 } 1723 1724 switch (d->code) { 1725 case CMD_SEND_OBJECT_INFO: 1726 usb_packet_copy(p, d->data + d->offset, dlen); 1727 d->offset += dlen; 1728 if (d->offset == d->length) { 1729 /* The operation might have already failed */ 1730 if (!s->result) { 1731 usb_mtp_write_metadata(s); 1732 } 1733 usb_mtp_data_free(s->data_out); 1734 s->data_out = NULL; 1735 return; 1736 } 1737 break; 1738 case CMD_SEND_OBJECT: 1739 usb_packet_copy(p, d->data + d->offset, dlen); 1740 d->offset += dlen; 1741 if (d->offset == d->length) { 1742 usb_mtp_write_data(s); 1743 usb_mtp_data_free(s->data_out); 1744 s->data_out = NULL; 1745 return; 1746 } 1747 break; 1748 default: 1749 p->status = USB_RET_STALL; 1750 return; 1751 } 1752 } 1753 1754 static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p) 1755 { 1756 MTPState *s = USB_MTP(dev); 1757 MTPControl cmd; 1758 mtp_container container; 1759 uint32_t params[5]; 1760 uint16_t container_type; 1761 int i, rc; 1762 1763 switch (p->ep->nr) { 1764 case EP_DATA_IN: 1765 if (s->data_out != NULL) { 1766 /* guest bug */ 1767 trace_usb_mtp_stall(s->dev.addr, "awaiting data-out"); 1768 p->status = USB_RET_STALL; 1769 return; 1770 } 1771 if (p->iov.size < sizeof(container)) { 1772 trace_usb_mtp_stall(s->dev.addr, "packet too small"); 1773 p->status = USB_RET_STALL; 1774 return; 1775 } 1776 if (s->data_in != NULL) { 1777 MTPData *d = s->data_in; 1778 uint64_t dlen = d->length - d->offset; 1779 if (d->first) { 1780 trace_usb_mtp_data_in(s->dev.addr, d->trans, d->length); 1781 if (d->length + sizeof(container) > 0xFFFFFFFF) { 1782 container.length = cpu_to_le32(0xFFFFFFFF); 1783 } else { 1784 container.length = 1785 cpu_to_le32(d->length + sizeof(container)); 1786 } 1787 container.type = cpu_to_le16(TYPE_DATA); 1788 container.code = cpu_to_le16(d->code); 1789 container.trans = cpu_to_le32(d->trans); 1790 usb_packet_copy(p, &container, sizeof(container)); 1791 d->first = false; 1792 if (dlen > p->iov.size - sizeof(container)) { 1793 dlen = p->iov.size - sizeof(container); 1794 } 1795 } else { 1796 if (dlen > p->iov.size) { 1797 dlen = p->iov.size; 1798 } 1799 } 1800 if (d->fd == -1) { 1801 usb_packet_copy(p, d->data + d->offset, dlen); 1802 } else { 1803 if (d->alloc < p->iov.size) { 1804 d->alloc = p->iov.size; 1805 d->data = g_realloc(d->data, d->alloc); 1806 } 1807 rc = read(d->fd, d->data, dlen); 1808 if (rc != dlen) { 1809 memset(d->data, 0, dlen); 1810 s->result->code = RES_INCOMPLETE_TRANSFER; 1811 } 1812 usb_packet_copy(p, d->data, dlen); 1813 } 1814 d->offset += dlen; 1815 if (d->offset == d->length) { 1816 usb_mtp_data_free(s->data_in); 1817 s->data_in = NULL; 1818 } 1819 } else if (s->result != NULL) { 1820 MTPControl *r = s->result; 1821 int length = sizeof(container) + r->argc * sizeof(uint32_t); 1822 if (r->code == RES_OK) { 1823 trace_usb_mtp_success(s->dev.addr, r->trans, 1824 (r->argc > 0) ? r->argv[0] : 0, 1825 (r->argc > 1) ? r->argv[1] : 0); 1826 } else { 1827 trace_usb_mtp_error(s->dev.addr, r->code, r->trans, 1828 (r->argc > 0) ? r->argv[0] : 0, 1829 (r->argc > 1) ? r->argv[1] : 0); 1830 } 1831 container.length = cpu_to_le32(length); 1832 container.type = cpu_to_le16(TYPE_RESPONSE); 1833 container.code = cpu_to_le16(r->code); 1834 container.trans = cpu_to_le32(r->trans); 1835 for (i = 0; i < r->argc; i++) { 1836 params[i] = cpu_to_le32(r->argv[i]); 1837 } 1838 usb_packet_copy(p, &container, sizeof(container)); 1839 usb_packet_copy(p, ¶ms, length - sizeof(container)); 1840 g_free(s->result); 1841 s->result = NULL; 1842 } 1843 break; 1844 case EP_DATA_OUT: 1845 if (p->iov.size < sizeof(container)) { 1846 trace_usb_mtp_stall(s->dev.addr, "packet too small"); 1847 p->status = USB_RET_STALL; 1848 return; 1849 } 1850 if ((s->data_out != NULL) && !s->data_out->first) { 1851 container_type = TYPE_DATA; 1852 } else { 1853 usb_packet_copy(p, &container, sizeof(container)); 1854 container_type = le16_to_cpu(container.type); 1855 } 1856 switch (container_type) { 1857 case TYPE_COMMAND: 1858 if (s->data_in || s->data_out || s->result) { 1859 trace_usb_mtp_stall(s->dev.addr, "transaction inflight"); 1860 p->status = USB_RET_STALL; 1861 return; 1862 } 1863 cmd.code = le16_to_cpu(container.code); 1864 cmd.argc = (le32_to_cpu(container.length) - sizeof(container)) 1865 / sizeof(uint32_t); 1866 cmd.trans = le32_to_cpu(container.trans); 1867 if (cmd.argc > ARRAY_SIZE(cmd.argv)) { 1868 cmd.argc = ARRAY_SIZE(cmd.argv); 1869 } 1870 if (p->iov.size < sizeof(container) + cmd.argc * sizeof(uint32_t)) { 1871 trace_usb_mtp_stall(s->dev.addr, "packet too small"); 1872 p->status = USB_RET_STALL; 1873 return; 1874 } 1875 usb_packet_copy(p, ¶ms, cmd.argc * sizeof(uint32_t)); 1876 for (i = 0; i < cmd.argc; i++) { 1877 cmd.argv[i] = le32_to_cpu(params[i]); 1878 } 1879 trace_usb_mtp_command(s->dev.addr, cmd.code, cmd.trans, 1880 (cmd.argc > 0) ? cmd.argv[0] : 0, 1881 (cmd.argc > 1) ? cmd.argv[1] : 0, 1882 (cmd.argc > 2) ? cmd.argv[2] : 0, 1883 (cmd.argc > 3) ? cmd.argv[3] : 0, 1884 (cmd.argc > 4) ? cmd.argv[4] : 0); 1885 usb_mtp_command(s, &cmd); 1886 break; 1887 case TYPE_DATA: 1888 /* One of the previous transfers has already errored but the 1889 * responder is still sending data associated with it 1890 */ 1891 if (s->result != NULL) { 1892 return; 1893 } 1894 usb_mtp_get_data(s, &container, p); 1895 break; 1896 default: 1897 /* not needed as long as the mtp device is read-only */ 1898 p->status = USB_RET_STALL; 1899 return; 1900 } 1901 break; 1902 case EP_EVENT: 1903 #ifdef CONFIG_INOTIFY1 1904 if (!QTAILQ_EMPTY(&s->events)) { 1905 struct MTPMonEntry *e = QTAILQ_LAST(&s->events, events); 1906 uint32_t handle; 1907 int len = sizeof(container) + sizeof(uint32_t); 1908 1909 if (p->iov.size < len) { 1910 trace_usb_mtp_stall(s->dev.addr, 1911 "packet too small to send event"); 1912 p->status = USB_RET_STALL; 1913 return; 1914 } 1915 1916 QTAILQ_REMOVE(&s->events, e, next); 1917 container.length = cpu_to_le32(len); 1918 container.type = cpu_to_le32(TYPE_EVENT); 1919 container.code = cpu_to_le16(e->event); 1920 container.trans = 0; /* no trans specific events */ 1921 handle = cpu_to_le32(e->handle); 1922 usb_packet_copy(p, &container, sizeof(container)); 1923 usb_packet_copy(p, &handle, sizeof(uint32_t)); 1924 g_free(e); 1925 return; 1926 } 1927 #endif 1928 p->status = USB_RET_NAK; 1929 return; 1930 default: 1931 trace_usb_mtp_stall(s->dev.addr, "invalid endpoint"); 1932 p->status = USB_RET_STALL; 1933 return; 1934 } 1935 1936 if (p->actual_length == 0) { 1937 trace_usb_mtp_nak(s->dev.addr, p->ep->nr); 1938 p->status = USB_RET_NAK; 1939 return; 1940 } else { 1941 trace_usb_mtp_xfer(s->dev.addr, p->ep->nr, p->actual_length, 1942 p->iov.size); 1943 return; 1944 } 1945 } 1946 1947 static void usb_mtp_realize(USBDevice *dev, Error **errp) 1948 { 1949 MTPState *s = USB_MTP(dev); 1950 1951 usb_desc_create_serial(dev); 1952 usb_desc_init(dev); 1953 QTAILQ_INIT(&s->objects); 1954 if (s->desc == NULL) { 1955 if (s->root == NULL) { 1956 error_setg(errp, "usb-mtp: x-root property must be configured"); 1957 return; 1958 } 1959 s->desc = strrchr(s->root, '/'); 1960 if (s->desc && s->desc[0]) { 1961 s->desc = g_strdup(s->desc + 1); 1962 } else { 1963 s->desc = g_strdup("none"); 1964 } 1965 } 1966 /* Mark store as RW */ 1967 if (!s->readonly) { 1968 s->flags |= (1 << MTP_FLAG_WRITABLE); 1969 } 1970 1971 } 1972 1973 static const VMStateDescription vmstate_usb_mtp = { 1974 .name = "usb-mtp", 1975 .unmigratable = 1, 1976 .version_id = 1, 1977 .minimum_version_id = 1, 1978 .fields = (VMStateField[]) { 1979 VMSTATE_USB_DEVICE(dev, MTPState), 1980 VMSTATE_END_OF_LIST() 1981 } 1982 }; 1983 1984 static Property mtp_properties[] = { 1985 DEFINE_PROP_STRING("x-root", MTPState, root), 1986 DEFINE_PROP_STRING("desc", MTPState, desc), 1987 DEFINE_PROP_BOOL("readonly", MTPState, readonly, true), 1988 DEFINE_PROP_END_OF_LIST(), 1989 }; 1990 1991 static void usb_mtp_class_initfn(ObjectClass *klass, void *data) 1992 { 1993 DeviceClass *dc = DEVICE_CLASS(klass); 1994 USBDeviceClass *uc = USB_DEVICE_CLASS(klass); 1995 1996 uc->realize = usb_mtp_realize; 1997 uc->product_desc = "QEMU USB MTP"; 1998 uc->usb_desc = &desc; 1999 uc->cancel_packet = usb_mtp_cancel_packet; 2000 uc->handle_attach = usb_desc_attach; 2001 uc->handle_reset = usb_mtp_handle_reset; 2002 uc->handle_control = usb_mtp_handle_control; 2003 uc->handle_data = usb_mtp_handle_data; 2004 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 2005 dc->desc = "USB Media Transfer Protocol device"; 2006 dc->fw_name = "mtp"; 2007 dc->vmsd = &vmstate_usb_mtp; 2008 dc->props = mtp_properties; 2009 } 2010 2011 static TypeInfo mtp_info = { 2012 .name = TYPE_USB_MTP, 2013 .parent = TYPE_USB_DEVICE, 2014 .instance_size = sizeof(MTPState), 2015 .class_init = usb_mtp_class_initfn, 2016 }; 2017 2018 static void usb_mtp_register_types(void) 2019 { 2020 type_register_static(&mtp_info); 2021 } 2022 2023 type_init(usb_mtp_register_types) 2024