VBoxGuestR3LibDragAndDrop.cpp revision 00331fbaff118e6a5077fe96327aca51a70459db
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/* $Id$ */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/** @file
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Drag & Drop.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/*
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Copyright (C) 2011-2013 Oracle Corporation
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync *
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * available from http://www.virtualbox.org. This file is free software;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * General Public License (GPL) as published by the Free Software
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync *
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * The contents of this file may alternatively be used under the terms
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * of the Common Development and Distribution License Version 1.0
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * VirtualBox OSE distribution, in which case the provisions of the
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * CDDL are applicable instead of those of the GPL.
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync *
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * You may elect to license modified versions of this file under the
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * terms and conditions of either the GPL or the CDDL or both.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/*******************************************************************************
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync* Header Files *
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync*******************************************************************************/
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/path.h>
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#include <iprt/dir.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/file.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/uri.h>
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync#include <iprt/thread.h>
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/cpp/list.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/cpp/ministring.h>
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include "VBGLR3Internal.h"
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include "VBox/HostServices/DragAndDropSvc.h"
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/* Here all the communication with the host over HGCM is handled platform
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * neutral. Also the receiving of URIs content (directory trees and files) is
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * done here. So the platform code of the guests, should not take care of that.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Todo:
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * - Sending dirs/files in the G->H case
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * - Maybe the EOL converting of text mime-types (not fully sure, eventually
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * better done on the host side)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic int vbglR3DnDPathSanitize(char *pszPath, size_t cbPath);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync/******************************************************************************
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Private internal functions *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ******************************************************************************/
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic int vbglR3DnDCreateDropDir(char* pszDropDir, size_t cbSize)
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync{
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync AssertPtrReturn(pszDropDir, VERR_INVALID_POINTER);
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync AssertReturn(cbSize, VERR_INVALID_PARAMETER);
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync /** @todo On Windows we also could use the registry to override
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync * this path, on Posix a dotfile and/or a guest property
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync * can be used. */
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync /* Get the users temp directory. Don't use the user's root directory (or
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync * something inside it) because we don't know for how long/if the data will
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync * be kept after the guest OS used it. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync int rc = RTPathTemp(pszDropDir, cbSize);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_FAILURE(rc))
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync return rc;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Append our base drop directory. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = RTPathAppend(pszDropDir, cbSize, "VirtualBox Dropped Files");
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync if (RT_FAILURE(rc))
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync return rc;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Create it when necessary. */
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync if (!RTDirExists(pszDropDir))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = RTDirCreateFullPath(pszDropDir, RTFS_UNIX_IRWXU);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_FAILURE(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return rc;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync /* The actually drop directory consist of the current time stamp and a
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * unique number when necessary. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync char pszTime[64];
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTTIMESPEC time;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime)))
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return VERR_BUFFER_OVERFLOW;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = vbglR3DnDPathSanitize(pszTime, sizeof(pszTime));
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (RT_FAILURE(rc))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return rc;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rc = RTPathAppend(pszDropDir, cbSize, pszTime);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (RT_FAILURE(rc))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return rc;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Create it (only accessible by the current user) */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTDirCreateUniqueNumbered(pszDropDir, cbSize, RTFS_UNIX_IRWXU, 3, '-');
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic int vbglR3DnDQueryNextHostMessageType(uint32_t uClientId, uint32_t *puMsg, uint32_t *pcParms, bool fWait)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync{
0c94a8282c9042b02f022302a3d987746140eab9vboxsync AssertPtrReturn(puMsg, VERR_INVALID_POINTER);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync DragAndDropSvc::VBOXDNDNEXTMSGMSG Msg;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync RT_ZERO(Msg);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.result = VERR_WRONG_ORDER;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.u32ClientID = uClientId;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.cParms = 3;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.msg.SetUInt32(0);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.num_parms.SetUInt32(0);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.block.SetUInt32(fWait);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (RT_SUCCESS(rc))
0c94a8282c9042b02f022302a3d987746140eab9vboxsync {
0c94a8282c9042b02f022302a3d987746140eab9vboxsync rc = Msg.hdr.result;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Fetch results */
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync rc = Msg.msg.GetUInt32(puMsg); AssertRC(rc);
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync rc = Msg.num_parms.GetUInt32(pcParms); AssertRC(rc);
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync }
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return rc;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic int vbglR3DnDHGProcessActionMessage(uint32_t uClientId,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync uint32_t uMsg,
56970d3a1944c7c073d66266cd52449835221badvboxsync uint32_t *puScreenId,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync uint32_t *puX,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync uint32_t *puY,
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync uint32_t *puDefAction,
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync uint32_t *puAllActions,
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync char *pszFormats,
56970d3a1944c7c073d66266cd52449835221badvboxsync uint32_t cbFormats,
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync uint32_t *pcbFormatsRecv)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertPtrReturn(puX, VERR_INVALID_POINTER);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertPtrReturn(puY, VERR_INVALID_POINTER);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertPtrReturn(puDefAction, VERR_INVALID_POINTER);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertPtrReturn(puAllActions, VERR_INVALID_POINTER);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertPtrReturn(pszFormats, VERR_INVALID_POINTER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertReturn(cbFormats, VERR_INVALID_PARAMETER);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertPtrReturn(pcbFormatsRecv, VERR_INVALID_POINTER);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync DragAndDropSvc::VBOXDNDHGACTIONMSG Msg;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RT_ZERO(Msg);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.hdr.u32ClientID = uClientId;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.hdr.u32Function = uMsg;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.hdr.cParms = 7;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync Msg.uScreenId.SetUInt32(0);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.uX.SetUInt32(0);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.uY.SetUInt32(0);
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync Msg.uDefAction.SetUInt32(0);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.uAllActions.SetUInt32(0);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.pvFormats.SetPtr(pszFormats, cbFormats);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync Msg.cFormats.SetUInt32(0);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = Msg.hdr.result;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync if (RT_SUCCESS(rc))
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync {
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync /* Fetch results */
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync rc = Msg.uX.GetUInt32(puX); AssertRC(rc);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync rc = Msg.uY.GetUInt32(puY); AssertRC(rc);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync rc = Msg.uDefAction.GetUInt32(puDefAction); AssertRC(rc);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync rc = Msg.uAllActions.GetUInt32(puAllActions); AssertRC(rc);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync rc = Msg.cFormats.GetUInt32(pcbFormatsRecv); AssertRC(rc);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync /* A little bit paranoia */
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync AssertReturn(cbFormats >= *pcbFormatsRecv, VERR_TOO_MUCH_DATA);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync }
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync return rc;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync}
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic int vbglR3DnDHGProcessLeaveMessage(uint32_t uClientId)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync DragAndDropSvc::VBOXDNDHGLEAVEMSG Msg;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RT_ZERO(Msg);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync Msg.hdr.u32ClientID = uClientId;
1969e98a26e5b56b67fbe3b6bfa007f8f09e86ebvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_LEAVE;
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync Msg.hdr.cParms = 0;
81614fc60e096e714022d10d38b70a36b9b21d48vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = Msg.hdr.result;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync return rc;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync}
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic int vbglR3DnDHGProcessCancelMessage(uint32_t uClientId)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync{
0c94a8282c9042b02f022302a3d987746140eab9vboxsync DragAndDropSvc::VBOXDNDHGCANCELMSG Msg;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync RT_ZERO(Msg);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.u32ClientID = uClientId;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_CANCEL;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.cParms = 0;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (RT_SUCCESS(rc))
0c94a8282c9042b02f022302a3d987746140eab9vboxsync rc = Msg.hdr.result;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return rc;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync}
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic int vbglR3DnDHGProcessSendDirMessage(uint32_t uClientId,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync char *pszDirname,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync uint32_t cbDirname,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync uint32_t *pcbDirnameRecv,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync uint32_t *pfMode)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync{
0c94a8282c9042b02f022302a3d987746140eab9vboxsync AssertPtrReturn(pszDirname, VERR_INVALID_POINTER);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync AssertReturn(cbDirname, VERR_INVALID_PARAMETER);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync AssertPtrReturn(pcbDirnameRecv, VERR_INVALID_POINTER);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync DragAndDropSvc::VBOXDNDHGSENDDIRMSG Msg;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync RT_ZERO(Msg);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.u32ClientID = uClientId;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DIR;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.hdr.cParms = 3;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.pvName.SetPtr(pszDirname, cbDirname);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.cName.SetUInt32(0);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.fMode.SetUInt32(0);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_SUCCESS(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = Msg.hdr.result;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_SUCCESS(Msg.hdr.result))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Fetch results */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = Msg.cName.GetUInt32(pcbDirnameRecv); AssertRC(rc);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = Msg.fMode.GetUInt32(pfMode); AssertRC(rc);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /* A little bit paranoia */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync AssertReturn(cbDirname >= *pcbDirnameRecv, VERR_TOO_MUCH_DATA);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return rc;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic int vbglR3DnDHGProcessSendFileMessage(uint32_t uClientId,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync char *pszFilename,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbFilename,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t *pcbFilenameRecv,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync void *pvData,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbData,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t *pcbDataRecv,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t *pfMode)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync{
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertReturn(cbFilename, VERR_INVALID_PARAMETER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertPtrReturn(pcbFilenameRecv, VERR_INVALID_POINTER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync DragAndDropSvc::VBOXDNDHGSENDFILEMSG Msg;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RT_ZERO(Msg);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.hdr.u32ClientID = uClientId;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_FILE;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.hdr.cParms = 5;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.pvName.SetPtr(pszFilename, cbFilename);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.cName.SetUInt32(0);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.pvData.SetPtr(pvData, cbData);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.cData.SetUInt32(0);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.fMode.SetUInt32(0);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync if (RT_SUCCESS(rc))
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync {
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync rc = Msg.hdr.result;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync if (RT_SUCCESS(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Fetch results */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = Msg.cName.GetUInt32(pcbFilenameRecv); AssertRC(rc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = Msg.cData.GetUInt32(pcbDataRecv); AssertRC(rc);
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync rc = Msg.fMode.GetUInt32(pfMode); AssertRC(rc);
56970d3a1944c7c073d66266cd52449835221badvboxsync /* A little bit paranoia */
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync AssertReturn(cbFilename >= *pcbFilenameRecv, VERR_TOO_MUCH_DATA);
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync }
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync }
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync return rc;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync}
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic int vbglR3DnDHGProcessURIMessages(uint32_t uClientId,
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync uint32_t *puScreenId,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync char *pszFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t *pcbFormatRecv,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync void **ppvData,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbData,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync size_t *pcbDataRecv)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync{
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertPtrReturn(ppvData, VERR_INVALID_POINTER);
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync AssertPtrReturn(cbData, VERR_INVALID_PARAMETER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Make a string list out of the uri data. */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTCList<RTCString> uriList = RTCString(static_cast<char*>(*ppvData), *pcbDataRecv - 1).split("\r\n");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (uriList.isEmpty())
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return VINF_SUCCESS;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbTmpData = _1M * 10; /** @todo r=andy 10MB, uh, really?? */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync void *pvTmpData = RTMemAlloc(cbTmpData);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (!pvTmpData)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return VERR_NO_MEMORY;
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Create and query the (unique) drop target directory. */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync char pszDropDir[RTPATH_MAX];
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync int rc = vbglR3DnDCreateDropDir(pszDropDir, sizeof(pszDropDir));
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_FAILURE(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTMemFree(pvTmpData);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return rc;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Patch the old drop data with the new drop directory, so the drop target
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * can find the files. */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTCList<RTCString> guestUriList;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync for (size_t i = 0; i < uriList.size(); ++i)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync const RTCString &strUri = uriList.at(i);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Query the path component of a file URI. If this hasn't a
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * file scheme, null is returned. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (pszFilePath)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = vbglR3DnDPathSanitize(pszFilePath, strlen(pszFilePath));
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (RT_FAILURE(rc))
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync break;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /** @todo Use RTPathJoin? */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTCString strFullPath = RTCString().printf("%s%c%s", pszDropDir, RTPATH_SLASH, pszFilePath);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync char *pszNewUri = RTUriFileCreate(strFullPath.c_str());
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (pszNewUri)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync guestUriList.append(pszNewUri);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTStrFree(pszNewUri);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync else
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync guestUriList.append(strUri);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Cleanup the old data and write the new data back to the event. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMemFree(*ppvData);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTCString newData = RTCString::join(guestUriList, "\r\n") + "\r\n";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *ppvData = RTStrDupN(newData.c_str(), newData.length());
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *pcbDataRecv = newData.length() + 1;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Lists for holding created files & directories in the case of a
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * rollback. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTCList<RTCString> guestDirList;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTCList<RTCString> guestFileList;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync char pszPathname[RTPATH_MAX];
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync uint32_t cbPathname = 0;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while (fLoop)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync uint32_t uNextMsg;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync uint32_t cNextParms;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false /* fWait */);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync switch (uNextMsg)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case DragAndDropSvc::HOST_DND_HG_SND_DIR:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync uint32_t fMode = 0;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = vbglR3DnDHGProcessSendDirMessage(uClientId,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync pszPathname,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync sizeof(pszPathname),
0c94a8282c9042b02f022302a3d987746140eab9vboxsync &cbPathname,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync &fMode);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (RT_SUCCESS(rc))
0c94a8282c9042b02f022302a3d987746140eab9vboxsync rc = vbglR3DnDPathSanitize(pszPathname, sizeof(pszPathname));
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (RT_SUCCESS(rc))
0c94a8282c9042b02f022302a3d987746140eab9vboxsync {
0c94a8282c9042b02f022302a3d987746140eab9vboxsync char *pszNewDir = RTPathJoinA(pszDropDir, pszPathname);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (pszNewDir)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync {
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (!guestDirList.contains(pszNewDir))
0c94a8282c9042b02f022302a3d987746140eab9vboxsync guestDirList.append(pszNewDir);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync RTStrFree(pszNewDir);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync }
0c94a8282c9042b02f022302a3d987746140eab9vboxsync else
0c94a8282c9042b02f022302a3d987746140eab9vboxsync rc = VERR_NO_MEMORY;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync break;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync case DragAndDropSvc::HOST_DND_HG_SND_FILE:
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync uint32_t cbDataRecv;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync uint32_t fMode = 0;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = vbglR3DnDHGProcessSendFileMessage(uClientId,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pszPathname,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync sizeof(pszPathname),
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync &cbPathname,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pvTmpData,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync cbTmpData,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync &cbDataRecv,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync &fMode);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = vbglR3DnDPathSanitize(pszPathname, sizeof(pszPathname));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync char *pszNewFile = RTPathJoinA(pszDropDir, pszPathname);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (pszNewFile)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTFILE hFile;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * create all sorts of funny races because we don't know if the guest has
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * modified the file in between the file data send calls. */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = RTFileOpen(&hFile, pszNewFile,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_SUCCESS(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, NULL);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_SUCCESS(rc))
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync {
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync rc = RTFileWrite(hFile, pvTmpData, cbDataRecv, 0);
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync /* Valid UNIX mode? */
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync if ( RT_SUCCESS(rc)
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync && (fMode & RTFS_UNIX_MASK))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTFileClose(hFile);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync if (!guestFileList.contains(pszNewFile))
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync guestFileList.append(pszNewFile);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync }
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTStrFree(pszNewFile);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync else
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync rc = VERR_NO_MEMORY;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync break;
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync }
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync {
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync rc = vbglR3DnDHGProcessCancelMessage(uClientId);
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync if (RT_SUCCESS(rc))
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync rc = VERR_CANCELLED;
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync /* Break out of the loop. */
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync }
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync default:
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync fLoop = false;
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync break;
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync }
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync }
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync else
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync {
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync if (rc == VERR_NO_DATA)
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync rc = VINF_SUCCESS;
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync break;
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync }
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync } /* while */
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync if (pvTmpData)
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync RTMemFree(pvTmpData);
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync /* Cleanup on failure or if the user has canceled. */
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync if (RT_FAILURE(rc))
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Remove any stuff created. */
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync for (size_t i = 0; i < guestFileList.size(); ++i)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTFileDelete(guestFileList.at(i).c_str());
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync for (size_t i = 0; i < guestDirList.size(); ++i)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTDirRemove(guestDirList.at(i).c_str());
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync RTDirRemove(pszDropDir);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync return rc;
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync}
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic int vbglR3DnDHGProcessDataMessageInternal(uint32_t uClientId,
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync uint32_t *puScreenId,
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync char *pszFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbFormat,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync uint32_t *pcbFormatRecv,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync void *pvData,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync uint32_t cbData,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync uint32_t *pcbDataTotal)
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync{
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync AssertReturn(cbFormat, VERR_INVALID_PARAMETER);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync AssertPtrReturn(pcbDataTotal, VERR_INVALID_POINTER);
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync DragAndDropSvc::VBOXDNDHGSENDDATAMSG Msg;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RT_ZERO(Msg);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.hdr.u32ClientID = uClientId;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DATA;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.cParms = 5;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync Msg.uScreenId.SetUInt32(0);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync Msg.pvFormat.SetPtr(pszFormat, cbFormat);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync Msg.cFormat.SetUInt32(0);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync Msg.pvData.SetPtr(pvData, cbData);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync Msg.cData.SetUInt32(0);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync if (RT_SUCCESS(rc))
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync {
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync rc = Msg.hdr.result;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync if ( RT_SUCCESS(rc)
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync || rc == VERR_BUFFER_OVERFLOW)
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync {
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync /* Fetch results */
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync rc = Msg.cData.GetUInt32(pcbDataTotal); AssertRC(rc);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync /* A little bit paranoia */
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync AssertReturn(cbData >= *pcbDataTotal, VERR_TOO_MUCH_DATA);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync }
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync }
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync return rc;
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync}
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsyncstatic int vbglR3DnDHGProcessMoreDataMessageInternal(uint32_t uClientId,
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync void *pvData,
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync uint32_t cbData,
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync uint32_t *pcbDataRecv)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync{
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync DragAndDropSvc::VBOXDNDHGSENDMOREDATAMSG Msg;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync RT_ZERO(Msg);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync Msg.hdr.u32ClientID = uClientId;
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.cParms = 2;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync Msg.pvData.SetPtr(pvData, cbData);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync Msg.cData.SetUInt32(0);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_SUCCESS(rc))
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync {
4f4cb69bca6bfda8f4d911759d1f3c6f528a173dvboxsync rc = Msg.hdr.result;
a66ec044d2a64d926996cd24da5faadccb070be3vboxsync if ( RT_SUCCESS(rc)
a66ec044d2a64d926996cd24da5faadccb070be3vboxsync || rc == VERR_BUFFER_OVERFLOW)
a66ec044d2a64d926996cd24da5faadccb070be3vboxsync {
a66ec044d2a64d926996cd24da5faadccb070be3vboxsync /* Fetch results */
a66ec044d2a64d926996cd24da5faadccb070be3vboxsync rc = Msg.cData.GetUInt32(pcbDataRecv); AssertRC(rc);
a66ec044d2a64d926996cd24da5faadccb070be3vboxsync /* A little bit paranoia */
a66ec044d2a64d926996cd24da5faadccb070be3vboxsync AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);
a66ec044d2a64d926996cd24da5faadccb070be3vboxsync }
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return rc;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync}
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic int vbglR3DnDHGProcessSendDataMessageLoop(uint32_t uClientId,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync uint32_t *puScreenId,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync char *pszFormat,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync uint32_t cbFormat,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync uint32_t *pcbFormatRecv,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync void **ppvData,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync uint32_t cbData,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync size_t *pcbDataRecv)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync{
0c94a8282c9042b02f022302a3d987746140eab9vboxsync uint32_t cbDataRecv = 0;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync int rc = vbglR3DnDHGProcessDataMessageInternal(uClientId,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync puScreenId,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pszFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync cbFormat,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pcbFormatRecv,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync *ppvData,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync cbData,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync &cbDataRecv);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbAllDataRecv = cbDataRecv;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync while (rc == VERR_BUFFER_OVERFLOW)
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync {
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync uint32_t uNextMsg;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cNextParms;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RT_SUCCESS(rc))
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync switch(uNextMsg)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync case DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA:
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync *ppvData = RTMemRealloc(*ppvData, cbAllDataRecv + cbData);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (!*ppvData)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = VERR_NO_MEMORY;
20f21077abf35d7b7b618acb159267933907407fvboxsync break;
20f21077abf35d7b7b618acb159267933907407fvboxsync }
20f21077abf35d7b7b618acb159267933907407fvboxsync rc = vbglR3DnDHGProcessMoreDataMessageInternal(uClientId,
0d8c2135d15345cc68111eea91052cdf5518d7e3vboxsync &((char*)*ppvData)[cbAllDataRecv],
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync cbData,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync &cbDataRecv);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync cbAllDataRecv += cbDataRecv;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync break;
20f21077abf35d7b7b618acb159267933907407fvboxsync }
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync default:
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = vbglR3DnDHGProcessCancelMessage(uClientId);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_SUCCESS(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = VERR_CANCELLED;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync break;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (RT_SUCCESS(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync *pcbDataRecv = cbAllDataRecv;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return rc;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync}
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic int vbglR3DnDHGProcessSendDataMessage(uint32_t uClientId,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t *puScreenId,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync char *pszFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t *pcbFormatRecv,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync void **ppvData,
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync uint32_t cbData,
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync size_t *pcbDataRecv)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync{
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync int rc = vbglR3DnDHGProcessSendDataMessageLoop(uClientId,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync puScreenId,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pszFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync cbFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pcbFormatRecv,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ppvData,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync cbData,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pcbDataRecv);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RT_SUCCESS(rc))
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Check if this is an URI event. If so, let VbglR3 do all the actual
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * data transfer + file /directory creation internally without letting
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * the caller know.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync *
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * This keeps the actual (guest OS-)dependent client (like VBoxClient /
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * VBoxTray) small by not having too much redundant code. */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RTStrNICmp(pszFormat, "text/uri-list", *pcbFormatRecv) == 0)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = vbglR3DnDHGProcessURIMessages(uClientId,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync puScreenId,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pszFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync cbFormat,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pcbFormatRecv,
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync ppvData,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync cbData,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pcbDataRecv);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return rc;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync}
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsyncstatic int vbglR3DnDGHProcessRequestPendingMessage(uint32_t uClientId,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync uint32_t *puScreenId)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync{
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync DragAndDropSvc::VBOXDNDGHREQPENDINGMSG Msg;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync RT_ZERO(Msg);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync Msg.hdr.u32ClientID = uClientId;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_REQ_PENDING;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.hdr.cParms = 1;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync Msg.uScreenId.SetUInt32(0);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
20f21077abf35d7b7b618acb159267933907407fvboxsync if (RT_SUCCESS(rc))
20f21077abf35d7b7b618acb159267933907407fvboxsync {
20f21077abf35d7b7b618acb159267933907407fvboxsync rc = Msg.hdr.result;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_SUCCESS(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Fetch results */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return rc;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync}
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic int vbglR3DnDGHProcessDroppedMessage(uint32_t uClientId,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync char *pszFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t cbFormat,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t *pcbFormatRecv,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t *puAction)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync{
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync AssertReturn(cbFormat, VERR_INVALID_PARAMETER);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync AssertPtrReturn(puAction, VERR_INVALID_POINTER);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync DragAndDropSvc::VBOXDNDGHDROPPEDMSG Msg;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RT_ZERO(Msg);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Msg.hdr.u32ClientID = uClientId;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_EVT_DROPPED;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync Msg.hdr.cParms = 3;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync Msg.pvFormat.SetPtr(pszFormat, cbFormat);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync Msg.cFormat.SetUInt32(0);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync Msg.uAction.SetUInt32(0);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_SUCCESS(rc))
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = Msg.hdr.result;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (RT_SUCCESS(rc))
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /* Fetch results */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = Msg.uAction.GetUInt32(puAction); AssertRC(rc);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /* A little bit paranoia */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return rc;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync}
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsyncstatic int vbglR3DnDPathSanitize(char *pszPath, size_t cbPath)
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync{
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync int rc = VINF_SUCCESS;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync#ifdef RT_OS_WINDOWS
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync /* Filter out characters not allowed on Windows platforms, put in by
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync RTTimeSpecToString(). */
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync /** @todo Use something like RTPathSanitize() when available. Later. */
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync RTUNICP aCpSet[] =
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_',
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync 0xa0, 0xd7af, '\0' };
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync ssize_t cReplaced = RTStrPurgeComplementSet(pszPath, aCpSet, '_' /* Replacement */);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync if (cReplaced < 0)
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync rc = VERR_INVALID_UTF8_ENCODING;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync#endif
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync return rc;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync}
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync/******************************************************************************
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync * Public functions *
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync ******************************************************************************/
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsyncVBGLR3DECL(int) VbglR3DnDConnect(uint32_t *pu32ClientId)
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync{
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync AssertPtrReturn(pu32ClientId, VERR_INVALID_POINTER);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync /* Initialize header */
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync VBoxGuestHGCMConnectInfo Info;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync RT_ZERO(Info.Loc.u);
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync Info.result = VERR_WRONG_ORDER;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Info.u32ClientID = UINT32_MAX; /* try make valgrind shut up. */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Initialize parameter */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync int rc = RTStrCopy(Info.Loc.u.host.achName, sizeof(Info.Loc.u.host.achName), "VBoxDragAndDropSvc");
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync if (RT_FAILURE(rc)) return rc;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /* Do request */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info));
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (RT_SUCCESS(rc))
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = Info.result;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (RT_SUCCESS(rc))
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync *pu32ClientId = Info.u32ClientID;
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync }
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync return rc;
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync}
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsyncVBGLR3DECL(int) VbglR3DnDDisconnect(uint32_t u32ClientId)
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync{
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync VBoxGuestHGCMDisconnectInfo Info;
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync Info.result = VERR_WRONG_ORDER;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync Info.u32ClientID = u32ClientId;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /* Do request */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (RT_SUCCESS(rc))
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = Info.result;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync return rc;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync}
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsyncVBGLR3DECL(int) VbglR3DnDProcessNextMessage(uint32_t u32ClientId, CPVBGLR3DNDHGCMEVENT pEvent)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync{
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync uint32_t uMsg = 0;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync uint32_t uNumParms = 0;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync const uint32_t ccbFormats = _64K;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync const uint32_t ccbData = _64K;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync int rc = vbglR3DnDQueryNextHostMessageType(u32ClientId, &uMsg, &uNumParms,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync true /* fWait */);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (RT_SUCCESS(rc))
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync switch(uMsg)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_ENTER:
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_MOVE:
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED:
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pEvent->uType = uMsg;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (!pEvent->pszFormats)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = VERR_NO_MEMORY;
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync if (RT_SUCCESS(rc))
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync rc = vbglR3DnDHGProcessActionMessage(u32ClientId,
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync uMsg,
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync &pEvent->uScreenId,
2346cab03e0c9fba1765c8e21ef98f03c8564cd8vboxsync &pEvent->u.a.uXpos,
81614fc60e096e714022d10d38b70a36b9b21d48vboxsync &pEvent->u.a.uYpos,
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync &pEvent->u.a.uDefAction,
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync &pEvent->u.a.uAllActions,
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync pEvent->pszFormats,
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync ccbFormats,
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync &pEvent->cbFormats);
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync break;
76f3a3817b6b96f5beb30b76efebdf2d87090cf0vboxsync }
81614fc60e096e714022d10d38b70a36b9b21d48vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE:
81614fc60e096e714022d10d38b70a36b9b21d48vboxsync {
a655881be920ead6948994168c5ee09e5798aa05vboxsync pEvent->uType = uMsg;
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync rc = vbglR3DnDHGProcessLeaveMessage(u32ClientId);
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync break;
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync case DragAndDropSvc::HOST_DND_HG_SND_DATA:
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pEvent->uType = uMsg;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (!pEvent->pszFormats)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync rc = VERR_NO_MEMORY;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync pEvent->u.b.pvData = RTMemAlloc(ccbData);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!pEvent->u.b.pvData)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMemFree(pEvent->pszFormats);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync pEvent->pszFormats = NULL;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = VERR_NO_MEMORY;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_SUCCESS(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = vbglR3DnDHGProcessSendDataMessage(u32ClientId,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync &pEvent->uScreenId,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync pEvent->pszFormats,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ccbFormats,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync &pEvent->cbFormats,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync &pEvent->u.b.pvData,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ccbData,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync &pEvent->u.b.cbData);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pEvent->uType = uMsg;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = vbglR3DnDHGProcessCancelMessage(u32ClientId);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync break;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync case DragAndDropSvc::HOST_DND_GH_REQ_PENDING:
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pEvent->uType = uMsg;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = vbglR3DnDGHProcessRequestPendingMessage(u32ClientId,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync &pEvent->uScreenId);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync break;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pEvent->uType = uMsg;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (!pEvent->pszFormats)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = VERR_NO_MEMORY;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RT_SUCCESS(rc))
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = vbglR3DnDGHProcessDroppedMessage(u32ClientId,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pEvent->pszFormats,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ccbFormats,
56970d3a1944c7c073d66266cd52449835221badvboxsync &pEvent->cbFormats,
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync &pEvent->u.a.uDefAction);
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync break;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync }
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync default:
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync rc = VERR_NOT_SUPPORTED;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync break;
56970d3a1944c7c073d66266cd52449835221badvboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return rc;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync}
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncVBGLR3DECL(int) VbglR3DnDHGAcknowledgeOperation(uint32_t u32ClientId, uint32_t uAction)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync{
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync DragAndDropSvc::VBOXDNDHGACKOPMSG Msg;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RT_ZERO(Msg);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.result = VERR_WRONG_ORDER;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.u32ClientID = u32ClientId;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_ACK_OP;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.cParms = 1;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Initialize parameter */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.uAction.SetUInt32(uAction);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Do request */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RT_SUCCESS(rc))
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = Msg.hdr.result;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return rc;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync}
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncVBGLR3DECL(int) VbglR3DnDHGRequestData(uint32_t u32ClientId, const char* pcszFormat)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync{
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync AssertPtrReturn(pcszFormat, VERR_INVALID_PARAMETER);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync DragAndDropSvc::VBOXDNDHGREQDATAMSG Msg;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync RT_ZERO(Msg);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.result = VERR_WRONG_ORDER;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.u32ClientID = u32ClientId;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_REQ_DATA;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.cParms = 1;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Initialize parameter */
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync Msg.pFormat.SetPtr((void*)pcszFormat, (uint32_t)strlen(pcszFormat) + 1);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Do request */
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync if (RT_SUCCESS(rc))
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync rc = Msg.hdr.result;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync return rc;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync}
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncVBGLR3DECL(int) VbglR3DnDGHAcknowledgePending(uint32_t u32ClientId,
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync uint32_t uDefAction, uint32_t uAllActions,
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync const char* pcszFormats)
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync{
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync AssertPtrReturn(pcszFormats, VERR_INVALID_POINTER);
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync DragAndDropSvc::VBOXDNDGHACKPENDINGMSG Msg;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RT_ZERO(Msg);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.result = VERR_WRONG_ORDER;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync Msg.hdr.u32ClientID = u32ClientId;
56970d3a1944c7c073d66266cd52449835221badvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_ACK_PENDING;
56970d3a1944c7c073d66266cd52449835221badvboxsync Msg.hdr.cParms = 3;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Initialize parameter */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.uDefAction.SetUInt32(uDefAction);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.uAllActions.SetUInt32(uAllActions);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.pFormat.SetPtr((void*)pcszFormats, (uint32_t)strlen(pcszFormats) + 1);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Do request */
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync if (RT_SUCCESS(rc))
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = Msg.hdr.result;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return rc;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync}
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsyncVBGLR3DECL(int) VbglR3DnDGHSendData(uint32_t u32ClientId, void *pvData, uint32_t cbData)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync DragAndDropSvc::VBOXDNDGHSENDDATAMSG Msg;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync RT_ZERO(Msg);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync Msg.hdr.result = VERR_WRONG_ORDER;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.u32ClientID = u32ClientId;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DATA;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync Msg.hdr.cParms = 2;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.uSize.SetUInt32(cbData);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync int rc = VINF_SUCCESS;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync uint32_t cbMax = _1M; /** @todo Remove 1 MB limit. */
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync uint32_t cbSent = 0;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync while (cbSent < cbData)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync /* Initialize parameter */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync uint32_t cbToSend = RT_MIN(cbData - cbSent, cbMax);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync Msg.pData.SetPtr(static_cast<uint8_t*>(pvData) + cbSent, cbToSend);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Do request */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RT_SUCCESS(rc))
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync rc = Msg.hdr.result;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /* Did the host cancel the event? */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (rc == VERR_CANCELLED)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync break;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync else
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync break;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync cbSent += cbToSend;
23d8f7aff045c2bade1b168fee79a3e4749e2345vboxsync// RTThreadSleep(500);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync return rc;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync}
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncVBGLR3DECL(int) VbglR3DnDGHErrorEvent(uint32_t u32ClientId, int rcOp)
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync{
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync DragAndDropSvc::VBOXDNDGHEVTERRORMSG Msg;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RT_ZERO(Msg);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync Msg.hdr.result = VERR_WRONG_ORDER;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync Msg.hdr.u32ClientID = u32ClientId;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_EVT_ERROR;
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync Msg.hdr.cParms = 1;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /* Initialize parameter */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync Msg.uRC.SetUInt32(rcOp);
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync /* Do request */
20f21077abf35d7b7b618acb159267933907407fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
20f21077abf35d7b7b618acb159267933907407fvboxsync if (RT_SUCCESS(rc))
20f21077abf35d7b7b618acb159267933907407fvboxsync rc = Msg.hdr.result;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync
20f21077abf35d7b7b618acb159267933907407fvboxsync return rc;
20f21077abf35d7b7b618acb159267933907407fvboxsync}
20f21077abf35d7b7b618acb159267933907407fvboxsync
20f21077abf35d7b7b618acb159267933907407fvboxsyncVBGLR3DECL(int) VbglR3DnDGHSendFile(uint32_t u32ClientId, const char *pszPath)
20f21077abf35d7b7b618acb159267933907407fvboxsync{
20f21077abf35d7b7b618acb159267933907407fvboxsync return 0;
9540ab73f6cd0c76f44f6bbfe73f89ac145390b8vboxsync}
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync