MtpStorage* MtpServer::getStorage(MtpStorageID id) { if (id == 0) return mStorages[0]; for (int i = 0; i < mStorages.size(); i++) { MtpStorage* storage = mStorages[i]; if (storage->getStorageID() == id) return storage; } return NULL; }
MtpStorage* MtpServer::getStorage(MtpStorageID id) { MTPD("getStorage\n"); if (id == 0) { MTPD("mStorages\n"); return mStorages[0]; } for (size_t i = 0; i < mStorages.size(); i++) { MtpStorage* storage = mStorages[i]; MTPD("id: %d\n", id); MTPD("storage: %d\n", storage->getStorageID()); if (storage->getStorageID() == id) { return storage; } } return NULL; }
MtpResponseCode MtpServer::doGetStorageInfo() { MtpStringBuffer string; if (!mSessionOpen) return MTP_RESPONSE_SESSION_NOT_OPEN; MtpStorageID id = mRequest.getParameter(1); MtpStorage* storage = getStorage(id); if (!storage) return MTP_RESPONSE_INVALID_STORAGE_ID; mData.putUInt16(storage->getType()); mData.putUInt16(storage->getFileSystemType()); mData.putUInt16(storage->getAccessCapability()); mData.putUInt64(storage->getMaxCapacity()); mData.putUInt64(storage->getFreeSpace()); mData.putUInt32(1024*1024*1024); // Free Space in Objects string.set(storage->getDescription()); mData.putString(string); mData.putEmptyString(); // Volume Identifier return MTP_RESPONSE_OK; }
MtpResponseCode MtpServer::doSendObjectInfo() { MtpString path; MtpStorageID storageID = mRequest.getParameter(1); MtpStorage* storage = getStorage(storageID); MtpObjectHandle parent = mRequest.getParameter(2); if (!storage) return MTP_RESPONSE_INVALID_STORAGE_ID; // special case the root if (parent == MTP_PARENT_ROOT) { path = storage->getPath(); parent = 0; } else { int64_t length; MtpObjectFormat format; int result = mDatabase->getObjectFilePath(parent, path, length, format); if (result != MTP_RESPONSE_OK) return result; if (format != MTP_FORMAT_ASSOCIATION) return MTP_RESPONSE_INVALID_PARENT_OBJECT; } // read only the fields we need mData.getUInt32(); // storage ID MtpObjectFormat format = mData.getUInt16(); mData.getUInt16(); // protection status mSendObjectFileSize = mData.getUInt32(); mData.getUInt16(); // thumb format mData.getUInt32(); // thumb compressed size mData.getUInt32(); // thumb pix width mData.getUInt32(); // thumb pix height mData.getUInt32(); // image pix width mData.getUInt32(); // image pix height mData.getUInt32(); // image bit depth mData.getUInt32(); // parent uint16_t associationType = mData.getUInt16(); uint32_t associationDesc = mData.getUInt32(); // association desc mData.getUInt32(); // sequence number MtpStringBuffer name, created, modified; mData.getString(name); // file name mData.getString(created); // date created mData.getString(modified); // date modified // keywords follow LOGV("name: %s format: %04X\n", (const char *)name, format); time_t modifiedTime; if (!parseDateTime(modified, modifiedTime)) modifiedTime = 0; if (path[path.size() - 1] != '/') path += "/"; path += (const char *)name; // check space first if (mSendObjectFileSize > storage->getFreeSpace()) return MTP_RESPONSE_STORAGE_FULL; uint64_t maxFileSize = storage->getMaxFileSize(); // check storage max file size if (maxFileSize != 0) { // if mSendObjectFileSize is 0xFFFFFFFF, then all we know is the file size // is >= 0xFFFFFFFF if (mSendObjectFileSize > maxFileSize || mSendObjectFileSize == 0xFFFFFFFF) return MTP_RESPONSE_OBJECT_TOO_LARGE; } LOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID); MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path, format, parent, storageID, mSendObjectFileSize, modifiedTime); if (handle == kInvalidObjectHandle) { return MTP_RESPONSE_GENERAL_ERROR; } if (format == MTP_FORMAT_ASSOCIATION) { mode_t mask = umask(0); int ret = mkdir((const char *)path, mDirectoryPermission); umask(mask); if (ret && ret != -EEXIST) return MTP_RESPONSE_GENERAL_ERROR; chown((const char *)path, getuid(), mFileGroup); // SendObject does not get sent for directories, so call endSendObject here instead mDatabase->endSendObject(path, handle, MTP_FORMAT_ASSOCIATION, MTP_RESPONSE_OK); } else { mSendObjectFilePath = path; // save the handle for the SendObject call, which should follow mSendObjectHandle = handle; mSendObjectFormat = format; } mResponse.setParameter(1, storageID); mResponse.setParameter(2, parent); mResponse.setParameter(3, handle); return MTP_RESPONSE_OK; }