VBoxGuestR3LibDragAndDrop.cpp revision 63f24ac9931b0f1ccae2b11fdccd535ebca34c84
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Drag & Drop.
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * Copyright (C) 2011-2013 Oracle Corporation
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 * 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 * 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* Header Files *
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 * - 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 * Private internal functions *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync ******************************************************************************/
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDQueryNextHostMessageType(uint32_t uClientId, uint32_t *puMsg, uint32_t *pcParms, bool fWait)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.num_parms.GetUInt32(pcParms); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessActionMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puDefAction, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(puAllActions, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbFormatsRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); 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);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormats >= *pcbFormatsRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessLeaveMessage(uint32_t uClientId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_LEAVE;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessCancelMessage(uint32_t uClientId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_CANCEL;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessSendDirMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbDirnameRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DIR;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.cbName.GetUInt32(pcbDirnameRecv); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbDirname >= *pcbDirnameRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessSendFileMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbFilenameRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_FILE;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.cbName.GetUInt32(pcbFilenameRecv); AssertRC(rc);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.cbData.GetUInt32(pcbDataRecv); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFilename >= *pcbFilenameRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessURIMessages(uint32_t uClientId,
822e11c896dd36c9dc3609dff676059576b7d3devboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Allocate temp buffer. */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync uint32_t cbTmpData = _64K; /** @todo Make this configurable? */
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync /* Create and query the (unique) drop target directory. */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync int rc = DnDDirCreateDroppedFiles(pszDropDir, sizeof(pszDropDir));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Patch the old drop data with the new drop directory, so the drop target
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * can find the files. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = lstURI.RootFromURIData(*ppvData, *pcbDataRecv,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync 0 /* fFlags */);
822e11c896dd36c9dc3609dff676059576b7d3devboxsync /* Cleanup the old data and write the new data back to the event. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTCString strData = lstURI.RootToString(pszDropDir);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync *ppvData = RTStrDupN(strData.c_str(), strData.length());
82391de567696f10b21a762fde6a06fe3c266d28vboxsync /* Lists for holding created files & directories
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * in the case of a rollback. */
822e11c896dd36c9dc3609dff676059576b7d3devboxsync bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false /* fWait */);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowFunc(("HOST_DND_HG_SND_DIR pszPathName=%s, cbPathName=%RU32, fMode=0x%x, rc=%Rrc\n",
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = DnDPathSanitize(szPathName, sizeof(szPathName));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync char *pszNewDir = RTPathJoinA(pszDropDir, szPathName);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0);
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 rc = DnDPathSanitize(szPathName, sizeof(szPathName));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync char *pszPathAbs = RTPathJoinA(pszDropDir, szPathName);
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. */
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /** @todo r=andy Not very safe to assume that we were last appending to the current file. */
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync /* Valid UNIX mode? */
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowFunc(("Opening file failed with rc=%Rrc\n", rc));
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync /* Break out of the loop. */
822e11c896dd36c9dc3609dff676059576b7d3devboxsync } /* while */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Cleanup on failure or if the user has canceled. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Remove any stuff created. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessDataMessageInternal(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync AssertPtrReturn(pcbDataTotal, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DATA;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync rc = Msg.cbData.GetUInt32(pcbDataTotal); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync AssertReturn(cbData >= *pcbDataTotal, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessMoreDataMessageInternal(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = Msg.cbData.GetUInt32(pcbDataRecv); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncstatic int vbglR3DnDHGProcessSendDataMessageLoop(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DnDHGProcessDataMessageInternal(uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync *ppvData = RTMemRealloc(*ppvData, cbAllDataRecv + cbData);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DnDHGProcessMoreDataMessageInternal(uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDHGProcessSendDataMessage(uint32_t uClientId,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync int rc = vbglR3DnDHGProcessSendDataMessageLoop(uClientId,
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 * This keeps the actual (guest OS-)dependent client (like VBoxClient /
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync * VBoxTray) small by not having too much redundant code. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDGHProcessRequestPendingMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_REQ_PENDING;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int vbglR3DnDGHProcessDroppedMessage(uint32_t uClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcbFormatRecv, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_EVT_DROPPED;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = Msg.uAction.GetUInt32(puAction); AssertRC(rc);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/******************************************************************************
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Public functions *
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync ******************************************************************************/
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncVBGLR3DECL(int) VbglR3DnDConnect(uint32_t *pu32ClientId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pu32ClientId, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Initialize header */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Info.u32ClientID = UINT32_MAX; /* try make valgrind shut up. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Initialize parameter */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = RTStrCopy(Info.Loc.u.host.achName, sizeof(Info.Loc.u.host.achName), "VBoxDragAndDropSvc");
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Do request */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncVBGLR3DECL(int) VbglR3DnDDisconnect(uint32_t u32ClientId)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Do request */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncVBGLR3DECL(int) VbglR3DnDProcessNextMessage(uint32_t u32ClientId, CPVBGLR3DNDHGCMEVENT pEvent)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync int rc = vbglR3DnDQueryNextHostMessageType(u32ClientId, &uMsg, &uNumParms,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync true /* fWait */);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDHGProcessSendDataMessage(u32ClientId,
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. */
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync rc = vbglR3DnDGHProcessRequestPendingMessage(u32ClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncVBGLR3DECL(int) VbglR3DnDHGAcknowledgeOperation(uint32_t u32ClientId, uint32_t uAction)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_ACK_OP;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncVBGLR3DECL(int) VbglR3DnDHGRequestData(uint32_t u32ClientId, const char* pcszFormat)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertPtrReturn(pcszFormat, VERR_INVALID_PARAMETER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_REQ_DATA;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.pFormat.SetPtr((void*)pcszFormat, (uint32_t)strlen(pcszFormat) + 1);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsyncVBGLR3DECL(int) VbglR3DnDGHAcknowledgePending(uint32_t u32ClientId,
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync AssertPtrReturn(pcszFormats, VERR_INVALID_POINTER);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_ACK_PENDING;
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync Msg.pFormat.SetPtr((void*)pcszFormats, (uint32_t)strlen(pcszFormats) + 1);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHSendDataInternal(uint32_t u32ClientId,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DATA;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Total amount of bytes to send (including this data block). */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbTotalBytes.SetUInt32(cbData + cbAdditionalData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbMaxChunk = _64K; /* Transfer max. 64K chunks per message. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbCurChunk = RT_MIN(cbData - cbSent, cbMaxChunk);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.pvData.SetPtr(static_cast<uint8_t*>(pvData) + cbSent, cbCurChunk);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LogFlowFunc(("Returning rc=%Rrc, cbData=%RU32, cbAddtionalData=%RU32\n",
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHSendDir(uint32_t u32ClientId, DnDURIObject &obj)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertReturn(obj.GetType() == DnDURIObject::Directory, VERR_INVALID_PARAMETER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DIR;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync strPath.c_str(), strPath.length(), obj.GetMode()));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbName.SetUInt32((uint32_t)(strPath.length() + 1));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHSendFile(uint32_t u32ClientId, DnDURIObject &obj)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertReturn(obj.GetType() == DnDURIObject::File, VERR_INVALID_PARAMETER);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t cbBuf = _64K; /** @todo Make this configurable? */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_FILE;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync strPath.c_str(), strPath.length(), obj.GetMode()));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Msg.cbName.SetUInt32((uint32_t)(strPath.length() + 1));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHSendURIObject(uint32_t u32ClientId, DnDURIObject &obj)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic int vbglR3DnDGHProcessURIMessages(uint32_t u32ClientId,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync RTCString((const char *)pvData, cbData).split("\r\n");
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync int rc = lstURI.AppendNativePathsFromList(lstPaths, 0 /* fFlags */);
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 uint32_t cbToSend = (uint32_t)strRootDest.length() + 1;
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHSendDataInternal(u32ClientId, pvToSend, cbToSend,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Include total bytes of all file paths,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * file sizes etc. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHSendURIObject(u32ClientId, nextObj);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncVBGLR3DECL(int) VbglR3DnDGHSendData(uint32_t u32ClientId,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (DnDMIMEHasFileURLs(pszFormat, strlen(pszFormat)))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHProcessURIMessages(u32ClientId, pvData, cbData);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync rc = vbglR3DnDGHSendDataInternal(u32ClientId, pvData, cbData,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync 0 /* cbAdditionalData */);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsyncVBGLR3DECL(int) VbglR3DnDGHSendError(uint32_t u32ClientId, int rcErr)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_EVT_ERROR;
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync Msg.uRC.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync LogFlowFunc(("Sending error %Rrc returned with rc=%Rrc\n", rcErr, rc));
63f24ac9931b0f1ccae2b11fdccd535ebca34c84vboxsync#endif /* VBOX_WITH_DRAG_AND_DROP_GH */