GuestDnDSourceImpl.cpp revision 1a3b02207c6b6aca1b7bdd50fc2e79defe4e405e
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/* $Id$ */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/** @file
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * VBox Console COM Class implementation - Guest drag and drop source.
c793af95640863cd29868fc7c419c5d2496b207bsangeeta */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/*
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Copyright (C) 2014 Oracle Corporation
c793af95640863cd29868fc7c419c5d2496b207bsangeeta *
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
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/*******************************************************************************
c793af95640863cd29868fc7c419c5d2496b207bsangeeta* Header Files *
c793af95640863cd29868fc7c419c5d2496b207bsangeeta*******************************************************************************/
fff7ec1d8ce71b3d8a998ac4391a99860ce07180Sowmini Varadhan#include "GuestImpl.h"
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include "GuestDnDSourceImpl.h"
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include "GuestDnDPrivate.h"
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include "Global.h"
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include "AutoCaller.h"
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include <iprt/cpp/utils.h> /* For unconst(). */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include <VBox/com/array.h>
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include <VBox/GuestHost/DragAndDrop.h>
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include <VBox/HostServices/DragAndDropSvc.h>
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#ifdef LOG_GROUP
c793af95640863cd29868fc7c419c5d2496b207bsangeeta #undef LOG_GROUP
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#endif
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#define LOG_GROUP LOG_GROUP_GUEST_DND
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include <VBox/log.h>
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// constructor / destructor
edd26dc5eeb3b093945c371e4b6dd8286348d53fdr/////////////////////////////////////////////////////////////////////////////
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeetaDEFINE_EMPTY_CTOR_DTOR(GuestDnDSource)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeetaHRESULT GuestDnDSource::FinalConstruct(void)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta LogFlowThisFunc(("\n"));
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return BaseFinalConstruct();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeetavoid GuestDnDSource::FinalRelease(void)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta LogFlowThisFuncEnter();
edd26dc5eeb3b093945c371e4b6dd8286348d53fdr uninit();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta BaseFinalRelease();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta LogFlowThisFuncLeave();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// public initializer/uninitializer for internal purposes only
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/////////////////////////////////////////////////////////////////////////////
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeetaint GuestDnDSource::init(const ComObjPtr<Guest>& pGuest)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta LogFlowThisFuncEnter();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta /* Enclose the state transition NotReady->InInit->Ready. */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AutoInitSpan autoInitSpan(this);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AssertReturn(autoInitSpan.isOk(), E_FAIL);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta unconst(m_pGuest) = pGuest;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta /* Confirm a successful initialization when it's the case. */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta autoInitSpan.setSucceeded();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return VINF_SUCCESS;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan/**
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan * Uninitializes the instance.
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan * Called from FinalRelease().
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkvoid GuestDnDSource::uninit(void)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta LogFlowThisFunc(("\n"));
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta /* Enclose the state transition Ready->InUninit->NotReady. */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AutoUninitSpan autoUninitSpan(this);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (autoUninitSpan.uninitDone())
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// implementation of wrapped IDnDBase methods.
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark/////////////////////////////////////////////////////////////////////////////
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::isFormatSupported(const com::Utf8Str &aFormat,
c793af95640863cd29868fc7c419c5d2496b207bsangeeta BOOL *aSupported)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta ReturnComNotImplemented();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#else /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark AutoCaller autoCaller(this);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (FAILED(autoCaller.rc())) return autoCaller.rc();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return GuestDnDBase::isFormatSupported(aFormat, aSupported);
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan#endif /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
188e166434dcdde5356d87fb06c169f15dc4dca9Erik NordmarkHRESULT GuestDnDSource::getFormats(std::vector<com::Utf8Str> &aFormats)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta ReturnComNotImplemented();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#else /* VBOX_WITH_DRAG_AND_DROP */
188e166434dcdde5356d87fb06c169f15dc4dca9Erik Nordmark
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AutoCaller autoCaller(this);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (FAILED(autoCaller.rc())) return autoCaller.rc();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
188e166434dcdde5356d87fb06c169f15dc4dca9Erik Nordmark
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return GuestDnDBase::getFormats(aFormats);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#endif /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::addFormats(const std::vector<com::Utf8Str> &aFormats)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta ReturnComNotImplemented();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#else /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AutoCaller autoCaller(this);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (FAILED(autoCaller.rc())) return autoCaller.rc();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return GuestDnDBase::addFormats(aFormats);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#endif /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
c793af95640863cd29868fc7c419c5d2496b207bsangeetaHRESULT GuestDnDSource::removeFormats(const std::vector<com::Utf8Str> &aFormats)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh ReturnComNotImplemented();
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh#else /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AutoCaller autoCaller(this);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (FAILED(autoCaller.rc())) return autoCaller.rc();
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return GuestDnDBase::removeFormats(aFormats);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#endif /* VBOX_WITH_DRAG_AND_DROP */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// implementation of wrapped IDnDTarget methods.
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark/////////////////////////////////////////////////////////////////////////////
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::dragIsPending(ULONG uScreenId,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark std::vector<com::Utf8Str> &aFormats,
c793af95640863cd29868fc7c419c5d2496b207bsangeeta std::vector<DnDAction_T> &aAllowedActions,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark DnDAction_T *aDefaultAction)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ReturnComNotImplemented();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#else /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark AutoCaller autoCaller(this);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (FAILED(autoCaller.rc())) return autoCaller.rc();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Default is ignoring the action. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark DnDAction_T defaultAction = DnDAction_Ignore;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
c793af95640863cd29868fc7c419c5d2496b207bsangeeta HRESULT hr = S_OK;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark VBOXHGCMSVCPARM paParms[1];
c793af95640863cd29868fc7c419c5d2496b207bsangeeta int i = 0;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng paParms[i++].setUInt32(uScreenId);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int rc = GuestDnDInst()->hostCall(DragAndDropSvc::HOST_DND_GH_REQ_PENDING,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark i, paParms);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (RT_SUCCESS(rc))
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng bool fFetchResult = true;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng GuestDnDResponse *pResp = GuestDnDInst()->response();
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (pResp)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (pResp->waitForGuestResponse() == VERR_TIMEOUT)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark fFetchResult = false;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (isDnDIgnoreAction(pResp->defAction()))
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark fFetchResult = false;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Fetch the default action to use. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (fFetchResult)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng defaultAction = GuestDnD::toMainAction(pResp->defAction());
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark GuestDnD::toFormatVector(m_strFormats, pResp->format(), aFormats);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark GuestDnD::toMainActions(pResp->allActions(), aAllowedActions);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (aDefaultAction)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta *aDefaultAction = defaultAction;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (RT_FAILURE(rc))
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark hr = setError(VBOX_E_IPRT_ERROR,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark tr("Unable to retrieve pending status (%Rrc)\n"), rc);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("hr=%Rhrc, defaultAction=0x%x\n", hr, defaultAction));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark return hr;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#endif /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark}
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::drop(const com::Utf8Str &aFormat,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng DnDAction_T aAction, ComPtr<IProgress> &aProgress)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ReturnComNotImplemented();
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#else /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
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"));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark AutoCaller autoCaller(this);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (FAILED(autoCaller.rc())) return autoCaller.rc();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint32_t uAction = GuestDnD::toHGCMAction(aAction);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* If there is no usable action, ignore this request. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (isDnDIgnoreAction(uAction))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return S_OK;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng HRESULT hr = S_OK;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark const char *pcszFormat = aFormat.c_str();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark bool fNeedsDropDir = DnDMIMENeedsDropDir(pcszFormat, strlen(pcszFormat));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("strFormat=%s, uAction=0x%x, fNeedsDropDir=%RTbool\n",
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark pcszFormat, uAction, fNeedsDropDir));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark GuestDnDResponse *pResp = GuestDnDInst()->response();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (pResp)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Reset any old data. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark pResp->reset();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark pResp->resetProgress(m_pGuest);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Set the format we are going to retrieve to have it around
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * when retrieving the data later. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark pResp->setFormat(aFormat);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (fNeedsDropDir)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark char szDropDir[RTPATH_MAX];
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int rc = DnDDirCreateDroppedFiles(szDropDir, sizeof(szDropDir));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng LogFlowFunc(("rc=%Rrc, szDropDir=%s\n", rc, szDropDir));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (RT_FAILURE(rc))
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark return setError(VBOX_E_IPRT_ERROR,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark tr("Unable to create the temporary drag and drop directory \"%s\" (%Rrc)\n"),
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark szDropDir, rc);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark pResp->setDropDir(szDropDir);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark VBOXHGCMSVCPARM paParms[4];
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int i = 0;
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 paParms[i++].setUInt32(uAction);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int rc = GuestDnDInst()->hostCall(DragAndDropSvc::HOST_DND_GH_EVT_DROPPED,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark i, paParms);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (RT_SUCCESS(rc))
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Query the progress object to the caller. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark pResp->queryProgressTo(aProgress.asOutParam());
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark else
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark hr = setError(VBOX_E_IPRT_ERROR,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark tr("Error signalling to drop data (%Rrc)\n"), rc);
188e166434dcdde5356d87fb06c169f15dc4dca9Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("Returning hr=%Rhrc\n", hr));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark return hr;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#endif /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark}
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik NordmarkHRESULT GuestDnDSource::receiveData(std::vector<BYTE> &aData)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ReturnComNotImplemented();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#else /* VBOX_WITH_DRAG_AND_DROP */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Input validation. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark AutoCaller autoCaller(this);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (FAILED(autoCaller.rc())) return autoCaller.rc();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark HRESULT hr = S_OK;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark GuestDnDResponse *pResp = GuestDnDInst()->response();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (pResp)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng size_t cbData = pResp->size();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (cbData)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const void *pvData = pResp->data();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark AssertPtr(pvData);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark Utf8Str strFormat = pResp->format();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("strFormat=%s, cbData=%zu, pvData=0x%p\n",
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark strFormat.c_str(), cbData, pvData));
e11c3f44f531fdff80941ce57c065d2ae861cefcmeem
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark try
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (DnDMIMEHasFileURLs(strFormat.c_str(), strFormat.length()))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("strDropDir=%s\n", pResp->dropDir().c_str()));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark DnDURIList lstURI;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark int rc2 = lstURI.RootFromURIData(pvData, cbData, 0 /* fFlags */);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (RT_SUCCESS(rc2))
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark Utf8Str strURIs = lstURI.RootToString(pResp->dropDir());
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark size_t cbURIs = strURIs.length();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("Found %zu root URIs (%zu bytes)\n",
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark lstURI.RootCount(), cbURIs));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark aData.resize(cbURIs + 1 /* Include termination */);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark memcpy(&aData.front(), strURIs.c_str(), cbURIs);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark else
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark hr = VBOX_E_IPRT_ERROR;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark else
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Copy the data into a safe array of bytes. */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark aData.resize(cbData);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark memcpy(&aData.front(), pvData, cbData);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark catch (std::bad_alloc &)
9e3469d3db608feb0e43d9955cbf406c22025463Erik Nordmark {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark hr = E_OUTOFMEMORY;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /* Delete the data. */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng pResp->reset();
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark else
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hr = VBOX_E_INVALID_OBJECT_STATE;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark LogFlowFunc(("Returning hr=%Rhrc\n", hr));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark return hr;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark#endif /* VBOX_WITH_DRAG_AND_DROP */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark