GuestDnDSourceImpl.cpp revision 1a3b02207c6b6aca1b7bdd50fc2e79defe4e405e
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * VBox Console COM Class implementation - Guest drag and drop source.
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Copyright (C) 2014 Oracle Corporation
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * This file is part of VirtualBox Open Source Edition (OSE), as
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * available from http://www.virtualbox.org. This file is free software;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * you can redistribute it and/or modify it under the terms of the GNU
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * General Public License (GPL) as published by the Free Software
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Foundation, in version 2 as it comes in the "COPYING" file of the
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/*******************************************************************************
c793af95640863cd29868fc7c419c5d2496b207bsangeeta* Header Files *
c793af95640863cd29868fc7c419c5d2496b207bsangeeta*******************************************************************************/
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// constructor / destructor
edd26dc5eeb3b093945c371e4b6dd8286348d53fdr/////////////////////////////////////////////////////////////////////////////
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// public initializer/uninitializer for internal purposes only
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/////////////////////////////////////////////////////////////////////////////
c793af95640863cd29868fc7c419c5d2496b207bsangeetaint GuestDnDSource::init(const ComObjPtr<Guest>& pGuest)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta /* Enclose the state transition NotReady->InInit->Ready. */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta /* Confirm a successful initialization when it's the case. */
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan * Uninitializes the instance.
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan * Called from FinalRelease().
c793af95640863cd29868fc7c419c5d2496b207bsangeeta /* Enclose the state transition Ready->InUninit->NotReady. */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// implementation of wrapped IDnDBase methods.
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark/////////////////////////////////////////////////////////////////////////////
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::isFormatSupported(const com::Utf8Str &aFormat,
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#else /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (FAILED(autoCaller.rc())) return autoCaller.rc();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return GuestDnDBase::isFormatSupported(aFormat, aSupported);
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan#endif /* VBOX_WITH_DRAG_AND_DROP */
188e166434dcdde5356d87fb06c169f15dc4dca9Erik NordmarkHRESULT GuestDnDSource::getFormats(std::vector<com::Utf8Str> &aFormats)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#else /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (FAILED(autoCaller.rc())) return autoCaller.rc();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#endif /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::addFormats(const std::vector<com::Utf8Str> &aFormats)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#else /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (FAILED(autoCaller.rc())) return autoCaller.rc();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#endif /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeetaHRESULT GuestDnDSource::removeFormats(const std::vector<com::Utf8Str> &aFormats)
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh#else /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (FAILED(autoCaller.rc())) return autoCaller.rc();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#endif /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// implementation of wrapped IDnDTarget methods.
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark/////////////////////////////////////////////////////////////////////////////
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::dragIsPending(ULONG uScreenId,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#else /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (FAILED(autoCaller.rc())) return autoCaller.rc();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Default is ignoring the action. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int rc = GuestDnDInst()->hostCall(DragAndDropSvc::HOST_DND_GH_REQ_PENDING,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng GuestDnDResponse *pResp = GuestDnDInst()->response();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (pResp->waitForGuestResponse() == VERR_TIMEOUT)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Fetch the default action to use. */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng defaultAction = GuestDnD::toMainAction(pResp->defAction());
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark GuestDnD::toFormatVector(m_strFormats, pResp->format(), aFormats);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark GuestDnD::toMainActions(pResp->allActions(), aAllowedActions);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark tr("Unable to retrieve pending status (%Rrc)\n"), rc);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("hr=%Rhrc, defaultAction=0x%x\n", hr, defaultAction));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#endif /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::drop(const com::Utf8Str &aFormat,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng DnDAction_T aAction, ComPtr<IProgress> &aProgress)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#else /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Input validation. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (RT_UNLIKELY((aFormat.c_str()) == NULL || *(aFormat.c_str()) == '\0'))
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark return setError(E_INVALIDARG, tr("No drop format specified"));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (FAILED(autoCaller.rc())) return autoCaller.rc();
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint32_t uAction = GuestDnD::toHGCMAction(aAction);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* If there is no usable action, ignore this request. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark bool fNeedsDropDir = DnDMIMENeedsDropDir(pcszFormat, strlen(pcszFormat));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("strFormat=%s, uAction=0x%x, fNeedsDropDir=%RTbool\n",
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark GuestDnDResponse *pResp = GuestDnDInst()->response();
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Reset any old data. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Set the format we are going to retrieve to have it around
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * when retrieving the data later. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int rc = DnDDirCreateDroppedFiles(szDropDir, sizeof(szDropDir));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng LogFlowFunc(("rc=%Rrc, szDropDir=%s\n", rc, szDropDir));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark tr("Unable to create the temporary drag and drop directory \"%s\" (%Rrc)\n"),
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark paParms[i++].setPointer((void*)aFormat.c_str(), (uint32_t)aFormat.length() + 1);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark paParms[i++].setUInt32((uint32_t)aFormat.length() + 1);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int rc = GuestDnDInst()->hostCall(DragAndDropSvc::HOST_DND_GH_EVT_DROPPED,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Query the progress object to the caller. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark pResp->queryProgressTo(aProgress.asOutParam());
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark tr("Error signalling to drop data (%Rrc)\n"), rc);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#endif /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::receiveData(std::vector<BYTE> &aData)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#else /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Input validation. */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (FAILED(autoCaller.rc())) return autoCaller.rc();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark GuestDnDResponse *pResp = GuestDnDInst()->response();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("strFormat=%s, cbData=%zu, pvData=0x%p\n",
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (DnDMIMEHasFileURLs(strFormat.c_str(), strFormat.length()))
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("strDropDir=%s\n", pResp->dropDir().c_str()));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int rc2 = lstURI.RootFromURIData(pvData, cbData, 0 /* fFlags */);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark Utf8Str strURIs = lstURI.RootToString(pResp->dropDir());
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("Found %zu root URIs (%zu bytes)\n",
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark aData.resize(cbURIs + 1 /* Include termination */);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark memcpy(&aData.front(), strURIs.c_str(), cbURIs);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Copy the data into a safe array of bytes. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Delete the data. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#endif /* VBOX_WITH_DRAG_AND_DROP */