diff options
Diffstat (limited to 'media/mtp')
-rw-r--r-- | media/mtp/MtpProperty.cpp | 13 | ||||
-rw-r--r-- | media/mtp/MtpServer.cpp | 80 | ||||
-rw-r--r-- | media/mtp/MtpServer.h | 1 | ||||
-rw-r--r-- | media/mtp/MtpStorageInfo.cpp | 4 |
4 files changed, 67 insertions, 31 deletions
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp index 375ed9a..c500901 100644 --- a/media/mtp/MtpProperty.cpp +++ b/media/mtp/MtpProperty.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "MtpProperty" #include <inttypes.h> +#include <cutils/compiler.h> #include "MtpDataPacket.h" #include "MtpDebug.h" #include "MtpProperty.h" @@ -190,9 +191,9 @@ void MtpProperty::write(MtpDataPacket& packet) { if (deviceProp) writeValue(packet, mCurrentValue); } - packet.putUInt32(mGroupCode); if (!deviceProp) - packet.putUInt8(mFormFlag); + packet.putUInt32(mGroupCode); + packet.putUInt8(mFormFlag); if (mFormFlag == kFormRange) { writeValue(packet, mMinimumValue); writeValue(packet, mMaximumValue); @@ -518,8 +519,14 @@ void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { length = packet.getUInt32(); - if (length == 0) + // Fail if resulting array is over 2GB. This is because the maximum array + // size may be less than SIZE_MAX on some platforms. + if ( CC_UNLIKELY( + length == 0 || + length >= INT32_MAX / sizeof(MtpPropertyValue)) ) { + length = 0; return NULL; + } MtpPropertyValue* result = new MtpPropertyValue[length]; for (int i = 0; i < length; i++) readValue(packet, result[i]); diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 155f645..aa43967 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -94,6 +94,7 @@ static const MtpEventCode kSupportedEventCodes[] = { MTP_EVENT_OBJECT_REMOVED, MTP_EVENT_STORE_ADDED, MTP_EVENT_STORE_REMOVED, + MTP_EVENT_DEVICE_PROP_CHANGED, }; MtpServer::MtpServer(int fd, MtpDatabase* database, bool ptp, @@ -262,6 +263,11 @@ void MtpServer::sendStoreRemoved(MtpStorageID id) { sendEvent(MTP_EVENT_STORE_REMOVED, id); } +void MtpServer::sendDevicePropertyChanged(MtpDeviceProperty property) { + ALOGV("sendDevicePropertyChanged %d\n", property); + sendEvent(MTP_EVENT_DEVICE_PROP_CHANGED, property); +} + void MtpServer::sendEvent(MtpEventCode code, uint32_t param1) { if (mSessionOpen) { mEvent.setEventCode(code); @@ -319,6 +325,14 @@ bool MtpServer::handleRequest() { mSendObjectHandle = kInvalidObjectHandle; } + int containertype = mRequest.getContainerType(); + if (containertype != MTP_CONTAINER_TYPE_COMMAND) { + ALOGE("wrong container type %d", containertype); + return false; + } + + ALOGV("got command %s (%x)", MtpDebug::getOperationCodeName(operation), operation); + switch (operation) { case MTP_OPERATION_GET_DEVICE_INFO: response = doGetDeviceInfo(); @@ -409,7 +423,8 @@ bool MtpServer::handleRequest() { response = doEndEditObject(); break; default: - ALOGE("got unsupported command %s", MtpDebug::getOperationCodeName(operation)); + ALOGE("got unsupported command %s (%x)", + MtpDebug::getOperationCodeName(operation), operation); response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED; break; } @@ -787,7 +802,7 @@ MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) { int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format); if (result != MTP_RESPONSE_OK) return result; - if (offset + length > fileLength) + if (offset + length > (uint64_t)fileLength) length = fileLength - offset; const char* filePath = (const char *)pathBuf; @@ -944,22 +959,28 @@ MtpResponseCode MtpServer::doSendObject() { fchmod(mfr.fd, mFilePermission); umask(mask); - if (initialData > 0) + if (initialData > 0) { ret = write(mfr.fd, mData.getData(), initialData); + } - if (mSendObjectFileSize - initialData > 0) { - mfr.offset = initialData; - if (mSendObjectFileSize == 0xFFFFFFFF) { - // tell driver to read until it receives a short packet - mfr.length = 0xFFFFFFFF; - } else { - mfr.length = mSendObjectFileSize - initialData; - } + if (ret < 0) { + ALOGE("failed to write initial data"); + result = MTP_RESPONSE_GENERAL_ERROR; + } else { + if (mSendObjectFileSize - initialData > 0) { + mfr.offset = initialData; + if (mSendObjectFileSize == 0xFFFFFFFF) { + // tell driver to read until it receives a short packet + mfr.length = 0xFFFFFFFF; + } else { + mfr.length = mSendObjectFileSize - initialData; + } - ALOGV("receiving %s\n", (const char *)mSendObjectFilePath); - // transfer the file - ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); - ALOGV("MTP_RECEIVE_FILE returned %d\n", ret); + ALOGV("receiving %s\n", (const char *)mSendObjectFilePath); + // transfer the file + ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); + ALOGV("MTP_RECEIVE_FILE returned %d\n", ret); + } } close(mfr.fd); @@ -984,7 +1005,7 @@ done: static void deleteRecursive(const char* path) { char pathbuf[PATH_MAX]; - int pathLength = strlen(path); + size_t pathLength = strlen(path); if (pathLength >= sizeof(pathbuf) - 1) { ALOGE("path too long: %s\n", path); } @@ -1106,12 +1127,13 @@ MtpResponseCode MtpServer::doSendPartialObject() { // can't start writing past the end of the file if (offset > edit->mSize) { - ALOGD("writing past end of object, offset: %lld, edit->mSize: %lld", offset, edit->mSize); + ALOGD("writing past end of object, offset: %" PRIu64 ", edit->mSize: %" PRIu64, + offset, edit->mSize); return MTP_RESPONSE_GENERAL_ERROR; } const char* filePath = (const char *)edit->mPath; - ALOGV("receiving partial %s %lld %" PRIu32 "\n", filePath, offset, length); + ALOGV("receiving partial %s %" PRIu64 " %" PRIu32, filePath, offset, length); // read the header, and possibly some data int ret = mData.read(mFD); @@ -1125,15 +1147,19 @@ MtpResponseCode MtpServer::doSendPartialObject() { length -= initialData; } - if (length > 0) { - mtp_file_range mfr; - mfr.fd = edit->mFD; - mfr.offset = offset; - mfr.length = length; - - // transfer the file - ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); - ALOGV("MTP_RECEIVE_FILE returned %d", ret); + if (ret < 0) { + ALOGE("failed to write initial data"); + } else { + if (length > 0) { + mtp_file_range mfr; + mfr.fd = edit->mFD; + mfr.offset = offset; + mfr.length = length; + + // transfer the file + ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); + ALOGV("MTP_RECEIVE_FILE returned %d", ret); + } } if (ret < 0) { mResponse.setParameter(1, 0); diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h index dfa8258..b3a11e0 100644 --- a/media/mtp/MtpServer.h +++ b/media/mtp/MtpServer.h @@ -104,6 +104,7 @@ public: void sendObjectAdded(MtpObjectHandle handle); void sendObjectRemoved(MtpObjectHandle handle); + void sendDevicePropertyChanged(MtpDeviceProperty property); private: void sendStoreAdded(MtpStorageID id); diff --git a/media/mtp/MtpStorageInfo.cpp b/media/mtp/MtpStorageInfo.cpp index dcd37cd..2b1a9ae 100644 --- a/media/mtp/MtpStorageInfo.cpp +++ b/media/mtp/MtpStorageInfo.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "MtpStorageInfo" +#include <inttypes.h> + #include "MtpDebug.h" #include "MtpDataPacket.h" #include "MtpStorageInfo.h" @@ -63,7 +65,7 @@ void MtpStorageInfo::read(MtpDataPacket& packet) { void MtpStorageInfo::print() { ALOGD("Storage Info %08X:\n\tmStorageType: %d\n\tmFileSystemType: %d\n\tmAccessCapability: %d\n", mStorageID, mStorageType, mFileSystemType, mAccessCapability); - ALOGD("\tmMaxCapacity: %lld\n\tmFreeSpaceBytes: %lld\n\tmFreeSpaceObjects: %d\n", + ALOGD("\tmMaxCapacity: %" PRIu64 "\n\tmFreeSpaceBytes: %" PRIu64 "\n\tmFreeSpaceObjects: %d\n", mMaxCapacity, mFreeSpaceBytes, mFreeSpaceObjects); ALOGD("\tmStorageDescription: %s\n\tmVolumeIdentifier: %s\n", mStorageDescription, mVolumeIdentifier); |