Example #1
0
static int ptpfs_release(struct inode *ino, struct file *filp)
{
    //printk(KERN_INFO "%s    object:%X    dcount: %d\n",  __FUNCTION__,ino->i_ino, filp->f_dentry->d_count);
    struct ptp_data_buffer *data=(struct ptp_data_buffer*)filp->private_data;
    if (data)
    {
        switch (filp->f_flags & O_ACCMODE)
        {
        case O_RDWR:
        case O_WRONLY:
            {
                struct ptp_object_info object;
                memset(&object,0,sizeof(object));
                if (ptp_getobjectinfo(PTPFSSB(ino->i_sb),ino->i_ino,&object)!=PTP_RC_OK)
                {
                    ptp_free_data_buffer(data);
                    kfree(data);
                    return -EPERM;
                }

                ptp_deleteobject(PTPFSSB(ino->i_sb),ino->i_ino,0);
                int count = 0;
                int x;
                for (x = 0; x < data->num_blocks; x++)
                {
                    count += data->blocks[x].block_size;
                }


                int storage = object.storage_id;
                int parent = object.parent_object;
                int handle = ino->i_ino;
                object.object_compressed_size=count;
                int ret = ptp_sendobjectinfo(PTPFSSB(ino->i_sb), &storage, &parent, &handle, &object);
                ret = ptp_sendobject(PTPFSSB(ino->i_sb),data,count);

                ino->i_size = count;
                ino->i_mtime = CURRENT_TIME;
                ptpfs_free_inode_data(ino);//uncache
                ptpfs_free_inode_data(PTPFSINO(ino) -> parent);//uncache

                //the inode number will change.  Kill this inode so next dir lookup will create a new one
                dput(filp->f_dentry);
                //iput(ino);
            }
            break;
        }

        ptp_free_data_buffer(data);
        kfree(data);
    }
    return 0;
}
Example #2
0
static int ptpfs_mkdir(struct inode *ino,struct dentry *d,int i)
{
    //printk(KERN_INFO "%s   %s %d\n",__FUNCTION__,d->d_name.name,i);
    __u32 storage;
    __u32 parent;
    __u32 handle;
    struct ptp_object_info objectinfo;
    memset(&objectinfo,0,sizeof(objectinfo));

    storage = PTPFSINO(ino)->storage;
    if (PTPFSINO(ino)->type == INO_TYPE_STGDIR)
    {
        parent = 0xffffffff;
    }
    else
    {
        parent = ino->i_ino;
    }

    objectinfo.filename = (unsigned char *)d->d_name.name;
    objectinfo.object_format=PTP_OFC_Association;
    objectinfo.association_type = PTP_AT_GenericFolder;

    int ret = ptp_sendobjectinfo(PTPFSSB(ino->i_sb), &storage, &parent, &handle, &objectinfo);
    /*
    if (ret == PTP_RC_OK)
    {

        struct ptp_data_buffer data;
        memset(&data,0,sizeof(data));
        ret = ptp_sendobject(PTPFSSB(ino->i_sb),&data,0);
    }
    */


    objectinfo.filename = NULL;
    ptp_free_object_info(&objectinfo);

    if (ret == PTP_RC_OK)
    {
        ptpfs_free_inode_data(ino);//uncache
        ino->i_version++;

        return 0;
    }
    return -EPERM;
}
Example #3
0
static int ptpfs_create(struct inode *dir,struct dentry *d,int i) 
{
    //printk(KERN_INFO "%s   %s %d\n",__FUNCTION__,d->d_name.name,i);
    __u32 storage;
    __u32 parent;
    __u32 handle;
    struct ptp_object_info objectinfo;
    memset(&objectinfo,0,sizeof(objectinfo));

    storage = PTPFSINO(dir)->storage;
    if (PTPFSINO(dir)->type == INO_TYPE_STGDIR)
    {
        parent = 0xffffffff;
    }
    else
    {
        parent = dir->i_ino;
    }

    objectinfo.filename = (unsigned char *)d->d_name.name;
    objectinfo.object_format=get_format((unsigned char *)d->d_name.name,d->d_name.len);
    objectinfo.object_compressed_size=0;

    int ret = ptp_sendobjectinfo(PTPFSSB(dir->i_sb), &storage, &parent, &handle, &objectinfo);

    if (ret == PTP_RC_OK)
    {
        struct ptp_data_buffer data;
        struct ptp_block block;
        unsigned char buf[10];

        memset(&data,0,sizeof(data));
        memset(&block,0,sizeof(block));
        data.blocks=&block;
        data.num_blocks = 1;
        block.block_size = 0;
        block.block = buf;

        ret = ptp_sendobject(PTPFSSB(dir->i_sb),&data,0);


        if (handle == 0)
        {
            //problem - it didn't return the right handle - need to do something find it
            struct ptp_object_handles objects;
            objects.n = 0;
            objects.handles = NULL;

            ptpfs_get_dir_data(dir);
            if (PTPFSINO(dir)->type == INO_TYPE_DIR)
            {
                ptp_getobjecthandles(PTPFSSB(dir->i_sb), PTPFSINO(dir)->storage, 0x000000, dir->i_ino,&objects);
            }
            else
            {
                ptp_getobjecthandles(PTPFSSB(dir->i_sb), dir->i_ino, 0x000000, 0xffffffff ,&objects);
            }

            int x,y;
            for (x = 0; x < objects.n && !handle; x++ )
            {
                for (y = 0; y < PTPFSINO(dir)->data.dircache.num_files; y++)
                {
                    if (PTPFSINO(dir)->data.dircache.file_info[y].handle == objects.handles[x])
                    {
                        objects.handles[x] = 0;
                        y = PTPFSINO(dir)->data.dircache.num_files;
                    }
                }
                if (objects.handles[x])
                {
                    handle = objects.handles[x]; 
                }
            }
            ptp_free_object_handles(&objects);
        }


        int mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH | S_IFREG;
        struct inode *newi = ptpfs_get_inode(dir->i_sb, mode  , 0,handle);
        PTPFSINO(newi)->parent = dir;
        ptpfs_set_inode_info(newi,&objectinfo);
        atomic_inc(&newi->i_count);    /* New dentry reference */
        d_instantiate(d, newi);

        objectinfo.filename = NULL;
        ptp_free_object_info(&objectinfo);

        ptpfs_free_inode_data(dir);//uncache
        dir->i_version++;
        newi->i_mtime = CURRENT_TIME;
        return 0;
    }
    objectinfo.filename = NULL;
    ptp_free_object_info(&objectinfo);
    return -EPERM;


}
Example #4
0
/**
 * Sends a MTP object to the device.
 * 
 * @param device a pointer to the device.
 * @param p_parenthandle a pointer to the parent handle.
 * @param p_handle a pointer to the handle.
 * @param meta the metadata to describe the object.
 * @param data the object data to send.
 */
void VitaMTP_SendObject(LIBMTP_mtpdevice_t *device, uint32_t* p_parenthandle, uint32_t* p_handle, metadata_t* meta, unsigned char* data){
    uint32_t sendhandle = *p_parenthandle;
    uint32_t store = 0x00010001; // TODO: What is this number? Does it change?
    uint32_t handle = *p_handle;
    uint32_t parenthandle = *p_parenthandle;
    MTPProperties* props = NULL;
    int nProps = 0;
    PTPObjectInfo objectinfo;
    memset(&objectinfo, 0x0, sizeof(PTPObjectInfo));
    
    if(meta->dataType == SaveData){
        objectinfo.ObjectFormat = PTP_OFC_Association; // 0x3001
        objectinfo.ThumbFormat = PTP_OFC_Undefined; // 0x3000
        objectinfo.Filename = meta->data.saveData.dirName;
        ptp_sendobjectinfo((PTPParams*)device->params, &store, &parenthandle, &handle, &objectinfo);
        sendhandle = handle;
        
        // Totaly useless and unused, but official CMA does that
        VitaMTP_GetObjectPropList(device, handle, &props, &nProps);
        free(props);
    }else if(meta->dataType == File){
        parenthandle = sendhandle;
        objectinfo.ObjectFormat = PTP_OFC_PSPSave; // 0xB00A
        objectinfo.ObjectCompressedSize = (uint32_t)meta->size;
        objectinfo.CaptureDate = meta->dateTimeCreated;
        objectinfo.ModificationDate = meta->dateTimeCreated;
        objectinfo.Filename = meta->data.file.name;
        ptp_sendobjectinfo((PTPParams*)device->params, &store, &parenthandle, &handle, &objectinfo);
        
        ptp_sendobject((PTPParams*)device->params, data, meta->size);
        
        MTPProperties prop;
        prop.property = PTP_OPC_Name; // 0xDC44
        prop.datatype = PTP_DTC_STR; // 0xFFFF
        prop.ObjectHandle = handle;
        prop.propval.str = meta->title;
        ptp_mtp_setobjectproplist((PTPParams*)device->params, &prop, 1);
        
        // Totaly useless and unused, but official CMA does that
        VitaMTP_GetObjectPropList(device, handle, &props, &nProps);
        free(props);
    }else if(meta->dataType == Folder){
        parenthandle = sendhandle;
        objectinfo.ObjectFormat = PTP_OFC_Association; // 0x3001
        objectinfo.ObjectCompressedSize = 0;
        objectinfo.CaptureDate = meta->dateTimeCreated;
        objectinfo.ModificationDate = meta->dateTimeCreated;
        objectinfo.Filename = meta->data.folder.name;
        ptp_sendobjectinfo((PTPParams*)device->params, &store, &parenthandle, &handle, &objectinfo);
        
        MTPProperties prop;
        prop.property = PTP_OPC_Name; // 0xDC44
        prop.datatype = PTP_DTC_STR; // 0xFFFF
        prop.ObjectHandle = handle;
        prop.propval.str = meta->data.folder.name;
        ptp_mtp_setobjectproplist((PTPParams*)device->params, &prop, 1);
        
        // Totaly useless and unused, but official CMA does that
        VitaMTP_GetObjectPropList(device, handle, &props, &nProps);
        free(props);
    }
    *p_handle = handle;
    *p_parenthandle = parenthandle;
}