VBoxGuestR3LibDragAndDrop.cpp revision ebcdaa5077bc9189c419330b1c84880018e3db99
77b1a2d8b5dbe2c0b5200794914239fee3c8ee5dvboxsync * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Drag & Drop.
be41e59f051a3abb5cd05e7fe270ab2fea791f5avboxsync * Copyright (C) 2011-2013 Oracle Corporation
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * available from http://www.virtualbox.org. This file is free software;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * The contents of this file may alternatively be used under the terms
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * of the Common Development and Distribution License Version 1.0
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * VirtualBox OSE distribution, in which case the provisions of the
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * CDDL are applicable instead of those of the GPL.
cd6f71bc352f550074f1ba2c830a2cf2f0b3dd46vboxsync * You may elect to license modified versions of this file under the
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * terms and conditions of either the GPL or the CDDL or both.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Header Files *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
efff36b306e370346025647a158689021df2e1d1vboxsync/* Here all the communication with the host over HGCM is handled platform
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * neutral. Also the receiving of URIs content (directory trees and files) is
f5e53763b0a581b0299e98028c6c52192eb06785vboxsync * done here. So the platform code of the guests, should not take care of that.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * - Sending dirs/files in the G->H case
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * - Maybe the EOL converting of text MIME types (not fully sure, eventually
efff36b306e370346025647a158689021df2e1d1vboxsync * better done on the host side)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Private internal functions *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync ******************************************************************************/
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncstatic int vbglR3DnDQueryNextHostMessageType(uint32_t uClientId, uint32_t *puMsg, uint32_t *pcParms, bool fWait)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync rc = Msg.num_parms.GetUInt32(pcParms); AssertRC(rc);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncstatic int vbglR3DnDHGProcessActionMessage(uint32_t uClientId,
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertPtrReturn(puDefAction, VERR_INVALID_POINTER);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync AssertPtrReturn(puAllActions, VERR_INVALID_POINTER);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync AssertPtrReturn(pcbFormatsRecv, VERR_INVALID_POINTER);
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync rc = Msg.uDefAction.GetUInt32(puDefAction); AssertRC(rc);
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync rc = Msg.uAllActions.GetUInt32(puAllActions); AssertRC(rc);
c0a370e600bb60153a269fb32b5f709347c35768vboxsync rc = Msg.cFormats.GetUInt32(pcbFormatsRecv); AssertRC(rc);
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync AssertReturn(cbFormats >= *pcbFormatsRecv, VERR_TOO_MUCH_DATA);
61d064a54f03596920c3918f58ecc7764074a5d8vboxsyncstatic int vbglR3DnDHGProcessLeaveMessage(uint32_t uClientId)
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_LEAVE;
16a9adc14900ca18e6909679a579f6833425e030vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsyncstatic int vbglR3DnDHGProcessCancelMessage(uint32_t uClientId)
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_CANCEL;
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
e4f367251aede667a6de69baa54ef9eb5f150871vboxsyncstatic int vbglR3DnDHGProcessSendDirMessage(uint32_t uClientId,
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync AssertPtrReturn(pcbDirnameRecv, VERR_INVALID_POINTER);
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DIR;
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync rc = Msg.cbName.GetUInt32(pcbDirnameRecv); AssertRC(rc);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync AssertReturn(cbDirname >= *pcbDirnameRecv, VERR_TOO_MUCH_DATA);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsyncstatic int vbglR3DnDHGProcessSendFileMessage(uint32_t uClientId,
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync AssertPtrReturn(pcbFilenameRecv, VERR_INVALID_POINTER);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_FILE;
16a9adc14900ca18e6909679a579f6833425e030vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
16a9adc14900ca18e6909679a579f6833425e030vboxsync rc = Msg.cbName.GetUInt32(pcbFilenameRecv); AssertRC(rc);
16a9adc14900ca18e6909679a579f6833425e030vboxsync rc = Msg.cbData.GetUInt32(pcbDataRecv); AssertRC(rc);
16a9adc14900ca18e6909679a579f6833425e030vboxsync AssertReturn(cbFilename >= *pcbFilenameRecv, VERR_TOO_MUCH_DATA);
16a9adc14900ca18e6909679a579f6833425e030vboxsync AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);
16a9adc14900ca18e6909679a579f6833425e030vboxsyncstatic int vbglR3DnDHGProcessURIMessages(uint32_t uClientId,
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* Allocate temp buffer. */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync uint32_t cbTmpData = _64K; /** @todo Make this configurable? */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* Create and query the (unique) drop target directory. */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync int rc = DnDDirCreateDroppedFiles(pszDropDir, sizeof(pszDropDir));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* Patch the old drop data with the new drop directory, so the drop target
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * can find the files. */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync rc = lstURI.RootFromURIData(*ppvData, *pcbDataRecv,
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync 0 /* fFlags */);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* Cleanup the old data and write the new data back to the event. */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync RTCString strData = lstURI.RootToString(pszDropDir);
a9d49c8f2b28a72e6a4db86eee91e4569290157bvboxsync *ppvData = RTStrDupN(strData.c_str(), strData.length());
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* Lists for holding created files & directories
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * in the case of a rollback. */
22ec733a5e041fcdfe02fce2eafc9faf8b0077ddvboxsync bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */
aa834e89e076db44fa8fe82d177748f0a45d14c2vboxsync rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false /* fWait */);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync LogFlowFunc(("HOST_DND_HG_SND_DIR pszPathName=%s, cbPathName=%RU32, fMode=0x%x, rc=%Rrc\n",
d5ea45cc92d7f1d3ade8189944531f665bfe8ed5vboxsync rc = DnDPathSanitize(szPathName, sizeof(szPathName));
9496f2d398b49813176939d7a339ae513d5175efvboxsync char *pszNewDir = RTPathJoinA(pszDropDir, szPathName);
468c2bcb36eb9a032f5dd0fcb34db10bd58e9996vboxsync rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0);
ba74637cb4d2e749337d51ccbfb1038bdd3e2092vboxsync LogFlowFunc(("HOST_DND_HG_SND_FILE pszPathName=%s, cbPathName=%RU32, pvData=0x%p, cbDataRecv=%RU32, fMode=0x%x, rc=%Rrc\n",
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync szPathName, cbPathName, pvTmpData, cbDataRecv, fMode, rc));
ba74637cb4d2e749337d51ccbfb1038bdd3e2092vboxsync rc = DnDPathSanitize(szPathName, sizeof(szPathName));
adefd5e9babba486cba0cfae52f5a0f6c8c4ef24vboxsync char *pszPathAbs = RTPathJoinA(pszDropDir, szPathName);
b5ad839a3757b305d4e98d7264da2b53c9cd27f0vboxsync /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * create all sorts of funny races because we don't know if the guest has
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * modified the file in between the file data send calls. */
b5ad839a3757b305d4e98d7264da2b53c9cd27f0vboxsync RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE);
b5ad839a3757b305d4e98d7264da2b53c9cd27f0vboxsync /** @todo r=andy Not very safe to assume that we were last appending to the current file. */
b5ad839a3757b305d4e98d7264da2b53c9cd27f0vboxsync /* Valid UNIX mode? */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
9496f2d398b49813176939d7a339ae513d5175efvboxsync LogFlowFunc(("Opening file failed with rc=%Rrc\n", rc));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /* Break out of the loop. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync } /* while */
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync /* Cleanup on failure or if the user has canceled. */
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync /* Remove any stuff created. */
16a9adc14900ca18e6909679a579f6833425e030vboxsyncstatic int vbglR3DnDHGProcessDataMessageInternal(uint32_t uClientId,
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER);
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync AssertPtrReturn(pcbDataTotal, VERR_INVALID_POINTER);
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DATA;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
a0a5ab4e085a7ee5b95bdfae04cec7de95792c3cvboxsync rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
a0a5ab4e085a7ee5b95bdfae04cec7de95792c3cvboxsync rc = Msg.cbData.GetUInt32(pcbDataTotal); AssertRC(rc);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertReturn(cbData >= *pcbDataTotal, VERR_TOO_MUCH_DATA);
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsyncstatic int vbglR3DnDHGProcessMoreDataMessageInternal(uint32_t uClientId,
9496f2d398b49813176939d7a339ae513d5175efvboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA;
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync rc = Msg.cbData.GetUInt32(pcbDataRecv); AssertRC(rc);
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);
9496f2d398b49813176939d7a339ae513d5175efvboxsyncstatic int vbglR3DnDHGProcessSendDataMessageLoop(uint32_t uClientId,
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync int rc = vbglR3DnDHGProcessDataMessageInternal(uClientId,
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false);
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync *ppvData = RTMemRealloc(*ppvData, cbAllDataRecv + cbData);
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync rc = vbglR3DnDHGProcessMoreDataMessageInternal(uClientId,
16a9adc14900ca18e6909679a579f6833425e030vboxsyncstatic int vbglR3DnDHGProcessSendDataMessage(uint32_t uClientId,
16a9adc14900ca18e6909679a579f6833425e030vboxsync int rc = vbglR3DnDHGProcessSendDataMessageLoop(uClientId,
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync /* Check if this is an URI event. If so, let VbglR3 do all the actual
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * data transfer + file/directory creation internally without letting
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync * the caller know.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * This keeps the actual (guest OS-)dependent client (like VBoxClient /
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync * VBoxTray) small by not having too much redundant code. */
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsyncstatic int vbglR3DnDGHProcessRequestPendingMessage(uint32_t uClientId,
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_REQ_PENDING;
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsyncstatic int vbglR3DnDGHProcessDroppedMessage(uint32_t uClientId,
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER);
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_EVT_DROPPED;
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync rc = Msg.uAction.GetUInt32(puAction); AssertRC(rc);
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync/******************************************************************************
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync * Public functions *
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync ******************************************************************************/
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsyncVBGLR3DECL(int) VbglR3DnDConnect(uint32_t *pu32ClientId)
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync AssertPtrReturn(pu32ClientId, VERR_INVALID_POINTER);
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync /* Initialize header */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Info.u32ClientID = UINT32_MAX; /* try make valgrind shut up. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Initialize parameter */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = RTStrCopy(Info.Loc.u.host.achName, sizeof(Info.Loc.u.host.achName), "VBoxDragAndDropSvc");
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync /* Do request */
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsyncVBGLR3DECL(int) VbglR3DnDDisconnect(uint32_t u32ClientId)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* Do request */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncVBGLR3DECL(int) VbglR3DnDProcessNextMessage(uint32_t u32ClientId, CPVBGLR3DNDHGCMEVENT pEvent)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync int rc = vbglR3DnDQueryNextHostMessageType(u32ClientId, &uMsg, &uNumParms,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync true /* fWait */);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync rc = vbglR3DnDHGProcessSendDataMessage(u32ClientId,
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync /* All messages in this case are handled internally
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * by vbglR3DnDHGProcessSendDataMessage() and must
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * be specified by a preceding HOST_DND_HG_SND_DATA call. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync rc = vbglR3DnDGHProcessRequestPendingMessage(u32ClientId,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncVBGLR3DECL(int) VbglR3DnDHGAcknowledgeOperation(uint32_t u32ClientId, uint32_t uAction)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_ACK_OP;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncVBGLR3DECL(int) VbglR3DnDHGRequestData(uint32_t u32ClientId, const char* pcszFormat)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync AssertPtrReturn(pcszFormat, VERR_INVALID_PARAMETER);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_REQ_DATA;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Msg.pFormat.SetPtr((void*)pcszFormat, (uint32_t)strlen(pcszFormat) + 1);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
59a2c1c0a4a0762b46bc5ff056f5705ec9c0a660vboxsyncVBGLR3DECL(int) VbglR3DnDGHAcknowledgePending(uint32_t u32ClientId,
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync AssertPtrReturn(pcszFormats, VERR_INVALID_POINTER);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_ACK_PENDING;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Msg.pFormat.SetPtr((void*)pcszFormats, (uint32_t)strlen(pcszFormats) + 1);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncstatic int vbglR3DnDGHSendDataInternal(uint32_t u32ClientId,
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DATA;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Total amount of bytes to send (including this data block). */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Msg.cbTotalBytes.SetUInt32(cbData + cbAdditionalData);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync uint32_t cbMaxChunk = _64K; /** @todo Transfer max. 64K chunks per message. Configurable? */
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync uint32_t cbCurChunk = RT_MIN(cbData - cbSent, cbMaxChunk);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync Msg.pvData.SetPtr(static_cast<uint8_t*>(pvData) + cbSent, cbCurChunk);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync LogFlowFunc(("Returning rc=%Rrc, cbData=%RU32, cbAddtionalData=%RU32, cbSent=%RU32\n",
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncstatic int vbglR3DnDGHSendDir(uint32_t u32ClientId, DnDURIObject &obj)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync AssertReturn(obj.GetType() == DnDURIObject::Directory, VERR_INVALID_PARAMETER);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DIR;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync strPath.c_str(), strPath.length(), obj.GetMode()));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync Msg.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync Msg.cbName.SetUInt32((uint32_t)(strPath.length() + 1));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsyncstatic int vbglR3DnDGHSendFile(uint32_t u32ClientId, DnDURIObject &obj)
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync AssertReturn(obj.GetType() == DnDURIObject::File, VERR_INVALID_PARAMETER);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync uint32_t cbBuf = _64K; /** @todo Make this configurable? */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_FILE;
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync strPath.c_str(), strPath.length(), obj.GetMode()));
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync Msg.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1));
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync Msg.cbName.SetUInt32((uint32_t)(strPath.length() + 1));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
30c39307775310ba50de9d9b74f1ea9e12524102vboxsyncstatic int vbglR3DnDGHSendURIObject(uint32_t u32ClientId, DnDURIObject &obj)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncstatic int vbglR3DnDGHProcessURIMessages(uint32_t u32ClientId,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync RTCString((const char *)pvData, cbData).split("\r\n");
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync int rc = lstURI.AppendNativePathsFromList(lstPaths, 0 /* fFlags */);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* Send metadata; in this case it's the (non-recursive) file/directory
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * URI list the host needs to know to initialize the drag'n drop operation. */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync uint32_t cbToSend = (uint32_t)strRootDest.length() + 1;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = vbglR3DnDGHSendDataInternal(u32ClientId, pvToSend, cbToSend,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* Include total bytes of all file paths,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * file sizes etc. */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = vbglR3DnDGHSendURIObject(u32ClientId, nextObj);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncVBGLR3DECL(int) VbglR3DnDGHSendData(uint32_t u32ClientId,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (DnDMIMEHasFileURLs(pszFormat, strlen(pszFormat)))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = vbglR3DnDGHProcessURIMessages(u32ClientId, pvData, cbData);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = vbglR3DnDGHSendDataInternal(u32ClientId, pvData, cbData,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync 0 /* cbAdditionalData */);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncVBGLR3DECL(int) VbglR3DnDGHSendError(uint32_t u32ClientId, int rcErr)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_EVT_ERROR;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync Msg.uRC.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
b0b15690f00527424b2d5fb88456d747252322f7vboxsync LogFlowFunc(("Sending error %Rrc returned with rc=%Rrc\n", rcErr, rc));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync#endif /* VBOX_WITH_DRAG_AND_DROP_GH */