/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <dirent.h>
#include "../twcommon.h"
#include <cutils/properties.h>

#include "MtpTypes.h"
#include "MtpDebug.h"
#include "MtpDatabase.h"
#include "MtpObjectInfo.h"
#include "MtpProperty.h"
#include "MtpServer.h"
#include "MtpStorage.h"
#include "MtpStringBuffer.h"

#include <linux/usb/f_mtp.h>

static const MtpOperationCode kSupportedOperationCodes[] = {
	MTP_OPERATION_GET_DEVICE_INFO,
	MTP_OPERATION_OPEN_SESSION,
	MTP_OPERATION_CLOSE_SESSION,
	MTP_OPERATION_GET_STORAGE_IDS,
	MTP_OPERATION_GET_STORAGE_INFO,
	MTP_OPERATION_GET_NUM_OBJECTS,
	MTP_OPERATION_GET_OBJECT_HANDLES,
	MTP_OPERATION_GET_OBJECT_INFO,
	MTP_OPERATION_GET_OBJECT,
	MTP_OPERATION_GET_THUMB,
	MTP_OPERATION_DELETE_OBJECT,
	MTP_OPERATION_SEND_OBJECT_INFO,
	MTP_OPERATION_SEND_OBJECT,
//	MTP_OPERATION_INITIATE_CAPTURE,
//	MTP_OPERATION_FORMAT_STORE,
//	MTP_OPERATION_RESET_DEVICE,
//	MTP_OPERATION_SELF_TEST,
//	MTP_OPERATION_SET_OBJECT_PROTECTION,
//	MTP_OPERATION_POWER_DOWN,
	MTP_OPERATION_GET_DEVICE_PROP_DESC,
	MTP_OPERATION_GET_DEVICE_PROP_VALUE,
	MTP_OPERATION_SET_DEVICE_PROP_VALUE,
	MTP_OPERATION_RESET_DEVICE_PROP_VALUE,
//	MTP_OPERATION_TERMINATE_OPEN_CAPTURE,
//	MTP_OPERATION_MOVE_OBJECT,
//	MTP_OPERATION_COPY_OBJECT,
	MTP_OPERATION_GET_PARTIAL_OBJECT,
//	MTP_OPERATION_INITIATE_OPEN_CAPTURE,
	MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED,
	MTP_OPERATION_GET_OBJECT_PROP_DESC,
	MTP_OPERATION_GET_OBJECT_PROP_VALUE,
	MTP_OPERATION_SET_OBJECT_PROP_VALUE,
	MTP_OPERATION_GET_OBJECT_PROP_LIST,
//	MTP_OPERATION_SET_OBJECT_PROP_LIST,
//	MTP_OPERATION_GET_INTERDEPENDENT_PROP_DESC,
//	MTP_OPERATION_SEND_OBJECT_PROP_LIST,
	MTP_OPERATION_GET_OBJECT_REFERENCES,
	MTP_OPERATION_SET_OBJECT_REFERENCES,
//	MTP_OPERATION_SKIP,
	// Android extension for direct file IO
	MTP_OPERATION_GET_PARTIAL_OBJECT_64,
	MTP_OPERATION_SEND_PARTIAL_OBJECT,
	MTP_OPERATION_TRUNCATE_OBJECT,
	MTP_OPERATION_BEGIN_EDIT_OBJECT,
	MTP_OPERATION_END_EDIT_OBJECT,
};

static const MtpEventCode kSupportedEventCodes[] = {
	MTP_EVENT_OBJECT_ADDED,
	MTP_EVENT_OBJECT_REMOVED,
	MTP_EVENT_STORE_ADDED,
	MTP_EVENT_STORE_REMOVED,
	MTP_EVENT_OBJECT_PROP_CHANGED,
};

MtpServer::MtpServer(int fd, MtpDatabase* database, bool ptp,
					int fileGroup, int filePerm, int directoryPerm)
	:	mFD(fd),
		mDatabase(database),
		mPtp(ptp),
		mFileGroup(fileGroup),
		mFilePermission(filePerm),
		mDirectoryPermission(directoryPerm),
		mSessionID(0),
		mSessionOpen(false),
		mSendObjectHandle(kInvalidObjectHandle),
		mSendObjectFormat(0),
		mSendObjectFileSize(0)
{
}

MtpServer::~MtpServer() {
}

void MtpServer::addStorage(MtpStorage* storage) {
	MTPD("addStorage(): storage: %x\n", storage);
	mDatabase->createDB(storage, storage->getStorageID());
	android::Mutex::Autolock autoLock(mMutex);
	mStorages.push(storage);
	sendStoreAdded(storage->getStorageID());
}

void MtpServer::removeStorage(MtpStorage* storage) {
	android::Mutex::Autolock autoLock(mMutex);

	for (size_t i = 0; i < mStorages.size(); i++) {
		if (mStorages[i] == storage) {
			mStorages.removeAt(i);
			sendStoreRemoved(storage->getStorageID());
			break;
		}
	}
}

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;
}

bool MtpServer::hasStorage(MtpStorageID id) {
	MTPD("in hasStorage\n");
	if (id == 0 || id == 0xFFFFFFFF)
		return mStorages.size() > 0;
	return (getStorage(id) != NULL);
}

void MtpServer::run() {
	int fd = mFD;

	MTPI("MtpServer::run fd: %d\n", fd);

	while (1) {
		MTPD("About to read device...\n");
		int ret = mRequest.read(fd);
		if (ret < 0) {
			MTPD("request read returned %d, errno: %d", ret, errno);
			if (errno == ECANCELED) {
				// return to top of loop and wait for next command
				continue;
			}
			break;
		}
		MtpOperationCode operation = mRequest.getOperationCode();
		MtpTransactionID transaction = mRequest.getTransactionID();

		MTPD("operation: %s", MtpDebug::getOperationCodeName(operation));
		mRequest.dump();

		// FIXME need to generalize this
		bool dataIn = (operation == MTP_OPERATION_SEND_OBJECT_INFO
					|| operation == MTP_OPERATION_SET_OBJECT_REFERENCES
					|| operation == MTP_OPERATION_SET_OBJECT_PROP_VALUE
					|| operation == MTP_OPERATION_SET_DEVICE_PROP_VALUE);
		if (dataIn) {
			int ret = mData.read(fd);
			if (ret < 0) {
				MTPD("data read returned %d, errno: %d", ret, errno);
				if (errno == ECANCELED) {
					// return to top of loop and wait for next command
					continue;
				}
				break;
			}
			MTPD("received data:");
			mData.dump();
		} else {
			mData.reset();
		}

		if (handleRequest()) {
			if (!dataIn && mData.hasData()) {
				mData.setOperationCode(operation);
				mData.setTransactionID(transaction);
				MTPD("sending data:");
				mData.dump();
				ret = mData.write(fd);
				if (ret < 0) {
					MTPD("request write returned %d, errno: %d", ret, errno);
					if (errno == ECANCELED) {
						// return to top of loop and wait for next command
						continue;
					}
					break;
				}
			}

			mResponse.setTransactionID(transaction);
			MTPD("sending response %04X\n", mResponse.getResponseCode());
			ret = mResponse.write(fd);
			MTPD("ret: %d\n", ret);
			mResponse.dump();
			if (ret < 0) {
				MTPD("request write returned %d, errno: %d", ret, errno);
				if (errno == ECANCELED) {
					// return to top of loop and wait for next command
					continue;
				}
				break;
			}
		} else {
			MTPD("skipping response\n");
		}
	}

	// commit any open edits
	int count = mObjectEditList.size();
	for (int i = 0; i < count; i++) {
		ObjectEdit* edit = mObjectEditList[i];
		commitEdit(edit);
		delete edit;
	}
	mObjectEditList.clear();

	if (mSessionOpen)
		mDatabase->sessionEnded();
	close(fd);
	mFD = -1;
}

void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
	MTPD("sendObjectAdded %d\n", handle);
	sendEvent(MTP_EVENT_OBJECT_ADDED, handle);
}

void MtpServer::sendObjectRemoved(MtpObjectHandle handle) {
	MTPD("sendObjectRemoved %d\n", handle);
	sendEvent(MTP_EVENT_OBJECT_REMOVED, handle);
}

void MtpServer::sendObjectUpdated(MtpObjectHandle handle) {
	MTPD("sendObjectUpdated %d\n", handle);
	sendEvent(MTP_EVENT_OBJECT_PROP_CHANGED, handle);
}

void MtpServer::sendStoreAdded(MtpStorageID id) {
	MTPD("sendStoreAdded %08X\n", id);
	sendEvent(MTP_EVENT_STORE_ADDED, id);
}

void MtpServer::sendStoreRemoved(MtpStorageID id) {
	MTPD("sendStoreRemoved %08X\n", id);
	sendEvent(MTP_EVENT_STORE_REMOVED, id);
}

void MtpServer::sendEvent(MtpEventCode code, uint32_t param1) {
	MTPD("MtpServer::sendEvent sending event code: %x\n", code);
	if (mSessionOpen) {
		mEvent.setEventCode(code);
		mEvent.setTransactionID(mRequest.getTransactionID());
		mEvent.setParameter(1, param1);
		int ret = mEvent.write(mFD);
		MTPD("mEvent.write returned %d\n", ret);
	}
}

void MtpServer::addEditObject(MtpObjectHandle handle, MtpString& path,
		uint64_t size, MtpObjectFormat format, int fd) {
	ObjectEdit*  edit = new ObjectEdit(handle, path, size, format, fd);
	mObjectEditList.add(edit);
}

MtpServer::ObjectEdit* MtpServer::getEditObject(MtpObjectHandle handle) {
	int count = mObjectEditList.size();
	for (int i = 0; i < count; i++) {
		ObjectEdit* edit = mObjectEditList[i];
		if (edit->mHandle == handle) return edit;
	}
	return NULL;
}

void MtpServer::removeEditObject(MtpObjectHandle handle) {
	int count = mObjectEditList.size();
	for (int i = 0; i < count; i++) {
		ObjectEdit* edit = mObjectEditList[i];
		if (edit->mHandle == handle) {
			delete edit;
			mObjectEditList.removeAt(i);
			return;
		}
	}
	MTPE("ObjectEdit not found in removeEditObject");
}

void MtpServer::commitEdit(ObjectEdit* edit) {
	mDatabase->endSendObject((const char *)edit->mPath, edit->mHandle, edit->mFormat, true);
}


bool MtpServer::handleRequest() {
	android::Mutex::Autolock autoLock(mMutex);

	MtpOperationCode operation = mRequest.getOperationCode();
	MtpResponseCode response;

	mResponse.reset();

	if (mSendObjectHandle != kInvalidObjectHandle && operation != MTP_OPERATION_SEND_OBJECT) {
		// FIXME - need to delete mSendObjectHandle from the database
		MTPE("expected SendObject after SendObjectInfo");
		mSendObjectHandle = kInvalidObjectHandle;
	}

	switch (operation) {
		case MTP_OPERATION_GET_DEVICE_INFO:
				MTPD("doGetDeviceInfo()\n");
				response = doGetDeviceInfo();
				break;
			case MTP_OPERATION_OPEN_SESSION:
				MTPD("doOpenSesion()\n");
				response = doOpenSession();
				break;
			case MTP_OPERATION_CLOSE_SESSION:
				MTPD("doCloseSession()\n");
				response = doCloseSession();
				break;
			case MTP_OPERATION_GET_STORAGE_IDS:
				MTPD("doGetStorageIDs()\n");
				response = doGetStorageIDs();
				break;
		 	 case MTP_OPERATION_GET_STORAGE_INFO:
				MTPD("about to call doGetStorageInfo()\n");
				response = doGetStorageInfo();
				break;
			case MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED:
				MTPD("about to call doGetObjectPropsSupported()\n");
				response = doGetObjectPropsSupported();
				break;
			case MTP_OPERATION_GET_OBJECT_HANDLES:
				MTPD("about to call doGetObjectHandles()\n");
				response = doGetObjectHandles();
				break;
			case MTP_OPERATION_GET_NUM_OBJECTS:
				MTPD("about to call doGetNumbObjects()\n");
				response = doGetNumObjects();
				break;
			case MTP_OPERATION_GET_OBJECT_REFERENCES:
				MTPD("about to call doGetObjectReferences()\n");
				response = doGetObjectReferences();
				break;
			case MTP_OPERATION_SET_OBJECT_REFERENCES:
				MTPD("about to call doSetObjectReferences()\n");
				response = doSetObjectReferences();
				break;
			case MTP_OPERATION_GET_OBJECT_PROP_VALUE:
				MTPD("about to call doGetObjectPropValue()\n");
				response = doGetObjectPropValue();
				break;
			case MTP_OPERATION_SET_OBJECT_PROP_VALUE:
				MTPD("about to call doSetObjectPropValue()\n");
				response = doSetObjectPropValue();
				break;
			case MTP_OPERATION_GET_DEVICE_PROP_VALUE:
				MTPD("about to call doGetDevicPropValue()\n");
				response = doGetDevicePropValue();
				break;
			case MTP_OPERATION_SET_DEVICE_PROP_VALUE:
				MTPD("about to call doSetDevicePropVaue()\n");
				response = doSetDevicePropValue();
				break;
			case MTP_OPERATION_RESET_DEVICE_PROP_VALUE:
				MTPD("about to call doResetDevicePropValue()\n");
				response = doResetDevicePropValue();
				break;
			case MTP_OPERATION_GET_OBJECT_PROP_LIST:
				MTPD("calling doGetObjectPropList()\n");
				response = doGetObjectPropList();
				break;
			case MTP_OPERATION_GET_OBJECT_INFO:
				MTPD("calling doGetObjectInfo()\n");
				response = doGetObjectInfo();
				break;
			case MTP_OPERATION_GET_OBJECT:
				MTPD("about to call doGetObject()\n");
				response = doGetObject();
				break;
			case MTP_OPERATION_GET_THUMB:
				response = doGetThumb();
				break;
			case MTP_OPERATION_GET_PARTIAL_OBJECT:
			case MTP_OPERATION_GET_PARTIAL_OBJECT_64:
				response = doGetPartialObject(operation);
				break;
			case MTP_OPERATION_SEND_OBJECT_INFO:
				MTPD("about to call doSendObjectInfo()\n");
				response = doSendObjectInfo();
				break;
			case MTP_OPERATION_SEND_OBJECT:
				MTPD("about to call doSendObject()\n");
				response = doSendObject();
				break;
			case MTP_OPERATION_DELETE_OBJECT:
				response = doDeleteObject();
				break;
			case MTP_OPERATION_GET_OBJECT_PROP_DESC:
				MTPD("about to call doGetObjectPropDesc()\n");
				response = doGetObjectPropDesc();
				break;
			case MTP_OPERATION_GET_DEVICE_PROP_DESC:
				MTPD("about to call doGetDevicePropDesc()\n");
				response = doGetDevicePropDesc();
				break;
			case MTP_OPERATION_SEND_PARTIAL_OBJECT:
				response = doSendPartialObject();
				break;
			case MTP_OPERATION_TRUNCATE_OBJECT:
				response = doTruncateObject();
				break;
			case MTP_OPERATION_BEGIN_EDIT_OBJECT:
				response = doBeginEditObject();
				break;
			case MTP_OPERATION_END_EDIT_OBJECT:
				response = doEndEditObject();
				break;
			default:
				MTPE("got unsupported command %s", MtpDebug::getOperationCodeName(operation));
				response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
				break;
		}

		if (response == MTP_RESPONSE_TRANSACTION_CANCELLED)
			return false;
		mResponse.setResponseCode(response);
		return true;
}

MtpResponseCode MtpServer::doGetDeviceInfo() {
	MtpStringBuffer   string;
	char prop_value[PROPERTY_VALUE_MAX];

	MtpObjectFormatList* playbackFormats = mDatabase->getSupportedPlaybackFormats();
	MtpObjectFormatList* captureFormats = mDatabase->getSupportedCaptureFormats();
	MtpDevicePropertyList* deviceProperties = mDatabase->getSupportedDeviceProperties();

	// fill in device info
	mData.putUInt16(MTP_STANDARD_VERSION);
	if (mPtp) {
		MTPD("doGetDeviceInfo putting 0\n");
		mData.putUInt32(0);
	} else {
		// MTP Vendor Extension ID
		MTPD("doGetDeviceInfo putting 6\n");
		mData.putUInt32(6);
	}
	mData.putUInt16(MTP_STANDARD_VERSION);
	if (mPtp) {
		// no extensions
		MTPD("doGetDeviceInfo no extensions\n");
		string.set("");
	} else {
		// MTP extensions
		MTPD("doGetDeviceInfo microsoft.com: 1.0; android.com: 1.0;\n");
		string.set("microsoft.com: 1.0; android.com: 1.0;");
	}
	mData.putString(string); // MTP Extensions
	mData.putUInt16(0); //Functional Mode
	MTPD("doGetDeviceInfo opcodes, %i\n", sizeof(kSupportedOperationCodes) / sizeof(uint16_t));
	MTPD("doGetDeviceInfo eventcodes, %i\n", sizeof(kSupportedEventCodes) / sizeof(uint16_t));
	mData.putAUInt16(kSupportedOperationCodes,
			sizeof(kSupportedOperationCodes) / sizeof(uint16_t)); // Operations Supported
	mData.putAUInt16(kSupportedEventCodes,
			sizeof(kSupportedEventCodes) / sizeof(uint16_t)); // Events Supported
	mData.putAUInt16(deviceProperties); // Device Properties Supported
	mData.putAUInt16(captureFormats); // Capture Formats
	mData.putAUInt16(playbackFormats);  // Playback Formats

	property_get("ro.product.manufacturer", prop_value, "unknown manufacturer");
	MTPD("prop: %s\n", prop_value);
	string.set(prop_value);
	mData.putString(string);   // Manufacturer

	property_get("ro.product.model", prop_value, "MTP Device");
	string.set(prop_value);
	mData.putString(string);   // Model
	string.set("1.0");
	mData.putString(string);   // Device Version

	property_get("ro.serialno", prop_value, "????????");
	MTPD("sn: %s\n", prop_value);
	string.set(prop_value);
	mData.putString(string);   // Serial Number

	delete playbackFormats;
	delete captureFormats;
	delete deviceProperties;

	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doOpenSession() {
	if (mSessionOpen) {
		mResponse.setParameter(1, mSessionID);
		return MTP_RESPONSE_SESSION_ALREADY_OPEN;
	}
	mSessionID = mRequest.getParameter(1);
	mSessionOpen = true;

	mDatabase->sessionStarted();

	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doCloseSession() {
	if (!mSessionOpen)
		return MTP_RESPONSE_SESSION_NOT_OPEN;
	mSessionID = 0;
	mSessionOpen = false;
	mDatabase->sessionEnded();
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doGetStorageIDs() {
	MTPD("doGetStorageIDs()\n");
	if (!mSessionOpen)
		return MTP_RESPONSE_SESSION_NOT_OPEN;
	int count = mStorages.size();
	mData.putUInt32(count);
	for (int i = 0; i < count; i++) {
		MTPD("getting storageid %d\n", mStorages[i]->getStorageID());
		mData.putUInt32(mStorages[i]->getStorageID());
	}

	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doGetStorageInfo() {
	MtpStringBuffer   string;
	MTPD("doGetStorageInfo()\n");
	if (!mSessionOpen)
		return MTP_RESPONSE_SESSION_NOT_OPEN;
	MtpStorageID id = mRequest.getParameter(1);
	MtpStorage* storage = getStorage(id);
	if (!storage) {
		MTPE("invalid storage id\n");
		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::doGetObjectPropsSupported() {
	MTPD("doGetObjectPropsSupported()\n");
	if (!mSessionOpen)
		return MTP_RESPONSE_SESSION_NOT_OPEN;
	MtpObjectFormat format = mRequest.getParameter(1);
	mDatabase->lockMutex();
	MtpObjectPropertyList* properties = mDatabase->getSupportedObjectProperties(format);
	mData.putAUInt16(properties);
	delete properties;
	mDatabase->unlockMutex();
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doGetObjectHandles() {
	if (!mSessionOpen)
		return MTP_RESPONSE_SESSION_NOT_OPEN;
	MtpStorageID storageID = mRequest.getParameter(1);	  // 0xFFFFFFFF for all storage
	MtpObjectFormat format = mRequest.getParameter(2);	  // 0 for all formats
	MtpObjectHandle parent = mRequest.getParameter(3);	  // 0xFFFFFFFF for objects with no parent
															// 0x00000000 for all objects

	if (!hasStorage(storageID))
		return MTP_RESPONSE_INVALID_STORAGE_ID;

	MTPD("calling MtpDatabase->getObjectList()\n");
	mDatabase->lockMutex();
	MtpObjectHandleList* handles = mDatabase->getObjectList(storageID, format, parent);
	mData.putAUInt32(handles);
	delete handles;
	mDatabase->unlockMutex();
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doGetNumObjects() {
	if (!mSessionOpen)
		return MTP_RESPONSE_SESSION_NOT_OPEN;
	MtpStorageID storageID = mRequest.getParameter(1);	  // 0xFFFFFFFF for all storage
	MtpObjectFormat format = mRequest.getParameter(2);	  // 0 for all formats
	MtpObjectHandle parent = mRequest.getParameter(3);	  // 0xFFFFFFFF for objects with no parent
															// 0x00000000 for all objects
	if (!hasStorage(storageID))
		return MTP_RESPONSE_INVALID_STORAGE_ID;

	mDatabase->lockMutex();
	int count = mDatabase->getNumObjects(storageID, format, parent);
	mDatabase->unlockMutex();
	if (count >= 0) {
		mResponse.setParameter(1, count);
		return MTP_RESPONSE_OK;
	} else {
		mResponse.setParameter(1, 0);
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	}
}

MtpResponseCode MtpServer::doGetObjectReferences() {
	if (!mSessionOpen)
		return MTP_RESPONSE_SESSION_NOT_OPEN;
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpObjectHandle handle = mRequest.getParameter(1);

	// FIXME - check for invalid object handle
	mDatabase->lockMutex();
	MtpObjectHandleList* handles = mDatabase->getObjectReferences(handle);
	if (handles) {
		mData.putAUInt32(handles);
		delete handles;
	} else {
		MTPD("MtpServer::doGetObjectReferences putEmptyArray\n");
		mData.putEmptyArray();
	}
	mDatabase->unlockMutex();
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doSetObjectReferences() {
	if (!mSessionOpen)
		return MTP_RESPONSE_SESSION_NOT_OPEN;
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpStorageID handle = mRequest.getParameter(1);

	MtpObjectHandleList* references = mData.getAUInt32();
	mDatabase->lockMutex();
	MtpResponseCode result = mDatabase->setObjectReferences(handle, references);
	mDatabase->unlockMutex();
	delete references;
	return result;
}

MtpResponseCode MtpServer::doGetObjectPropValue() {
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpObjectHandle handle = mRequest.getParameter(1);
	MtpObjectProperty property = mRequest.getParameter(2);
	MTPD("GetObjectPropValue %d %s\n", handle,
			MtpDebug::getObjectPropCodeName(property));

	mDatabase->lockMutex();
	MtpResponseCode res = mDatabase->getObjectPropertyValue(handle, property, mData);
	mDatabase->unlockMutex();
	return res;
}

MtpResponseCode MtpServer::doSetObjectPropValue() {
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpObjectHandle handle = mRequest.getParameter(1);
	MtpObjectProperty property = mRequest.getParameter(2);
	MTPD("SetObjectPropValue %d %s\n", handle,
			MtpDebug::getObjectPropCodeName(property));

	mDatabase->lockMutex();
	MtpResponseCode res = mDatabase->setObjectPropertyValue(handle, property, mData);
	mDatabase->unlockMutex();
	return res;
}

MtpResponseCode MtpServer::doGetDevicePropValue() {
	MtpDeviceProperty property = mRequest.getParameter(1);
	MTPD("GetDevicePropValue %s\n",
			MtpDebug::getDevicePropCodeName(property));

	mDatabase->lockMutex();
	MtpResponseCode res = mDatabase->getDevicePropertyValue(property, mData);
	mDatabase->unlockMutex();
	return res;
}

MtpResponseCode MtpServer::doSetDevicePropValue() {
	MtpDeviceProperty property = mRequest.getParameter(1);
	MTPD("SetDevicePropValue %s\n",
			MtpDebug::getDevicePropCodeName(property));

	mDatabase->lockMutex();
	MtpResponseCode res = mDatabase->setDevicePropertyValue(property, mData);
	mDatabase->unlockMutex();
	return res;
}

MtpResponseCode MtpServer::doResetDevicePropValue() {
	MtpDeviceProperty property = mRequest.getParameter(1);
	MTPD("ResetDevicePropValue %s\n",
			MtpDebug::getDevicePropCodeName(property));

	mDatabase->lockMutex();
	MtpResponseCode res = mDatabase->resetDeviceProperty(property);
	mDatabase->unlockMutex();
	return res;
}

MtpResponseCode MtpServer::doGetObjectPropList() {
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;

	MtpObjectHandle handle = mRequest.getParameter(1);
	// use uint32_t so we can support 0xFFFFFFFF
	uint32_t format = mRequest.getParameter(2);
	uint32_t property = mRequest.getParameter(3);
	int groupCode = mRequest.getParameter(4);
	int depth = mRequest.getParameter(5);
	MTPD("GetObjectPropList %d format: %s property: %x group: %d depth: %d\n",
			handle, MtpDebug::getFormatCodeName(format),
			property, groupCode, depth);

	mDatabase->lockMutex();
	MtpResponseCode res = mDatabase->getObjectPropertyList(handle, format, property, groupCode, depth, mData);
	mDatabase->unlockMutex();
	return res;
}

MtpResponseCode MtpServer::doGetObjectInfo() {
	MTPD("inside doGetObjectInfo()\n");
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpObjectHandle handle = mRequest.getParameter(1);
	MtpObjectInfo info(handle);
	MTPD("calling mtpdatabase getObjectInfo()\n");
	mDatabase->lockMutex();
	MtpResponseCode result = mDatabase->getObjectInfo(handle, info);
	mDatabase->unlockMutex();
	if (result == MTP_RESPONSE_OK) {
		char	date[20];

		mData.putUInt32(info.mStorageID);
		mData.putUInt16(info.mFormat);
		mData.putUInt16(info.mProtectionStatus);

		// if object is being edited the database size may be out of date
		uint32_t size = info.mCompressedSize;
		ObjectEdit* edit = getEditObject(handle);
		if (edit)
			size = (edit->mSize > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)edit->mSize);
		mData.putUInt32(size);

		mData.putUInt16(info.mThumbFormat);
		mData.putUInt32(info.mThumbCompressedSize);
		mData.putUInt32(info.mThumbPixWidth);
		mData.putUInt32(info.mThumbPixHeight);
		mData.putUInt32(info.mImagePixWidth);
		mData.putUInt32(info.mImagePixHeight);
		mData.putUInt32(info.mImagePixDepth);
		mData.putUInt32(info.mParent);
		mData.putUInt16(info.mAssociationType);
		mData.putUInt32(info.mAssociationDesc);
		mData.putUInt32(info.mSequenceNumber);
		MTPD("info.mName: %s\n", info.mName);
		mData.putString(info.mName);
		mData.putEmptyString();	// date created
		formatDateTime(info.mDateModified, date, sizeof(date));
		mData.putString(date);   // date modified
		mData.putEmptyString();   // keywords
	}
	return result;
}

MtpResponseCode MtpServer::doGetObject() {
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpObjectHandle handle = mRequest.getParameter(1);
	MtpString pathBuf;
	int64_t fileLength;
	MtpObjectFormat format;
	MTPD("MtpServer::doGetObject calling getObjectFilePath\n");
	mDatabase->lockMutex();
	int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format);
	mDatabase->unlockMutex();
	if (result != MTP_RESPONSE_OK)
		return result;

	const char* filePath = (const char *)pathBuf;
	MTPD("filePath: %s\n", filePath);
	mtp_file_range  mfr;
	mfr.fd = open(filePath, O_RDONLY);
	if (mfr.fd < 0) {
		return MTP_RESPONSE_GENERAL_ERROR;
	}
	mfr.offset = 0;
	mfr.length = fileLength;
	MTPD("mfr.length: %lld\n", mfr.length);
	mfr.command = mRequest.getOperationCode();
	mfr.transaction_id = mRequest.getTransactionID();

	// then transfer the file
	int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr);
	MTPD("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
	close(mfr.fd);
	if (ret < 0) {
		if (errno == ECANCELED)
			return MTP_RESPONSE_TRANSACTION_CANCELLED;
		else
			return MTP_RESPONSE_GENERAL_ERROR;
	}
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doGetThumb() {
	MtpObjectHandle handle = mRequest.getParameter(1);
	size_t thumbSize;
	mDatabase->lockMutex();
	void* thumb = mDatabase->getThumbnail(handle, thumbSize);
	mDatabase->unlockMutex();
	if (thumb) {
		// send data
		mData.setOperationCode(mRequest.getOperationCode());
		mData.setTransactionID(mRequest.getTransactionID());
		mData.writeData(mFD, thumb, thumbSize);
		free(thumb);
		return MTP_RESPONSE_OK;
	} else {
		return MTP_RESPONSE_GENERAL_ERROR;
	}
}

MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) {
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpObjectHandle handle = mRequest.getParameter(1);
	uint64_t offset;
	uint32_t length;
	offset = mRequest.getParameter(2);
	if (operation == MTP_OPERATION_GET_PARTIAL_OBJECT_64) {
		// android extension with 64 bit offset
		uint64_t offset2 = mRequest.getParameter(3);
		offset = offset | (offset2 << 32);
		length = mRequest.getParameter(4);
	} else {
		// standard GetPartialObject
		length = mRequest.getParameter(3);
	}
	MtpString pathBuf;
	int64_t fileLength;
	MtpObjectFormat format;
	MTPD("MtpServer::doGetPartialObject calling getObjectFilePath\n");
	mDatabase->lockMutex();
	int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format);
	mDatabase->unlockMutex();
	if (result != MTP_RESPONSE_OK) {
		return result;
	}
	if (offset + length > (uint64_t)fileLength)
		length = fileLength - offset;

	const char* filePath = (const char *)pathBuf;
	mtp_file_range  mfr;
	mfr.fd = open(filePath, O_RDONLY);
	if (mfr.fd < 0) {
		return MTP_RESPONSE_GENERAL_ERROR;
	}
	mfr.offset = offset;
	mfr.length = length;
	mfr.command = mRequest.getOperationCode();
	mfr.transaction_id = mRequest.getTransactionID();
	mResponse.setParameter(1, length);

	// transfer the file
	int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr);
	MTPD("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
	close(mfr.fd);
	if (ret < 0) {
		if (errno == ECANCELED)
			return MTP_RESPONSE_TRANSACTION_CANCELLED;
		else
			return MTP_RESPONSE_GENERAL_ERROR;
	}
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doSendObjectInfo() {
	MTPD("MtpServer::doSendObjectInfo starting\n");
	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) {
		MTPD("MtpServer::doSendObjectInfo special case root\n");
		path = storage->getPath();
		parent = 0;
	} else {
		int64_t length;
		MtpObjectFormat format;
		MTPD("MtpServer::doSendObjectInfo calling getObjectFilePath\n");
		mDatabase->lockMutex();
		int result = mDatabase->getObjectFilePath(parent, path, length, format);
		mDatabase->unlockMutex();
		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

	MTPD("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;
	}

	MTPD("MtpServer::doSendObjectInfo path: %s parent: %d storageID: %08X\n", (const char*)path, parent, storageID);
	mDatabase->lockMutex();
	MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path,
			format, parent, storageID, mSendObjectFileSize, modifiedTime);
	mDatabase->unlockMutex();
	if (handle == kInvalidObjectHandle) {
		MTPE("MtpServer::doSendObjectInfo returning MTP_RESPONSE_GENERAL_ERROR, handle == kInvalidObjectHandle\n");
		return MTP_RESPONSE_GENERAL_ERROR;
	}

  if (format == MTP_FORMAT_ASSOCIATION) {
		mode_t mask = umask(0);
		MTPD("MtpServer::doSendObjectInfo mkdir '%s'\n", (const char *)path);
		int ret = mkdir((const char *)path, mDirectoryPermission);
		umask(mask);
		if (ret && ret != -EEXIST) {
			MTPE("MtpServer::doSendObjectInfo returning MTP_RESPONSE_GENERAL_ERROR, ret && ret != -EEXIST\n");
			return MTP_RESPONSE_GENERAL_ERROR;
		}
		chown((const char *)path, getuid(), mFileGroup);

		// SendObject does not get sent for directories, so call endSendObject here instead
		mDatabase->lockMutex();
		mDatabase->endSendObject(path, handle, MTP_FORMAT_ASSOCIATION, MTP_RESPONSE_OK);
		mDatabase->unlockMutex();
	} 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);
	MTPD("MtpServer::doSendObjectInfo returning MTP_RESPONSE_OK\n");
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doSendObject() {
	if (!hasStorage())
		return MTP_RESPONSE_GENERAL_ERROR;
	MtpResponseCode result = MTP_RESPONSE_OK;
	mode_t mask;
	int ret = 0, initialData;

	if (mSendObjectHandle == kInvalidObjectHandle) {
		MTPE("Expected SendObjectInfo before SendObject");
		result = MTP_RESPONSE_NO_VALID_OBJECT_INFO;
		goto done;
	}

	// read the header, and possibly some data
	ret = mData.read(mFD);
	if (ret < MTP_CONTAINER_HEADER_SIZE) {
		MTPE("MTP_RESPONSE_GENERAL_ERROR\n");
		result = MTP_RESPONSE_GENERAL_ERROR;
		goto done;
	}
	initialData = ret - MTP_CONTAINER_HEADER_SIZE;

	mtp_file_range  mfr;
	mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC, 0640);
	if (mfr.fd < 0) {
		result = MTP_RESPONSE_GENERAL_ERROR;
		MTPE("fd error\n");
		goto done;
	}
	fchown(mfr.fd, getuid(), mFileGroup);
	// set permissions
	mask = umask(0);
	fchmod(mfr.fd, mFilePermission);
	umask(mask);

	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;
		}

		MTPD("receiving %s\n", (const char *)mSendObjectFilePath);
		// transfer the file
		ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
	}
	close(mfr.fd);

	if (ret < 0) {
		unlink(mSendObjectFilePath);
		if (errno == ECANCELED)
			result = MTP_RESPONSE_TRANSACTION_CANCELLED;
		else {
		    	MTPD("errno: %d\n", errno);
			result = MTP_RESPONSE_GENERAL_ERROR;
		}
	}

done:
	// reset so we don't attempt to send the data back
	MTPD("MTP_RECEIVE_FILE returned %d\n", ret);
	mData.reset();
	mDatabase->lockMutex();
	mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat,
			result == MTP_RESPONSE_OK);
	mDatabase->unlockMutex();
	mSendObjectHandle = kInvalidObjectHandle;
	MTPD("result: %d\n", result);
	mSendObjectFormat = 0;
	return result;
}

static void deleteRecursive(const char* path) {
	char pathbuf[PATH_MAX];
	size_t pathLength = strlen(path);
	if (pathLength >= sizeof(pathbuf) - 1) {
		MTPE("path too long: %s\n", path);
	}
	strcpy(pathbuf, path);
	if (pathbuf[pathLength - 1] != '/') {
		pathbuf[pathLength++] = '/';
	}
	char* fileSpot = pathbuf + pathLength;
	int pathRemaining = sizeof(pathbuf) - pathLength - 1;

	DIR* dir = opendir(path);
	if (!dir) {
		MTPE("opendir %s failed: %s", path, strerror(errno));
		return;
	}

	struct dirent* entry;
	while ((entry = readdir(dir))) {
		const char* name = entry->d_name;

		// ignore "." and ".."
		if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
			continue;
		}

		int nameLength = strlen(name);
		if (nameLength > pathRemaining) {
			MTPE("path %s/%s too long\n", path, name);
			continue;
		}
		strcpy(fileSpot, name);

		int type = entry->d_type;
		struct stat st;
		if (lstat(pathbuf, &st)) {
			MTPE("Failed to lstat '%s'\n", pathbuf);
			continue;
		}
		if (st.st_mode & S_IFDIR) {
			deleteRecursive(pathbuf);
			rmdir(pathbuf);
		} else {
			unlink(pathbuf);
		}
	}
	closedir(dir);
}

static void deletePath(const char* path) {
	struct stat statbuf;
	if (stat(path, &statbuf) == 0) {
		if (S_ISDIR(statbuf.st_mode)) {
			deleteRecursive(path);
			rmdir(path);
		} else {
			unlink(path);
		}
	} else {
		MTPE("deletePath stat failed for %s: %s", path, strerror(errno));
	}
}

MtpResponseCode MtpServer::doDeleteObject() {
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpObjectHandle handle = mRequest.getParameter(1);
	MtpObjectFormat format = mRequest.getParameter(2);
	// FIXME - support deleting all objects if handle is 0xFFFFFFFF
	// FIXME - implement deleting objects by format

	MtpString filePath;
	int64_t fileLength;
	MTPD("MtpServer::doDeleteObject calling getObjectFilePath\n");
	mDatabase->lockMutex();
	int result = mDatabase->getObjectFilePath(handle, filePath, fileLength, format);
	if (result == MTP_RESPONSE_OK) {
		MTPD("deleting %s", (const char *)filePath);
		result = mDatabase->deleteFile(handle);
		// Don't delete the actual files unless the database deletion is allowed
		if (result == MTP_RESPONSE_OK) {
			deletePath((const char *)filePath);
		}
	}
	mDatabase->unlockMutex();
	return result;
}

MtpResponseCode MtpServer::doGetObjectPropDesc() {
	MtpObjectProperty propCode = mRequest.getParameter(1);
	MtpObjectFormat format = mRequest.getParameter(2);
	MTPD("MtpServer::doGetObjectPropDesc %s %s\n", MtpDebug::getObjectPropCodeName(propCode),
										MtpDebug::getFormatCodeName(format));
	mDatabase->lockMutex();
	MtpProperty* property = mDatabase->getObjectPropertyDesc(propCode, format);
	mDatabase->unlockMutex();
	if (!property) {
		MTPE("MtpServer::doGetObjectPropDesc propery not supported\n");
		return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
	}
	property->write(mData);
	delete property;
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doGetDevicePropDesc() {
	MtpDeviceProperty propCode = mRequest.getParameter(1);
	MTPD("GetDevicePropDesc %s\n", MtpDebug::getDevicePropCodeName(propCode));
	mDatabase->lockMutex();
	MtpProperty* property = mDatabase->getDevicePropertyDesc(propCode);
	mDatabase->unlockMutex();
	if (!property) {
		MTPE("MtpServer::doGetDevicePropDesc property not supported\n");
		return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
	}
	property->write(mData);
	delete property;
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doSendPartialObject() {
	if (!hasStorage())
		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
	MtpObjectHandle handle = mRequest.getParameter(1);
	uint64_t offset = mRequest.getParameter(2);
	uint64_t offset2 = mRequest.getParameter(3);
	offset = offset | (offset2 << 32);
	uint32_t length = mRequest.getParameter(4);

	ObjectEdit* edit = getEditObject(handle);
	if (!edit) {
		MTPE("object not open for edit in doSendPartialObject");
		return MTP_RESPONSE_GENERAL_ERROR;
	}

	// can't start writing past the end of the file
	if (offset > edit->mSize) {
		MTPE("writing past end of object, offset: %lld, edit->mSize: %lld", offset, edit->mSize);
		return MTP_RESPONSE_GENERAL_ERROR;
	}

	const char* filePath = (const char *)edit->mPath;
	MTPD("receiving partial %s %lld %lld\n", filePath, offset, length);

	// read the header, and possibly some data
	int ret = mData.read(mFD);
	if (ret < MTP_CONTAINER_HEADER_SIZE)
		return MTP_RESPONSE_GENERAL_ERROR;
	int initialData = ret - MTP_CONTAINER_HEADER_SIZE;

	if (initialData > 0) {
		ret = write(edit->mFD, mData.getData(), initialData);
		offset += initialData;
		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);
		MTPD("MTP_RECEIVE_FILE returned %d", ret);
	}
	if (ret < 0) {
		mResponse.setParameter(1, 0);
		if (errno == ECANCELED)
			return MTP_RESPONSE_TRANSACTION_CANCELLED;
		else
			return MTP_RESPONSE_GENERAL_ERROR;
	}

	// reset so we don't attempt to send this back
	mData.reset();
	mResponse.setParameter(1, length);
	uint64_t end = offset + length;
	if (end > edit->mSize) {
		edit->mSize = end;
	}
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doTruncateObject() {
	MtpObjectHandle handle = mRequest.getParameter(1);
	ObjectEdit* edit = getEditObject(handle);
	if (!edit) {
		MTPE("object not open for edit in doTruncateObject");
		return MTP_RESPONSE_GENERAL_ERROR;
	}

	uint64_t offset = mRequest.getParameter(2);
	uint64_t offset2 = mRequest.getParameter(3);
	offset |= (offset2 << 32);
	if (ftruncate(edit->mFD, offset) != 0) {
		return MTP_RESPONSE_GENERAL_ERROR;
	} else {
		edit->mSize = offset;
		return MTP_RESPONSE_OK;
	}
}

MtpResponseCode MtpServer::doBeginEditObject() {
	MtpObjectHandle handle = mRequest.getParameter(1);
	if (getEditObject(handle)) {
		MTPE("object already open for edit in doBeginEditObject");
		return MTP_RESPONSE_GENERAL_ERROR;
	}

	MtpString path;
	int64_t fileLength;
	MtpObjectFormat format;
	MTPD("MtpServer::doBeginEditObject calling getObjectFilePath\n");
	mDatabase->lockMutex();
	int result = mDatabase->getObjectFilePath(handle, path, fileLength, format);
	mDatabase->unlockMutex();
	if (result != MTP_RESPONSE_OK)
		return result;

	int fd = open((const char *)path, O_RDWR | O_EXCL);
	if (fd < 0) {
		MTPE("open failed for %s in doBeginEditObject (%d)", (const char *)path, errno);
		return MTP_RESPONSE_GENERAL_ERROR;
	}

	addEditObject(handle, path, fileLength, format, fd);
	return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doEndEditObject() {
	MtpObjectHandle handle = mRequest.getParameter(1);
	ObjectEdit* edit = getEditObject(handle);
	if (!edit) {
		MTPE("object not open for edit in doEndEditObject");
		return MTP_RESPONSE_GENERAL_ERROR;
	}

	commitEdit(edit);
	removeEditObject(handle);
	return MTP_RESPONSE_OK;
}
