0
votes

I'm currently working on a mac application to the transfer file from mac to mtp device such as usb.

I use the code below to add it:

LIBMTP_file_t *genfile;

char *AbsolutePath = NULL;
char *FileNameOnly = NULL;

QFileInfo fileInfo(filename);

FileNameOnly = convertQStr2char(fileInfo.fileName());
AbsolutePath = convertQStr2char(fileInfo.absoluteFilePath());

genfile = LIBMTP_new_file_t();

genfile->filesize = filesize;
genfile->filename = FileNameOnly;
genfile->filetype = file_type;
genfile->parent_id = CurrentFolderID;
genfile->storage_id = PulsDeviceMngr->devicestorage->id;

if ((genfile->filetype != LIBMTP_FILETYPE_ALBUM) && (genfile->filetype != LIBMTP_FILETYPE_PLAYLIST)) {
    ret = LIBMTP_Send_File_From_File(PulsDeviceMngr->device, AbsolutePath, genfile, ProgressBar, NULL);
    if (ret != 0) {
        qDebug() << "Error sending file";
        LIBMTP_Dump_Errorstack(PulsDeviceMngr->device);
        LIBMTP_Clear_Errorstack(PulsDeviceMngr->device);
    } else {
        PulsDeviceMngr->devicestorage->FreeSpaceInBytes -= filesize;
        PulsDeviceMngr->devicestorage->FreeSpaceInObjects--;
    }
}
LIBMTP_destroy_file_t(genfile);

This basically what is required by mtp to make it works.

I'm usine QT/C++ to develop the Software.

it seems that the QString is not impacted but only the char . char is needed because the api used only support char . I'm converting QString to char using the following code.

char *mtp_wrapper::convertQStr2char(QString str) {
    QByteArray latin_str = str.toLatin1();
    char *return_str = latin_str.data();
    return return_str;
}
  1. I got an issue to release genfile ?? it seems that the runtime consider that I can't free an not allocated pointer but I use to do it using the line below:

    genfile = LIBMTP_new_file_t(); LIBMTP_destroy_file_t(genfile);

There is no precondition to do it. when genfile happens, destroy happened. Some data are allocated on the genfile.

  1. I'm able now to open the file for PTP stat complain that I can not send object

Any idea ?

1
The pointer returned by QByteArray(filename_stripped).data(); becomes invalid immediately, so your program is undefined. Use a variable, not a temporary object.molbdnilo
I have made some change. but why it became invalid ?Seb
It becomes invalid because the QByteArray object that owns the data it points to is destroyed before you assign the pointer to anything.molbdnilo

1 Answers

2
votes

The problem lies in the convertQStr2char() method. The latin_str object is created on the stack and will be destroyed at the end of the enclosing code block. This object is responsible for management of its internal data.

When you call char *return_str = latin_str.data();, you only copy the pointer to latin_str's internal data. As your method returns, latin_str is destroyed and the memory pointed to by data() is freed, so your returned pointer now points to a freed memory as well.

LIBMTP_destroy_file_t is documented to deallocate memory used by the structure, including any strings. In particular, when you call it, it also tries to free the memory pointed to by FileNameOnly, but - as I explained above - the memory has been already freed by QByteArray's destructor, hence the error.

Since using freed pointer results in an undefined behavior, this may be also the cause of your second issue.