bool MTPDevice::connect(LIBMTP_raw_device_t *dev)
{
    if (m_device) {
        logerr("Already connected.\n");
        return true;
    }

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    m_device = LIBMTP_Open_Raw_Device_Uncached(dev);
    StreamHelper::on();

    if (!m_device) {
        LIBMTP_Dump_Errorstack(m_device);
        return false;
    }

    if (!enumStorages())
        return false;

    // Retrieve capabilities.
    m_capabilities = MTPDevice::getCapabilities(*this);

    logmsg("Connected.\n");
    return true;
}
bool MTPDevice::connect(const std::string &dev_file)
{
    if (m_device) {
        logerr("Already connected.\n");
        return true;
    }

    LIBMTP_raw_device_t *raw_device = smtpfs_raw_device_new(dev_file);
    if (!raw_device) {
        logerr("Can not open such device '", dev_file, "'.\n");
        return false;
    }

#ifdef HAVE_LIBUSB1
    // Try to reset USB device, so we don't wait until LIBMTP times out.
    // We do this every time we are about to mount a device, but better
    // connect on first try, than wait for 60s timeout.
    smtpfs_reset_device(raw_device);
#endif // HAVE_LIBUSB1

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device);
    StreamHelper::on();
    smtpfs_raw_device_free(raw_device);

    if (!m_device) {
        LIBMTP_Dump_Errorstack(m_device);
        return false;
    }

    if (!enumStorages())
        return false;

    logmsg("Connected.\n");
    return true;
}
Example #3
0
/**
 * @brief Get's the correct object from the device.
 * !Important! Release Device after using the returned object
 * @param pathItems A QStringList containing the items of the filepath
 * @return QPair with the object and its device. pair.fist is a nullpointer if the object doesn't exist or for root or, depending on the pathItems size device (1), storage (2) or file (>=3)
 */
QPair<void*, LIBMTP_mtpdevice_t*> MTPSlave::getPath ( const QString& path )
{
    QStringList pathItems = path.split ( QLatin1Char ( '/' ), QString::SkipEmptyParts );

    kDebug ( KIO_MTP ) << path << pathItems.size();

    QPair<void*, LIBMTP_mtpdevice_t*> ret;

    // Don' handle the root directory
    if ( pathItems.size() <= 0 )
    {
        return ret;
    }

    QMap<QString, LIBMTP_raw_device_t*> devices = getRawDevices();

    if ( devices.contains ( pathItems.at ( 0 ) ) )
    {
        LIBMTP_mtpdevice_t *device = LIBMTP_Open_Raw_Device_Uncached ( devices.value ( pathItems.at ( 0 ) ) );

        // return specific device
        if ( pathItems.size() == 1 )
        {
            ret.first = device;
            ret.second = device;

            kDebug(KIO_MTP) << "returning LIBMTP_mtpdevice_t";
        }

        if ( pathItems.size() > 2 )
        {
            // Query Cache after we have the device
            uint32_t c_fileID = fileCache->queryPath ( path );
            if ( c_fileID != 0 )
            {
                kDebug() << "Match found in cache, checking device";

                LIBMTP_file_t* file = LIBMTP_Get_Filemetadata ( device, c_fileID );
                if ( file )
                {
                    kDebug ( KIO_MTP ) << "Found file in cache";
                    ret.first = file;
                    ret.second = device;

                    kDebug(KIO_MTP) << "returning LIBMTP_file_t";

                    return ret;
                }
            }
            // Query cache for parent
            else if ( pathItems.size() > 3 )
            {
                QString parentPath = convertToPath ( pathItems, pathItems.size() - 1 );
                uint32_t c_parentID = fileCache->queryPath ( parentPath );

                kDebug() << "Match for parent found in cache, checking device";

                LIBMTP_file_t* parent = LIBMTP_Get_Filemetadata ( device, c_parentID );
                if ( parent )
                {
                    kDebug ( KIO_MTP ) << "Found parent in cache";
                    fileCache->addPath( parentPath, c_parentID );

                    QMap<QString, LIBMTP_file_t*> files = getFiles ( device, parent->storage_id, c_parentID );

                    if ( files.contains ( pathItems.last() ) )
                    {
                        LIBMTP_file_t* file = files.value( pathItems.last() );

                        ret.first = file;
                        ret.second = device;

                        kDebug(KIO_MTP) << "returning LIBMTP_file_t";

                        fileCache->addPath( path, file->item_id );
                    }

                    return ret;
                }
            }
        }

        QMap<QString, LIBMTP_devicestorage_t*> storages = getDevicestorages ( device );

        if ( pathItems.size() > 1 && storages.contains ( pathItems.at ( 1 ) ) )
        {
            LIBMTP_devicestorage_t *storage = storages.value ( pathItems.at ( 1 ) );

            if ( pathItems.size() == 2 )
            {
                ret.first = storage;
                ret.second = device;

                kDebug(KIO_MTP) << "returning LIBMTP_devicestorage_t";

                return ret;
            }

            int currentLevel = 2, currentParent = 0xFFFFFFFF;

            QMap<QString, LIBMTP_file_t*> files;

            // traverse further while depth not reached
            while ( currentLevel < pathItems.size() )
            {
                files = getFiles ( device, storage->id, currentParent );

                if ( files.contains ( pathItems.at ( currentLevel ) ) )
                {
                    currentParent = files.value ( pathItems.at ( currentLevel ) )->item_id;
                }
                else
                {

                    kDebug(KIO_MTP) << "returning LIBMTP_file_t";

                    return ret;
                }
                currentLevel++;
            }

            ret.first = LIBMTP_Get_Filemetadata ( device, currentParent );
            ret.second = device;

            fileCache->addPath ( path, currentParent );
        }
    }

    return ret;
}
Example #4
0
int main (int argc, char **argv)
{
  LIBMTP_raw_device_t * rawdevices;
  int numrawdevices;
  LIBMTP_error_number_t err;
  int i;

  int opt;
  extern int optind;
  extern char *optarg;

  while ((opt = getopt(argc, argv, "d")) != -1 ) {
    switch (opt) {
    case 'd':
      LIBMTP_Set_Debug(LIBMTP_DEBUG_PTP | LIBMTP_DEBUG_DATA);
      break;
    }
  }

  argc -= optind;
  argv += optind;

  LIBMTP_Init();

  err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices);
  switch(err) {
  case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
    fprintf(stdout, "   No raw devices found.\n");
    return 0;
  case LIBMTP_ERROR_CONNECTING:
    fprintf(stderr, "Detect: There has been an error connecting. Exiting\n");
    return 1;
  case LIBMTP_ERROR_MEMORY_ALLOCATION:
    fprintf(stderr, "Detect: Encountered a Memory Allocation Error. Exiting\n");
    return 1;
  case LIBMTP_ERROR_NONE:
    break;
  case LIBMTP_ERROR_GENERAL:
  default:
    fprintf(stderr, "Unknown connection error.\n");
    return 1;
  }

  /* Iterate over connected MTP devices */
  fprintf(stdout, "Attempting to connect device(s)\n");
  for (i = 0; i < numrawdevices; i++) {
    LIBMTP_mtpdevice_t *device;
    LIBMTP_devicestorage_t *storage;
    char *friendlyname;
    int ret;

    device = LIBMTP_Open_Raw_Device_Uncached(&rawdevices[i]);
    if (device == NULL) {
      fprintf(stderr, "Unable to open raw device %d\n", i);
      continue;
    }

    LIBMTP_Dump_Errorstack(device);
    LIBMTP_Clear_Errorstack(device);

    friendlyname = LIBMTP_Get_Friendlyname(device);
    if (friendlyname == NULL) {
      printf("Device: (NULL)\n");
    } else {
      printf("Device: %s\n", friendlyname);
      free(friendlyname);
    }

    /* Get all storages for this device */
    ret = LIBMTP_Get_Storage(device, LIBMTP_STORAGE_SORTBY_NOTSORTED);
    if (ret != 0) {
      perror("LIBMTP_Get_Storage()");
      goto bailout;
    }

    /* Loop over storages */
    for (storage = device->storage; storage != 0; storage = storage->next) {
      fprintf(stdout, "Storage: %s\n", storage->StorageDescription);
      recursive_file_tree(device, storage, 0, 0);
    }

  bailout:
    LIBMTP_Release_Device(device);
  } /* End For Loop */

  free(rawdevices);

  printf("OK.\n");

  return 0;
}
Example #5
0
int main(int argc, char **argv)
{
    int mainret = 0;

    if (argc < 2)
    {
        fprintf(stderr, "usage: %s [-d] mountpoint\n", argv[0]);
        exit(1);
    }
    char *mount_point = argv[1];
    argc -= 1;
    argv += 1;

    // LIBMTP_Set_Debug(LIBMTP_DEBUG_PTP | LIBMTP_DEBUG_DATA);
    LIBMTP_Init();

    LIBMTP_error_number_t mtperr;

    LIBMTP_raw_device_t *rawdevs;
    int nrawdev;
    mtperr = LIBMTP_Detect_Raw_Devices(&rawdevs, &nrawdev);
    switch (mtperr)
    {
    case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
        fprintf(stderr, "no raw devices\n");
        exit(0);
    case LIBMTP_ERROR_CONNECTING:
        fprintf(stderr, "ERROR connecting\n");
        exit(1);
    case LIBMTP_ERROR_MEMORY_ALLOCATION:
        fprintf(stderr, "ERROR memory allocation\n");
        exit(1);
    case LIBMTP_ERROR_NONE:
        break;
    default:
        fprintf(stderr, "ERROR unknown\n");
        exit(1);
    }

    printf("%d raw devices:\n", nrawdev);
    int i;
    for (i = 0; i < nrawdev; ++i)
    {
        printf("  device #%d: %s: %s (%04X:%04X) @ bus %d, dev %d\n", i,
               rawdevs[i].device_entry.vendor, rawdevs[i].device_entry.product,
               rawdevs[i].device_entry.vendor_id,
               rawdevs[i].device_entry.product_id,
               rawdevs[i].bus_location,
               rawdevs[i].devnum);
    }

    mtpfuse_t ctx;
    memset(&ctx, 0, sizeof(ctx));

    printf("opening raw device #0...\n");
    ctx.dev = LIBMTP_Open_Raw_Device_Uncached(&rawdevs[0]);
    if (!ctx.dev)
    {
        fprintf(stderr, "ERROR opening raw device #0\n");
        exit(1);
    }

    LIBMTP_Dump_Errorstack(ctx.dev);
    LIBMTP_Clear_Errorstack(ctx.dev);

    char *name = LIBMTP_Get_Friendlyname(ctx.dev);
    printf("opened raw device %s.\n", name);

    int ret = LIBMTP_Get_Storage(ctx.dev, LIBMTP_STORAGE_SORTBY_NOTSORTED);
    if (ret != 0)
    {
        fprintf(stderr, "ERROR get %s's storage:\n", name);
        LIBMTP_Dump_Errorstack(ctx.dev);
        mainret = 1;
        goto done;
    }

    printf("device's storage:\n");
    LIBMTP_devicestorage_t *storage;
    for (storage = ctx.dev->storage, i = 0; storage; storage = storage->next, ++i)
    {
        printf("  storage #%d: %d - %s\n", i, storage->id, storage->StorageDescription);
    }
    if (i <= 0)
    {
        fprintf(stderr, "there is no storage that is usable.\n");
        mainret = 1;
        goto done;
    }

    mainret = fuse_main(argc, argv, &mtpfuse_ops, &ctx);

done:
    LIBMTP_Release_Device(ctx.dev);
    return mainret;
}
Example #6
0
static int
Device_init(Device *self, PyObject *args, PyObject *kwds)
{
    unsigned long busnum;
    unsigned char devnum;
    unsigned short vendor_id, product_id;
    PyObject *usb_serialnum;
    char *vendor, *product, *friendly_name, *manufacturer_name, *model_name, *serial_number, *device_version;
    LIBMTP_raw_device_t *rawdevs = NULL, rdev;
    int numdevs, c, tried_count = 0;
    LIBMTP_mtpdevice_t *dev = NULL;
    LIBMTP_error_number_t err;

    if (!PyArg_ParseTuple(args, "kBHHssO", &busnum, &devnum, &vendor_id, &product_id, &vendor, &product, &usb_serialnum)) return -1;

    // We have to build and search the rawdevice list instead of creating a
    // rawdevice directly as otherwise, dynamic bug flag assignment in libmtp
    // does not work
    Py_BEGIN_ALLOW_THREADS;
    err = LIBMTP_Detect_Raw_Devices(&rawdevs, &numdevs);
    Py_END_ALLOW_THREADS;
    if (err == LIBMTP_ERROR_NO_DEVICE_ATTACHED) { PyErr_SetString(MTPError, "No raw devices found"); return -1; }
    if (err == LIBMTP_ERROR_CONNECTING) { PyErr_SetString(MTPError, "There has been an error connecting"); return -1; }
    if (err == LIBMTP_ERROR_MEMORY_ALLOCATION) { PyErr_NoMemory(); return -1; }
    if (err != LIBMTP_ERROR_NONE) { PyErr_SetString(MTPError, "Failed to detect raw MTP devices"); return -1; }

    for (c = 0; c < numdevs; c++) {
        rdev = rawdevs[c];
        if (rdev.bus_location == (uint32_t)busnum && rdev.devnum == (uint8_t)devnum) {
            tried_count += 1;
            Py_BEGIN_ALLOW_THREADS;
            dev = LIBMTP_Open_Raw_Device_Uncached(&rdev);
            Py_END_ALLOW_THREADS;
            if (dev != NULL) break;
        }
    }

    if (rawdevs != NULL) free(rawdevs);
    if (dev == NULL) { 
        if (tried_count == 0) PyErr_Format(MTPError, "No device with busnum=%lu and devnum=%u found", busnum, devnum); 
        else PyErr_Format(MTPError, "Unable to open MTP device with busnum=%lu and devnum=%u, tried %d such devices", busnum, devnum, tried_count); 
        return -1;
    }

    self->device = dev;
    self->ids = Py_BuildValue("kBHHO", busnum, devnum, vendor_id, product_id, usb_serialnum);
    if (self->ids == NULL) return -1;

    Py_BEGIN_ALLOW_THREADS;
    friendly_name = LIBMTP_Get_Friendlyname(self->device);
    manufacturer_name = LIBMTP_Get_Manufacturername(self->device);
    model_name = LIBMTP_Get_Modelname(self->device);
    serial_number = LIBMTP_Get_Serialnumber(self->device);
    device_version = LIBMTP_Get_Deviceversion(self->device);
    Py_END_ALLOW_THREADS;

    if (friendly_name != NULL) {
        self->friendly_name = PyUnicode_FromString(friendly_name);
        free(friendly_name);
    }
    if (self->friendly_name == NULL) { self->friendly_name = Py_None; Py_INCREF(Py_None); }

    if (manufacturer_name != NULL) {
        self->manufacturer_name = PyUnicode_FromString(manufacturer_name);
        free(manufacturer_name);
    }
    if (self->manufacturer_name == NULL) { self->manufacturer_name = Py_None; Py_INCREF(Py_None); }

    if (model_name != NULL) {
        self->model_name = PyUnicode_FromString(model_name);
        free(model_name);
    }
    if (self->model_name == NULL) { self->model_name = Py_None; Py_INCREF(Py_None); }

    if (serial_number != NULL) {
        self->serial_number = PyUnicode_FromString(serial_number);
        free(serial_number);
    }
    if (self->serial_number == NULL) { self->serial_number = Py_None; Py_INCREF(Py_None); }

    if (device_version != NULL) {
        self->device_version = PyUnicode_FromString(device_version);
        free(device_version);
    }
    if (self->device_version == NULL) { self->device_version = Py_None; Py_INCREF(Py_None); }

    return 0;
}
bool MTPDevice::connect_priv(int dev_no, const std::string &dev_file)
{
    if (m_device) {
        logerr("Already connected.\n");
        return true;
    }

    int raw_devices_cnt;
    LIBMTP_raw_device_t *raw_devices;

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    LIBMTP_error_number_t err = LIBMTP_Detect_Raw_Devices(
        &raw_devices, &raw_devices_cnt);
    StreamHelper::on();

    if (err != LIBMTP_ERROR_NONE) {
        switch(err) {
        case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
            logerr("No raw devices found.\n");
            break;
        case LIBMTP_ERROR_CONNECTING:
            logerr("There has been an error connecting. Exiting.\n");
            break;
        case LIBMTP_ERROR_MEMORY_ALLOCATION:
            logerr("Encountered a Memory Allocation Error. Exiting.\n");
            break;
        case LIBMTP_ERROR_GENERAL:
            logerr("General error occured. Exiting.\n");
            break;
        case LIBMTP_ERROR_USB_LAYER:
            logerr("USB Layer error occured. Exiting.\n");
            break;
        default:
            break;
        }
        return false;
    }

#ifndef HAVE_LIBUSB1
    if (!dev_file.empty()) {
        uint8_t bnum, dnum;
        dev_no = raw_devices_cnt;

        if (smtpfs_usb_devpath(dev_file, &bnum, &dnum))
            for (dev_no = 0; dev_no < raw_devices_cnt; ++dev_no)
                if (bnum == raw_devices[dev_no].bus_location &&
                    dnum == raw_devices[dev_no].devnum)
                    break;

        if (dev_no == raw_devices_cnt) {
            logerr("Can not open such device '", dev_file, "'.\n");
            free(static_cast<void*>(raw_devices));
            return false;
        }
    }
#endif // !HAVE_LIBUSB1

    if (dev_no < 0 || dev_no >= raw_devices_cnt) {
        logerr("Can not connect to device no. ", dev_no + 1, ".\n");
        free(static_cast<void*>(raw_devices));
        return false;
    }

    LIBMTP_raw_device_t *raw_device = &raw_devices[dev_no];

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device);
    StreamHelper::on();
    free(static_cast<void*>(raw_devices));

    if (!m_device) {
        LIBMTP_Dump_Errorstack(m_device);
        return false;
    }

    if (!enumStorages())
        return false;

    // Retrieve capabilities.
    m_capabilities = MTPDevice::getCapabilities(*this);

    logmsg("Connected.\n");
    return true;
}
Example #8
0
int main (int argc, char **argv)
{
    LIBMTP_raw_device_t * rawdevices;
    int numrawdevices;
    LIBMTP_error_number_t err;
    int i;

    int opt;
    extern int optind;
    extern char *optarg;

    while ((opt = getopt(argc, argv, "d")) != -1 ) {
        switch (opt) {
        case 'd':
            LIBMTP_Set_Debug(LIBMTP_DEBUG_PTP | LIBMTP_DEBUG_DATA);
            break;
        }
    }

    argc -= optind;
    argv += optind;

    LIBMTP_Init();

    fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n");

    fprintf(stdout, "Listing raw device(s)\n");
    err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices);
    switch(err) {
    case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
        fprintf(stdout, "   No raw devices found.\n");
        return 0;
    case LIBMTP_ERROR_CONNECTING:
        fprintf(stderr, "Detect: There has been an error connecting. Exiting\n");
        return 1;
    case LIBMTP_ERROR_MEMORY_ALLOCATION:
        fprintf(stderr, "Detect: Encountered a Memory Allocation Error. Exiting\n");
        return 1;
    case LIBMTP_ERROR_NONE:
    {
        int i;

        fprintf(stdout, "   Found %d device(s):\n", numrawdevices);
        for (i = 0; i < numrawdevices; i++) {
            if (rawdevices[i].device_entry.vendor != NULL ||
                    rawdevices[i].device_entry.product != NULL) {
                fprintf(stdout, "   %s: %s (%04x:%04x) @ bus %d, dev %d\n",
                        rawdevices[i].device_entry.vendor,
                        rawdevices[i].device_entry.product,
                        rawdevices[i].device_entry.vendor_id,
                        rawdevices[i].device_entry.product_id,
                        rawdevices[i].bus_location,
                        rawdevices[i].devnum);
            } else {
                fprintf(stdout, "   %04x:%04x @ bus %d, dev %d\n",
                        rawdevices[i].device_entry.vendor_id,
                        rawdevices[i].device_entry.product_id,
                        rawdevices[i].bus_location,
                        rawdevices[i].devnum);
            }
        }
    }
    break;
    case LIBMTP_ERROR_GENERAL:
    default:
        fprintf(stderr, "Unknown connection error.\n");
        return 1;
    }

    /* Iterate over connected MTP devices */
    fprintf(stdout, "Attempting to connect device(s)\n");
    for (i = 0; i < numrawdevices; i++) {
        LIBMTP_mtpdevice_t *device;
        LIBMTP_devicestorage_t *storage;
        char *friendlyname;
        char *syncpartner;
        char *sectime;
        char *devcert;
        uint16_t *filetypes;
        uint16_t filetypes_len;
        uint8_t maxbattlevel;
        uint8_t currbattlevel;
        int ret;

        device = LIBMTP_Open_Raw_Device_Uncached(&rawdevices[i]);
        if (device == NULL) {
            fprintf(stderr, "Unable to open raw device %d\n", i);
            continue;
        }

        LIBMTP_Dump_Errorstack(device);
        LIBMTP_Clear_Errorstack(device);
        LIBMTP_Dump_Device_Info(device);

        printf("MTP-specific device properties:\n");
        // The friendly name
        friendlyname = LIBMTP_Get_Friendlyname(device);
        if (friendlyname == NULL) {
            fprintf(stdout, "   Friendly name: (NULL)\n");
        } else {
            fprintf(stdout, "   Friendly name: %s\n", friendlyname);
            free(friendlyname);
        }
        syncpartner = LIBMTP_Get_Syncpartner(device);
        if (syncpartner == NULL) {
            fprintf(stdout, "   Synchronization partner: (NULL)\n");
        } else {
            fprintf(stdout, "   Synchronization partner: %s\n", syncpartner);
            free(syncpartner);
        }

        // Some battery info
        ret = LIBMTP_Get_Batterylevel(device, &maxbattlevel, &currbattlevel);
        if (ret == 0) {
            fprintf(stdout, "   Battery level %d of %d (%d%%)\n",currbattlevel, maxbattlevel,
                    (int) ((float) currbattlevel/ (float) maxbattlevel * 100.0));
        } else {
            // Silently ignore. Some devices does not support getting the
            // battery level.
            LIBMTP_Clear_Errorstack(device);
        }

        ret = LIBMTP_Get_Supported_Filetypes(device, &filetypes, &filetypes_len);
        if (ret == 0) {
            uint16_t i;

            printf("libmtp supported (playable) filetypes:\n");
            for (i = 0; i < filetypes_len; i++) {
                fprintf(stdout, "   %s\n", LIBMTP_Get_Filetype_Description(filetypes[i]));
            }
        } else {
            LIBMTP_Dump_Errorstack(device);
            LIBMTP_Clear_Errorstack(device);
        }

        // Secure time XML fragment
        ret = LIBMTP_Get_Secure_Time(device, &sectime);
        if (ret == 0 && sectime != NULL) {
            fprintf(stdout, "\nSecure Time:\n%s\n", sectime);
            free(sectime);
        } else {
            // Silently ignore - there may be devices not supporting secure time.
            LIBMTP_Clear_Errorstack(device);
        }

        // Device certificate XML fragment
        if (rawdevices[i].device_entry.vendor_id == 0x041e) {
            /*
             * This code is currently disabled except for vendors we
             * know does support it: all devices say that
             * they support getting a device certificate but a lot of
             * them obviously doesn't, instead they crash when you try
             * to obtain it.
             */
            ret = LIBMTP_Get_Device_Certificate(device, &devcert);
            if (ret == 0 && devcert != NULL) {
                fprintf(stdout, "\nDevice Certificate:\n%s\n", devcert);
                free(devcert);
            } else {
                fprintf(stdout, "Unable to acquire device certificate, perhaps this device "
                        "does not support this\n");
                LIBMTP_Dump_Errorstack(device);
                LIBMTP_Clear_Errorstack(device);
            }
        }

        /* Try to get Media player device info XML file... */
        /* Loop over storages */
        for (storage = device->storage; storage != 0; storage = storage->next) {
            LIBMTP_file_t *files;

            /* Get file listing for the root directory, no other dirs */
            files = LIBMTP_Get_Files_And_Folders(device,
                                                 storage->id,
                                                 0);

            if (files != NULL) {
                LIBMTP_file_t *file, *tmp;
                file = files;
                while (file != NULL) {
                    if (!strcmp(file->filename, "WMPInfo.xml") ||
                            !strcmp(file->filename, "WMPinfo.xml") ||
                            !strcmp(file->filename, "default-capabilities.xml")) {
                        if (file->item_id != 0) {
                            /* Dump this file */
                            FILE *xmltmp = tmpfile();
                            int tmpfiledescriptor = fileno(xmltmp);

                            if (tmpfiledescriptor != -1) {
                                int ret = LIBMTP_Get_Track_To_File_Descriptor(device,
                                          file->item_id,
                                          tmpfiledescriptor,
                                          NULL,
                                          NULL);
                                if (ret == 0) {
                                    uint8_t *buf = NULL;
                                    uint32_t readbytes;

                                    buf = malloc(XML_BUFSIZE);
                                    if (buf == NULL) {
                                        printf("Could not allocate %08x bytes...\n", XML_BUFSIZE);
                                        LIBMTP_Dump_Errorstack(device);
                                        LIBMTP_Clear_Errorstack(device);
                                        free(rawdevices);
                                        return 1;
                                    }

                                    lseek(tmpfiledescriptor, 0, SEEK_SET);
                                    readbytes = read(tmpfiledescriptor, (void*) buf, XML_BUFSIZE);

                                    if (readbytes >= 2 && readbytes < XML_BUFSIZE) {
                                        fprintf(stdout, "\n%s file contents:\n", file->filename);
                                        dump_xml_fragment(buf, readbytes);
                                    } else {
                                        perror("Unable to read file");
                                        LIBMTP_Dump_Errorstack(device);
                                        LIBMTP_Clear_Errorstack(device);
                                    }
                                    free(buf);
                                } else {
                                    LIBMTP_Dump_Errorstack(device);
                                    LIBMTP_Clear_Errorstack(device);
                                }
                                fclose(xmltmp);
                            }
                        }
                    }
                    tmp = file;
                    file = file->next;
                    LIBMTP_destroy_file_t(tmp);
                }
            }
        }
        LIBMTP_Release_Device(device);
    } /* End For Loop */

    free(rawdevices);

    printf("OK.\n");

    return 0;
}
bool MTPDevice::connect(int dev_no)
{
    if (m_device) {
        logerr("Already connected.\n");
        return true;
    }

    int raw_devices_cnt;
    LIBMTP_raw_device_t *raw_devices;

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    LIBMTP_error_number_t err = LIBMTP_Detect_Raw_Devices(
        &raw_devices, &raw_devices_cnt);
    StreamHelper::on();

    if (dev_no < 0 || dev_no >= raw_devices_cnt) {
        logerr("Can not connect to device no. ", dev_no + 1, ".\n");
        free(static_cast<void*>(raw_devices));
        return false;
    }

    if (err != LIBMTP_ERROR_NONE) {
        switch(err) {
        case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
            logerr("No raw devices found.\n");
            break;
        case LIBMTP_ERROR_CONNECTING:
            logerr("There has been an error connecting. Exiting.\n");
            break;
        case LIBMTP_ERROR_MEMORY_ALLOCATION:
            logerr("Encountered a Memory Allocation Error. Exiting.\n");
            break;
        case LIBMTP_ERROR_GENERAL:
            logerr("General error occured. Exiting.\n");
            break;
        case LIBMTP_ERROR_USB_LAYER:
            logerr("USB Layer error occured. Exiting.\n");
            break;
        default:
            break;
        }
        return false;
    }

    LIBMTP_raw_device_t *raw_device = &raw_devices[dev_no];

#ifdef HAVE_LIBUSB1
    // Try to reset USB device, so we don't wait until LIBMTP times out.
    // We do this every time we are about to mount a device, but better
    // connect on first try, than wait for 60s timeout.
    smtpfs_reset_device(raw_device);
#endif // HAVE_LIBUSB1

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device);
    StreamHelper::on();
    free(static_cast<void*>(raw_devices));

    if (!m_device) {
        LIBMTP_Dump_Errorstack(m_device);
        return false;
    }

    if (!enumStorages())
        return false;

    logmsg("Connected.\n");
    return true;
}