VBoxGuestR3LibDragAndDrop.cpp revision 63f24ac9931b0f1ccae2b11fdccd535ebca34c84
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/* $Id$ */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/** @file
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Drag & Drop.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/*
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * Copyright (C) 2011-2013 Oracle Corporation
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * available from http://www.virtualbox.org. This file is free software;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * General Public License (GPL) as published by the Free Software
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * The contents of this file may alternatively be used under the terms
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * of the Common Development and Distribution License Version 1.0
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * VirtualBox OSE distribution, in which case the provisions of the
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * CDDL are applicable instead of those of the GPL.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * You may elect to license modified versions of this file under the
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * terms and conditions of either the GPL or the CDDL or both.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/*******************************************************************************
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync* Header Files *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync*******************************************************************************/
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#include <iprt/path.h>
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#include <iprt/dir.h>
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#include <iprt/file.h>
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#include <iprt/uri.h>
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#include <iprt/thread.h>
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#include <iprt/cpp/list.h>
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#include <iprt/cpp/ministring.h>
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#ifdef LOG_GROUP
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync #undef LOG_GROUP
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#endif
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#define LOG_GROUP LOG_GROUP_GUEST_DND
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#include <VBox/log.h>
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
5c127165d63f95b1763b4af2a2c6ae1025fc84fevboxsync#include <VBox/GuestHost/DragAndDrop.h>
5c127165d63f95b1763b4af2a2c6ae1025fc84fevboxsync#include <VBox/HostServices/DragAndDropSvc.h>
5c127165d63f95b1763b4af2a2c6ae1025fc84fevboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#include "VBGLR3Internal.h"
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/* Here all the communication with the host over HGCM is handled platform
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * neutral. Also the receiving of URIs content (directory trees and files) is
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * done here. So the platform code of the guests, should not take care of that.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Todo:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * - Sending dirs/files in the G->H case
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * - Maybe the EOL converting of text MIME types (not fully sure, eventually
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * better done on the host side)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/******************************************************************************
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Private internal functions *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync ******************************************************************************/
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDQueryNextHostMessageType(uint32_t uClientId, uint32_t *puMsg, uint32_t *pcParms, bool fWait)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puMsg, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDNEXTMSGMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.result = VERR_WRONG_ORDER;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 3;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.msg.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.num_parms.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.block.SetUInt32(fWait);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.msg.GetUInt32(puMsg); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.num_parms.GetUInt32(pcParms); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessActionMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t uMsg,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puScreenId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puX,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puY,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puDefAction,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puAllActions,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync char *pszFormats,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbFormats,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbFormatsRecv)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puX, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puY, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puDefAction, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puAllActions, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pszFormats, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormats, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbFormatsRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGACTIONMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = uMsg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 7;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uScreenId.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uX.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uY.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uDefAction.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uAllActions.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pvFormats.SetPtr(pszFormats, cbFormats);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.cFormats.SetUInt32(0);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uX.GetUInt32(puX); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uY.GetUInt32(puY); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uDefAction.GetUInt32(puDefAction); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uAllActions.GetUInt32(puAllActions); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.cFormats.GetUInt32(pcbFormatsRecv); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormats >= *pcbFormatsRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessLeaveMessage(uint32_t uClientId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGLEAVEMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_LEAVE;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 0;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessCancelMessage(uint32_t uClientId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGCANCELMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_CANCEL;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 0;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessSendDirMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync char *pszDirname,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbDirname,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbDirnameRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pfMode)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pszDirname, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbDirname, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbDirnameRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGSENDDIRMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DIR;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 3;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pvName.SetPtr(pszDirname, cbDirname);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbName.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.fMode.SetUInt32(0);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(Msg.hdr.result))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.cbName.GetUInt32(pcbDirnameRecv); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.fMode.GetUInt32(pfMode); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbDirname >= *pcbDirnameRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessSendFileMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync char *pszFilename,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbFilename,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbFilenameRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync void *pvData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbDataRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pfMode)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFilename, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbFilenameRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGSENDFILEMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_FILE;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 5;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pvName.SetPtr(pszFilename, cbFilename);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbName.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pvData.SetPtr(pvData, cbData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbData.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.fMode.SetUInt32(0);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.cbName.GetUInt32(pcbFilenameRecv); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.cbData.GetUInt32(pcbDataRecv); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.fMode.GetUInt32(pfMode); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFilename >= *pcbFilenameRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessURIMessages(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puScreenId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync char *pszFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbFormatRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync void **ppvData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync size_t *pcbDataRecv)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
822e11c896dd36c9dc3609dff676059576b7d3devboxsync AssertPtrReturn(ppvData, VERR_INVALID_POINTER);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync AssertPtrReturn(cbData, VERR_INVALID_PARAMETER);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync
82391de567696f10b21a762fde6a06fe3c266d28vboxsync if (!*pcbDataRecv)
82391de567696f10b21a762fde6a06fe3c266d28vboxsync return VERR_INVALID_PARAMETER;
82391de567696f10b21a762fde6a06fe3c266d28vboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Allocate temp buffer. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync uint32_t cbTmpData = _64K; /** @todo Make this configurable? */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync void *pvTmpData = RTMemAlloc(cbTmpData);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (!pvTmpData)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return VERR_NO_MEMORY;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync /* Create and query the (unique) drop target directory. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync char pszDropDir[RTPATH_MAX];
82391de567696f10b21a762fde6a06fe3c266d28vboxsync int rc = DnDDirCreateDroppedFiles(pszDropDir, sizeof(pszDropDir));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_FAILURE(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RTMemFree(pvTmpData);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Patch the old drop data with the new drop directory, so the drop target
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * can find the files. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync DnDURIList lstURI;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = lstURI.RootFromURIData(*ppvData, *pcbDataRecv,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync 0 /* fFlags */);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync if (RT_SUCCESS(rc))
822e11c896dd36c9dc3609dff676059576b7d3devboxsync {
822e11c896dd36c9dc3609dff676059576b7d3devboxsync /* Cleanup the old data and write the new data back to the event. */
822e11c896dd36c9dc3609dff676059576b7d3devboxsync RTMemFree(*ppvData);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTCString strData = lstURI.RootToString(pszDropDir);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync *ppvData = RTStrDupN(strData.c_str(), strData.length());
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync *pcbDataRecv = strData.length() + 1;
822e11c896dd36c9dc3609dff676059576b7d3devboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
82391de567696f10b21a762fde6a06fe3c266d28vboxsync /* Lists for holding created files & directories
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * in the case of a rollback. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RTCList<RTCString> guestDirList;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RTCList<RTCString> guestFileList;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync char szPathName[RTPATH_MAX];
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync uint32_t cbPathName = 0;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
822e11c896dd36c9dc3609dff676059576b7d3devboxsync bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */
822e11c896dd36c9dc3609dff676059576b7d3devboxsync while (fLoop)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t uNextMsg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cNextParms;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false /* fWait */);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
822e11c896dd36c9dc3609dff676059576b7d3devboxsync switch (uNextMsg)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_SND_DIR:
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync {
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync uint32_t fMode = 0;
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = vbglR3DnDHGProcessSendDirMessage(uClientId,
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync szPathName,
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync sizeof(szPathName),
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync &cbPathName,
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync &fMode);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync#ifdef DEBUG_andy
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowFunc(("HOST_DND_HG_SND_DIR pszPathName=%s, cbPathName=%RU32, fMode=0x%x, rc=%Rrc\n",
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync szPathName, cbPathName, fMode, rc));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync#endif
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (RT_SUCCESS(rc))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = DnDPathSanitize(szPathName, sizeof(szPathName));
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync char *pszNewDir = RTPathJoinA(pszDropDir, szPathName);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (pszNewDir)
822e11c896dd36c9dc3609dff676059576b7d3devboxsync {
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (!guestDirList.contains(pszNewDir))
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync guestDirList.append(pszNewDir);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync RTStrFree(pszNewDir);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync }
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync else
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = VERR_NO_MEMORY;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync break;
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_SND_FILE:
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync {
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync uint32_t cbDataRecv;
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync uint32_t fMode = 0;
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = vbglR3DnDHGProcessSendFileMessage(uClientId,
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync szPathName,
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync sizeof(szPathName),
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync &cbPathName,
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync pvTmpData,
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync cbTmpData,
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync &cbDataRecv,
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync &fMode);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync#ifdef DEBUG_andy
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowFunc(("HOST_DND_HG_SND_FILE pszPathName=%s, cbPathName=%RU32, pvData=0x%p, cbDataRecv=%RU32, fMode=0x%x, rc=%Rrc\n",
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync szPathName, cbPathName, pvTmpData, cbDataRecv, fMode, rc));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync#endif
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (RT_SUCCESS(rc))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = DnDPathSanitize(szPathName, sizeof(szPathName));
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync char *pszPathAbs = RTPathJoinA(pszDropDir, szPathName);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (pszPathAbs)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync RTFILE hFile;
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync * create all sorts of funny races because we don't know if the guest has
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync * modified the file in between the file data send calls. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = RTFileOpen(&hFile, pszPathAbs,
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /** @todo r=andy Not very safe to assume that we were last appending to the current file. */
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, NULL);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync if (RT_SUCCESS(rc))
822e11c896dd36c9dc3609dff676059576b7d3devboxsync {
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = RTFileWrite(hFile, pvTmpData, cbDataRecv, 0);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync /* Valid UNIX mode? */
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if ( RT_SUCCESS(rc)
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync && (fMode & RTFS_UNIX_MASK))
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync }
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync RTFileClose(hFile);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (!guestFileList.contains(pszPathAbs))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync guestFileList.append(pszPathAbs);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync#ifdef DEBUG
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync else
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowFunc(("Opening file failed with rc=%Rrc\n", rc));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync#endif
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync RTStrFree(pszPathAbs);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync else
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = VERR_NO_MEMORY;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync break;
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync {
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = vbglR3DnDHGProcessCancelMessage(uClientId);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (RT_SUCCESS(rc))
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = VERR_CANCELLED;
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync /* Break out of the loop. */
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync default:
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync fLoop = false;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync else
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync if (rc == VERR_NO_DATA)
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = VINF_SUCCESS;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (RT_FAILURE(rc))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync break;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
822e11c896dd36c9dc3609dff676059576b7d3devboxsync } /* while */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync if (pvTmpData)
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync RTMemFree(pvTmpData);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Cleanup on failure or if the user has canceled. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_FAILURE(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Remove any stuff created. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync for (size_t i = 0; i < guestFileList.size(); ++i)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RTFileDelete(guestFileList.at(i).c_str());
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync for (size_t i = 0; i < guestDirList.size(); ++i)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RTDirRemove(guestDirList.at(i).c_str());
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RTDirRemove(pszDropDir);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowFunc(("Failed with rc=%Rrc\n", rc));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessDataMessageInternal(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puScreenId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync char *pszFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbFormatRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync void *pvData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbData,
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync uint32_t *pcbDataTotal)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormat, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync AssertPtrReturn(pcbDataTotal, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGSENDDATAMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DATA;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 5;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uScreenId.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pvFormat.SetPtr(pszFormat, cbFormat);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.cFormat.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pvData.SetPtr(pvData, cbData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbData.SetUInt32(0);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync if ( RT_SUCCESS(rc)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync || rc == VERR_BUFFER_OVERFLOW)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = Msg.cbData.GetUInt32(pcbDataTotal); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync AssertReturn(cbData >= *pcbDataTotal, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessMoreDataMessageInternal(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync void *pvData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbDataRecv)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGSENDMOREDATAMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 2;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pvData.SetPtr(pvData, cbData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbData.SetUInt32(0);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if ( RT_SUCCESS(rc)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync || rc == VERR_BUFFER_OVERFLOW)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.cbData.GetUInt32(pcbDataRecv); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncstatic int vbglR3DnDHGProcessSendDataMessageLoop(uint32_t uClientId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync uint32_t *puScreenId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync char *pszFormat,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync uint32_t cbFormat,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync uint32_t *pcbFormatRecv,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync void **ppvData,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync uint32_t cbData,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync size_t *pcbDataRecv)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbDataRecv = 0;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DnDHGProcessDataMessageInternal(uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync puScreenId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pszFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync cbFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pcbFormatRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *ppvData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync cbData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync &cbDataRecv);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync uint32_t cbAllDataRecv = cbDataRecv;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync while (rc == VERR_BUFFER_OVERFLOW)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t uNextMsg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cNextParms;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync switch(uNextMsg)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *ppvData = RTMemRealloc(*ppvData, cbAllDataRecv + cbData);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (!*ppvData)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = VERR_NO_MEMORY;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DnDHGProcessMoreDataMessageInternal(uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync &((char*)*ppvData)[cbAllDataRecv],
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync cbData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync &cbDataRecv);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync cbAllDataRecv += cbDataRecv;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync default:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DnDHGProcessCancelMessage(uClientId);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = VERR_CANCELLED;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *pcbDataRecv = cbAllDataRecv;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessSendDataMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puScreenId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync char *pszFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbFormatRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync void **ppvData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync size_t *pcbDataRecv)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync int rc = vbglR3DnDHGProcessSendDataMessageLoop(uClientId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync puScreenId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pszFormat,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync cbFormat,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pcbFormatRecv,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync ppvData,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync cbData,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pcbDataRecv);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync /* Check if this is an URI event. If so, let VbglR3 do all the actual
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * data transfer + file/directory creation internally without letting
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync * the caller know.
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync *
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync * This keeps the actual (guest OS-)dependent client (like VBoxClient /
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync * VBoxTray) small by not having too much redundant code. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertPtr(pcbFormatRecv);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (DnDMIMEHasFileURLs(pszFormat, *pcbFormatRecv))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DnDHGProcessURIMessages(uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync puScreenId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pszFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync cbFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pcbFormatRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync ppvData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync cbData,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pcbDataRecv);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDGHProcessRequestPendingMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puScreenId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDGHREQPENDINGMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_REQ_PENDING;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 1;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uScreenId.SetUInt32(0);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDGHProcessDroppedMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync char *pszFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t cbFormat,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *pcbFormatRecv,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t *puAction)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormat, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puAction, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDGHDROPPEDMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32ClientID = uClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_EVT_DROPPED;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 3;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pvFormat.SetPtr(pszFormat, cbFormat);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.cFormat.SetUInt32(0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uAction.SetUInt32(0);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uAction.GetUInt32(puAction); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/******************************************************************************
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Public functions *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync ******************************************************************************/
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncVBGLR3DECL(int) VbglR3DnDConnect(uint32_t *pu32ClientId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pu32ClientId, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Initialize header */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync VBoxGuestHGCMConnectInfo Info;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Info.Loc.u);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Info.result = VERR_WRONG_ORDER;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Info.u32ClientID = UINT32_MAX; /* try make valgrind shut up. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Initialize parameter */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = RTStrCopy(Info.Loc.u.host.achName, sizeof(Info.Loc.u.host.achName), "VBoxDragAndDropSvc");
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_FAILURE(rc)) return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Do request */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Info.result;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *pu32ClientId = Info.u32ClientID;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncVBGLR3DECL(int) VbglR3DnDDisconnect(uint32_t u32ClientId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync VBoxGuestHGCMDisconnectInfo Info;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Info.result = VERR_WRONG_ORDER;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Info.u32ClientID = u32ClientId;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Do request */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Info.result;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncVBGLR3DECL(int) VbglR3DnDProcessNextMessage(uint32_t u32ClientId, CPVBGLR3DNDHGCMEVENT pEvent)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t uMsg = 0;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync uint32_t uNumParms = 0;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync const uint32_t ccbFormats = _64K;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync const uint32_t ccbData = _64K;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync int rc = vbglR3DnDQueryNextHostMessageType(u32ClientId, &uMsg, &uNumParms,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync true /* fWait */);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync switch(uMsg)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_ENTER:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_MOVE:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->uType = uMsg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (!pEvent->pszFormats)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = VERR_NO_MEMORY;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync if (RT_SUCCESS(rc))
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDHGProcessActionMessage(u32ClientId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync uMsg,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->uScreenId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->u.a.uXpos,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->u.a.uYpos,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->u.a.uDefAction,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->u.a.uAllActions,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pEvent->pszFormats,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync ccbFormats,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->cbFormats);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->uType = uMsg;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDHGProcessLeaveMessage(u32ClientId);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_HG_SND_DATA:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->uType = uMsg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (!pEvent->pszFormats)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = VERR_NO_MEMORY;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pEvent->u.b.pvData = RTMemAlloc(ccbData);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync if (!pEvent->u.b.pvData)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync {
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync RTMemFree(pEvent->pszFormats);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pEvent->pszFormats = NULL;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = VERR_NO_MEMORY;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync if (RT_SUCCESS(rc))
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDHGProcessSendDataMessage(u32ClientId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->uScreenId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pEvent->pszFormats,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync ccbFormats,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->cbFormats,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->u.b.pvData,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync ccbData,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->u.b.cbData);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync break;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync }
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync case DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA:
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync case DragAndDropSvc::HOST_DND_HG_SND_DIR:
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync case DragAndDropSvc::HOST_DND_HG_SND_FILE:
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync pEvent->uType = uMsg;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync /* All messages in this case are handled internally
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync * by vbglR3DnDHGProcessSendDataMessage() and must
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync * be specified by a preceding HOST_DND_HG_SND_DATA call. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = VERR_WRONG_ORDER;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync break;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync {
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pEvent->uType = uMsg;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDHGProcessCancelMessage(u32ClientId);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
82391de567696f10b21a762fde6a06fe3c266d28vboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_GH_REQ_PENDING:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->uType = uMsg;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDGHProcessRequestPendingMessage(u32ClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync &pEvent->uScreenId);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->uType = uMsg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (!pEvent->pszFormats)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = VERR_NO_MEMORY;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync if (RT_SUCCESS(rc))
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDGHProcessDroppedMessage(u32ClientId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync pEvent->pszFormats,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync ccbFormats,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->cbFormats,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync &pEvent->u.a.uDefAction);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
82391de567696f10b21a762fde6a06fe3c266d28vboxsync#endif
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync default:
82391de567696f10b21a762fde6a06fe3c266d28vboxsync {
82391de567696f10b21a762fde6a06fe3c266d28vboxsync pEvent->uType = uMsg;
82391de567696f10b21a762fde6a06fe3c266d28vboxsync
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync rc = VERR_NOT_SUPPORTED;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
82391de567696f10b21a762fde6a06fe3c266d28vboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncVBGLR3DECL(int) VbglR3DnDHGAcknowledgeOperation(uint32_t u32ClientId, uint32_t uAction)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGACKOPMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.result = VERR_WRONG_ORDER;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync Msg.hdr.u32ClientID = u32ClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_ACK_OP;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 1;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uAction.SetUInt32(uAction);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncVBGLR3DECL(int) VbglR3DnDHGRequestData(uint32_t u32ClientId, const char* pcszFormat)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcszFormat, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDHGREQDATAMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.result = VERR_WRONG_ORDER;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync Msg.hdr.u32ClientID = u32ClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_REQ_DATA;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 1;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pFormat.SetPtr((void*)pcszFormat, (uint32_t)strlen(pcszFormat) + 1);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
63f24ac9931b0f1ccae2b11fdccd535ebca34c84vboxsync#ifdef VBOX_WITH_DRAG_AND_DROP_GH
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncVBGLR3DECL(int) VbglR3DnDGHAcknowledgePending(uint32_t u32ClientId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync uint32_t uDefAction, uint32_t uAllActions,
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync const char* pcszFormats)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync AssertPtrReturn(pcszFormats, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDGHACKPENDINGMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.result = VERR_WRONG_ORDER;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync Msg.hdr.u32ClientID = u32ClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_ACK_PENDING;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 3;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uDefAction.SetUInt32(uDefAction);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.uAllActions.SetUInt32(uAllActions);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync Msg.pFormat.SetPtr((void*)pcszFormats, (uint32_t)strlen(pcszFormats) + 1);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHSendDataInternal(uint32_t u32ClientId,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync void *pvData, uint32_t cbData,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbAdditionalData)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDGHSENDDATAMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.result = VERR_WRONG_ORDER;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync Msg.hdr.u32ClientID = u32ClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DATA;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 2;
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Total amount of bytes to send (including this data block). */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbTotalBytes.SetUInt32(cbData + cbAdditionalData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync int rc;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbMaxChunk = _64K; /* Transfer max. 64K chunks per message. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbSent = 0;
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync
a3011b448b38c39a7222f2f1eb40c8349023f650vboxsync while (cbSent < cbData)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbCurChunk = RT_MIN(cbData - cbSent, cbMaxChunk);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.pvData.SetPtr(static_cast<uint8_t*>(pvData) + cbSent, cbCurChunk);
82391de567696f10b21a762fde6a06fe3c266d28vboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
82391de567696f10b21a762fde6a06fe3c266d28vboxsync
82391de567696f10b21a762fde6a06fe3c266d28vboxsync if (RT_FAILURE(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break;
82391de567696f10b21a762fde6a06fe3c266d28vboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync cbSent += cbCurChunk;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync }
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
82391de567696f10b21a762fde6a06fe3c266d28vboxsync if (RT_SUCCESS(rc))
82391de567696f10b21a762fde6a06fe3c266d28vboxsync Assert(cbSent == cbData);
82391de567696f10b21a762fde6a06fe3c266d28vboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LogFlowFunc(("Returning rc=%Rrc, cbData=%RU32, cbAddtionalData=%RU32\n",
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc, cbData, cbAdditionalData));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync return rc;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync}
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHSendDir(uint32_t u32ClientId, DnDURIObject &obj)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync{
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertReturn(obj.GetType() == DnDURIObject::Directory, VERR_INVALID_PARAMETER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync DragAndDropSvc::VBOXDNDGHSENDDIRMSG Msg;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RT_ZERO(Msg);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.result = VERR_WRONG_ORDER;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.u32ClientID = u32ClientId;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DIR;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.cParms = 3;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTCString strPath = obj.GetDestPath();
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LogFlowFunc(("strDir=%s (%zu), fMode=0x%x\n",
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync strPath.c_str(), strPath.length(), obj.GetMode()));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbName.SetUInt32((uint32_t)(strPath.length() + 1));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.fMode.SetUInt32(obj.GetMode());
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (RT_SUCCESS(rc))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.hdr.result;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LogFlowFuncLeaveRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync return rc;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync}
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHSendFile(uint32_t u32ClientId, DnDURIObject &obj)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync{
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertReturn(obj.GetType() == DnDURIObject::File, VERR_INVALID_PARAMETER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbBuf = _64K; /** @todo Make this configurable? */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync void *pvBuf = RTMemAlloc(cbBuf);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (!pvBuf)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync return VERR_NO_MEMORY;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync DragAndDropSvc::VBOXDNDGHSENDFILEMSG Msg;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RT_ZERO(Msg);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.result = VERR_WRONG_ORDER;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.u32ClientID = u32ClientId;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_FILE;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.cParms = 5;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTCString strPath = obj.GetDestPath();
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LogFlowFunc(("strFile=%s (%zu), fMode=0x%x\n",
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync strPath.c_str(), strPath.length(), obj.GetMode()));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbName.SetUInt32((uint32_t)(strPath.length() + 1));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.fMode.SetUInt32(obj.GetMode());
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync int rc = VINF_SUCCESS;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbData = obj.GetSize();
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync do
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbToRead = RT_MIN(cbData, cbBuf);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbRead = 0;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (cbToRead)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = obj.Read(pvBuf, cbToRead, &cbRead);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (RT_SUCCESS(rc))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbData.SetUInt32(cbRead);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.pvData.SetPtr(pvBuf, cbRead);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (RT_SUCCESS(rc))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.hdr.result;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync }
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (RT_FAILURE(rc))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync break;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Assert(cbRead <= cbData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync cbData -= cbRead;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync } while (cbData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTMemFree(pvBuf);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LogFlowFuncLeaveRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync return rc;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync}
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHSendURIObject(uint32_t u32ClientId, DnDURIObject &obj)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync{
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync int rc;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync switch (obj.GetType())
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case DnDURIObject::Directory:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHSendDir(u32ClientId, obj);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync break;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case DnDURIObject::File:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHSendFile(u32ClientId, obj);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync break;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync default:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertMsgFailed(("Type %ld not implemented\n",
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync obj.GetType()));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = VERR_NOT_IMPLEMENTED;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync break;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync }
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync return rc;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync}
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHProcessURIMessages(uint32_t u32ClientId,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync void *pvData, uint32_t cbData)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync{
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTCList<RTCString> lstPaths =
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTCString((const char *)pvData, cbData).split("\r\n");
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync DnDURIList lstURI;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync int rc = lstURI.AppendNativePathsFromList(lstPaths, 0 /* fFlags */);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (RT_SUCCESS(rc))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Send metadata; in this case it's the (non-recursive) file/directory
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * URI list the host needs to know to initialize the drag'n drop operation. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTCString strRootDest = lstURI.RootToString();
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Assert(strRootDest.isNotEmpty());
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync void *pvToSend = (void *)strRootDest.c_str();
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbToSend = (uint32_t)strRootDest.length() + 1;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHSendDataInternal(u32ClientId, pvToSend, cbToSend,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Include total bytes of all file paths,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * file sizes etc. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync lstURI.TotalBytes());
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync }
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (RT_SUCCESS(rc))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync while (!lstURI.IsEmpty())
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync DnDURIObject &nextObj = lstURI.First();
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHSendURIObject(u32ClientId, nextObj);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (RT_FAILURE(rc))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync break;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync lstURI.RemoveFirst();
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync }
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync }
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync return rc;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync}
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncVBGLR3DECL(int) VbglR3DnDGHSendData(uint32_t u32ClientId,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync const char *pszFormat,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync void *pvData, uint32_t cbData)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync{
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync int rc;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (DnDMIMEHasFileURLs(pszFormat, strlen(pszFormat)))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHProcessURIMessages(u32ClientId, pvData, cbData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync }
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync else
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHSendDataInternal(u32ClientId, pvData, cbData,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync 0 /* cbAdditionalData */);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (RT_FAILURE(rc))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync int rc2 = VbglR3DnDGHSendError(u32ClientId, rc);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (RT_SUCCESS(rc2))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc2 = rc;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync }
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsyncVBGLR3DECL(int) VbglR3DnDGHSendError(uint32_t u32ClientId, int rcErr)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync{
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync DragAndDropSvc::VBOXDNDGHEVTERRORMSG Msg;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync RT_ZERO(Msg);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.result = VERR_WRONG_ORDER;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync Msg.hdr.u32ClientID = u32ClientId;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_EVT_ERROR;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.cParms = 1;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync Msg.uRC.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if (RT_SUCCESS(rc))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.hdr.result;
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowFunc(("Sending error %Rrc returned with rc=%Rrc\n", rcErr, rc));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return rc;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync}
63f24ac9931b0f1ccae2b11fdccd535ebca34c84vboxsync#endif /* VBOX_WITH_DRAG_AND_DROP_GH */