int vbglR3GRPerform(VMMDevRequestHeader *pReq) { PVBGLREQHDR pReqHdr = (PVBGLREQHDR)pReq; uint32_t const cbReq = pReqHdr->cbIn; Assert(pReqHdr->cbOut == 0 || pReqHdr->cbOut == cbReq); pReqHdr->cbOut = cbReq; if (pReq->size < _1K) return vbglR3DoIOCtl(VBGL_IOCTL_VMMDEV_REQUEST(cbReq), pReqHdr, cbReq); return vbglR3DoIOCtl(VBGL_IOCTL_VMMDEV_REQUEST_BIG, pReqHdr, cbReq); }
/** * Wait for the host to signal one or more events and return which. * * The events will only be delivered by the host if they have been enabled * previously using @a VbglR3CtlFilterMask. If one or several of the events * have already been signalled but not yet waited for, this function will return * immediately and return those events. * * @returns IPRT status code. * * @param fMask The events we want to wait for, or-ed together. * @param cMillies How long to wait before giving up and returning * (VERR_TIMEOUT). Use RT_INDEFINITE_WAIT to wait until we * are interrupted or one of the events is signalled. * @param pfEvents Where to store the events signalled. Optional. */ VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents) { LogFlow(("VbglR3WaitEvent: fMask=0x%x, cMillies=%u, pfEvents=%p\n", fMask, cMillies, pfEvents)); AssertReturn((fMask & ~VMMDEV_EVENT_VALID_EVENT_MASK) == 0, VERR_INVALID_PARAMETER); AssertPtrNullReturn(pfEvents, VERR_INVALID_POINTER); VBoxGuestWaitEventInfo waitEvent; waitEvent.u32TimeoutIn = cMillies; waitEvent.u32EventMaskIn = fMask; waitEvent.u32Result = VBOXGUEST_WAITEVENT_ERROR; waitEvent.u32EventFlagsOut = 0; int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent)); if (RT_SUCCESS(rc)) { /* * If a guest requests for an event which is not available on the host side * (because of an older host version, a disabled feature or older Guest Additions), * don't trigger an assertion here even in debug builds - would be annoying. */ #if 0 AssertMsg(waitEvent.u32Result == VBOXGUEST_WAITEVENT_OK, ("%d rc=%Rrc\n", waitEvent.u32Result, rc)); #endif if (pfEvents) *pfEvents = waitEvent.u32EventFlagsOut; } LogFlow(("VbglR3WaitEvent: rc=%Rrc, u32EventFlagsOut=0x%x. u32Result=%d\n", rc, waitEvent.u32EventFlagsOut, waitEvent.u32Result)); return rc; }
VBGLR3DECL(int) VbglR3DnDConnect(uint32_t *pu32ClientId) { /* Validate input */ AssertPtrReturn(pu32ClientId, VERR_INVALID_POINTER); /* Initialize header */ VBoxGuestHGCMConnectInfo Info; RT_ZERO(Info.Loc.u); Info.result = VERR_WRONG_ORDER; Info.u32ClientID = UINT32_MAX; /* try make valgrind shut up. */ /* Initialize parameter */ Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing; int rc = RTStrCopy(Info.Loc.u.host.achName, sizeof(Info.Loc.u.host.achName), "VBoxDragAndDropSvc"); if (RT_FAILURE(rc)) return rc; /* Do request */ rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info)); if (RT_SUCCESS(rc)) { rc = Info.result; if (RT_SUCCESS(rc)) *pu32ClientId = Info.u32ClientID; } if (rc == VERR_HGCM_SERVICE_NOT_FOUND) rc = VINF_PERMISSION_DENIED; return rc; }
static int vbglR3DnDQueryNextHostMessageType(uint32_t uClientId, uint32_t *puMsg, uint32_t *pcParms, bool fWait) { /* Validate input */ AssertPtrReturn(puMsg, VERR_INVALID_POINTER); AssertPtrReturn(pcParms, VERR_INVALID_POINTER); /* Initialize header */ DragAndDropSvc::VBOXDNDNEXTMSGMSG Msg; RT_ZERO(Msg); Msg.hdr.result = VERR_WRONG_ORDER; Msg.hdr.u32ClientID = uClientId; Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG; Msg.hdr.cParms = 3; /* Initialize parameter */ Msg.msg.SetUInt32(0); Msg.num_parms.SetUInt32(0); Msg.block.SetUInt32(fWait); /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.hdr.result; if (RT_SUCCESS(rc)) { /* Fetch results */ rc = Msg.msg.GetUInt32(puMsg); AssertRC(rc); rc = Msg.num_parms.GetUInt32(pcParms); AssertRC(rc); } } return rc; }
/** * Get a host message. * * This will block until a message becomes available. * * @returns VBox status code. * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). * @param pMsg Where to store the message id. * @param pfFormats Where to store the format(s) the message applies to. */ VBGLR3DECL(int) VbglR3ClipboardGetHostMsg(uint32_t u32ClientId, uint32_t *pMsg, uint32_t *pfFormats) { VBoxClipboardGetHostMsg Msg; Msg.hdr.result = VERR_WRONG_ORDER; Msg.hdr.u32ClientID = u32ClientId; Msg.hdr.u32Function = VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG; Msg.hdr.cParms = 2; VbglHGCMParmUInt32Set(&Msg.msg, 0); VbglHGCMParmUInt32Set(&Msg.formats, 0); int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.hdr.result; if (RT_SUCCESS(rc)) { uint32_t u32Msg; rc = VbglHGCMParmUInt32Get(&Msg.msg, &u32Msg); if (RT_SUCCESS(rc)) { uint32_t fFormats; rc = VbglHGCMParmUInt32Get(&Msg.formats, &fFormats); if (RT_SUCCESS(rc)) { *pMsg = u32Msg; *pfFormats = fFormats; return Msg.hdr.result; } } } } return rc; }
VBGLR3DECL(int) VbglR3HostChannelRecv(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId, void *pvData, uint32_t cbData, uint32_t *pu32SizeReceived, uint32_t *pu32SizeRemaining) { VBoxHostChannelRecv parms; parms.hdr.result = VERR_WRONG_ORDER; parms.hdr.u32ClientID = u32HGCMClientId; parms.hdr.u32Function = VBOX_HOST_CHANNEL_FN_RECV; parms.hdr.cParms = 4; VbglHGCMParmUInt32Set(&parms.handle, u32ChannelHandle); VbglHGCMParmPtrSet(&parms.data, pvData, cbData); VbglHGCMParmUInt32Set(&parms.sizeReceived, 0); VbglHGCMParmUInt32Set(&parms.sizeRemaining, 0); int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(parms)), &parms, sizeof(parms)); if (RT_SUCCESS(rc)) { rc = parms.hdr.result; if (RT_SUCCESS(rc)) { *pu32SizeReceived = parms.sizeReceived.u.value32; *pu32SizeRemaining = parms.sizeRemaining.u.value32; } } return rc; }
VBGLR3DECL(int) VbglR3HostChannelEventWait(uint32_t *pu32ChannelHandle, uint32_t u32HGCMClientId, uint32_t *pu32EventId, void *pvParm, uint32_t cbParm, uint32_t *pu32SizeReturned) { VBoxHostChannelEventWait parms; parms.hdr.result = VERR_WRONG_ORDER; parms.hdr.u32ClientID = u32HGCMClientId; parms.hdr.u32Function = VBOX_HOST_CHANNEL_FN_EVENT_WAIT; parms.hdr.cParms = 4; VbglHGCMParmUInt32Set(&parms.handle, 0); VbglHGCMParmUInt32Set(&parms.id, 0); VbglHGCMParmPtrSet(&parms.parm, pvParm, cbParm); VbglHGCMParmUInt32Set(&parms.sizeReturned, 0); int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(parms)), &parms, sizeof(parms)); if (RT_SUCCESS(rc)) { rc = parms.hdr.result; if (RT_SUCCESS(rc)) { *pu32ChannelHandle = parms.handle.u.value32; *pu32EventId = parms.id.u.value32; *pu32SizeReturned = parms.sizeReturned.u.value32; } } return rc; }
static int vbglR3DnDHGProcessMoreDataMessageInternal(uint32_t uClientId, void *pvData, uint32_t cbData, uint32_t *pcbDataRecv) { /* Validate input */ AssertPtrReturn(pvData, VERR_INVALID_POINTER); AssertReturn(cbData, VERR_INVALID_PARAMETER); AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER); /* Initialize header */ DragAndDropSvc::VBOXDNDHGSENDMOREDATAMSG Msg; RT_ZERO(Msg); Msg.hdr.u32ClientID = g_clientId; Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA; Msg.hdr.cParms = 2; /* Initialize parameter */ Msg.pvData.SetPtr(pvData, cbData); Msg.cData.SetUInt32(0); /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.hdr.result; if ( RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW) { /* Fetch results */ rc = Msg.cData.GetUInt32(pcbDataRecv); AssertRC(rc); /* A little bit paranoia */ AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA); } } return rc; }
static int vbglR3DnDGHProcessRequestPendingMessage(uint32_t uClientId, uint32_t *puScreenId) { /* Validate input */ AssertPtrReturn(puScreenId, VERR_INVALID_POINTER); /* Initialize header */ DragAndDropSvc::VBOXDNDGHREQPENDINGMSG Msg; RT_ZERO(Msg); Msg.hdr.u32ClientID = uClientId; Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_REQ_PENDING; Msg.hdr.cParms = 1; /* Initialize parameter */ Msg.uScreenId.SetUInt32(0); /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.hdr.result; if (RT_SUCCESS(rc)) { /* Fetch results */ rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc); } } return rc; }
/** * Change the IRQ filter mask. * * @returns IPRT status code. * @param fOr The OR mask. * @param fNo The NOT mask. */ VBGLR3DECL(int) VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot) { VBoxGuestFilterMaskInfo Info; Info.u32OrMask = fOr; Info.u32NotMask = fNot; return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CTL_FILTER_MASK, &Info, sizeof(Info)); }
/** * Reads data from the host clipboard. * * @returns VBox status code. * @retval VINF_BUFFER_OVERFLOW If there is more data available than the caller provided buffer space for. * * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). * @param fFormat The format we're requesting the data in. * @param pv Where to store the data. * @param cb The size of the buffer pointed to by pv. * @param pcb The actual size of the host clipboard data. May be larger than cb. */ VBGLR3DECL(int) VbglR3ClipboardReadData(uint32_t u32ClientId, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcb) { VBoxClipboardReadData Msg; Msg.hdr.result = VERR_WRONG_ORDER; Msg.hdr.u32ClientID = u32ClientId; Msg.hdr.u32Function = VBOX_SHARED_CLIPBOARD_FN_READ_DATA; Msg.hdr.cParms = 3; VbglHGCMParmUInt32Set(&Msg.format, fFormat); VbglHGCMParmPtrSet(&Msg.ptr, pv, cb); VbglHGCMParmUInt32Set(&Msg.size, 0); int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.hdr.result; if (RT_SUCCESS(rc)) { uint32_t cbActual; rc = VbglHGCMParmUInt32Get(&Msg.size, &cbActual); if (RT_SUCCESS(rc)) { *pcb = cbActual; if (cbActual > cb) return VINF_BUFFER_OVERFLOW; return Msg.hdr.result; } } } return rc; }
/** * Write guest core dump. * * @returns IPRT status code. */ VBGLR3DECL(int) VbglR3WriteCoreDump(void) { VBGLIOCWRITECOREDUMP Req; VBGLREQHDR_INIT(&Req.Hdr, WRITE_CORE_DUMP); Req.u.In.fFlags = 0; return vbglR3DoIOCtl(VBGL_IOCTL_WRITE_CORE_DUMP, &Req.Hdr, sizeof(Req)); }
VBGLR3DECL(void) VbglR3HostChannelTerm(uint32_t u32HGCMClientId) { VBoxGuestHGCMDisconnectInfo disconnectInfo; disconnectInfo.result = VERR_WRONG_ORDER; disconnectInfo.u32ClientID = u32HGCMClientId; vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &disconnectInfo, sizeof(disconnectInfo)); }
/** * Report a change in the capabilities that we support to the host. * * @returns IPRT status code. * @param fOr Capabilities which have been added. * @param fNot Capabilities which have been removed. * * @todo Move to a different file. */ VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot) { VBoxGuestSetCapabilitiesInfo Info; Info.u32OrMask = fOr; Info.u32NotMask = fNot; return vbglR3DoIOCtl(VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES, &Info, sizeof(Info)); }
/** * Write to the backdoor logger from ring 3 guest code. * * @returns IPRT status code. * * @param pch The string to log. Does not need to be terminated. * @param cch The number of chars (bytes) to log. * * @remarks This currently does not accept more than 255 bytes of data at * one time. It should probably be rewritten to use pass a pointer * in the IOCtl. */ VBGLR3DECL(int) VbglR3WriteLog(const char *pch, size_t cch) { /* * Quietly skip NULL strings. * (Happens in the RTLogBackdoorPrintf case.) */ if (!cch) return VINF_SUCCESS; if (!VALID_PTR(pch)) return VERR_INVALID_POINTER; #ifdef RT_OS_WINDOWS /* * Duplicate the string as it may be read only (a C string). */ void *pvTmp = RTMemDup(pch, cch); if (!pvTmp) return VERR_NO_MEMORY; int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cch), pvTmp, cch); RTMemFree(pvTmp); return rc; #elif 0 /** @todo Several OSes could take this route (solaris and freebsd for instance). */ /* * Handle the entire request in one go. */ return vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cch), pvTmp, cch); #else /* * *BSD does not accept more than 4KB per ioctl request, while * Linux can't express sizes above 8KB, so, split it up into 2KB chunks. */ # define STEP 2048 int rc = VINF_SUCCESS; for (size_t off = 0; off < cch && RT_SUCCESS(rc); off += STEP) { size_t cbStep = RT_MIN(cch - off, STEP); rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cbStep), (char *)pch + off, cbStep); } # undef STEP return rc; #endif }
static int vbglR3DnDHGProcessActionMessage(uint32_t uClientId, uint32_t uMsg, uint32_t *puScreenId, uint32_t *puX, uint32_t *puY, uint32_t *puDefAction, uint32_t *puAllActions, char *pszFormats, uint32_t cbFormats, uint32_t *pcbFormatsRecv) { /* Validate input */ AssertPtrReturn(puScreenId, VERR_INVALID_POINTER); AssertPtrReturn(puX, VERR_INVALID_POINTER); AssertPtrReturn(puY, VERR_INVALID_POINTER); AssertPtrReturn(puDefAction, VERR_INVALID_POINTER); AssertPtrReturn(puAllActions, VERR_INVALID_POINTER); AssertPtrReturn(pszFormats, VERR_INVALID_POINTER); AssertReturn(cbFormats, VERR_INVALID_PARAMETER); AssertPtrReturn(pcbFormatsRecv, VERR_INVALID_POINTER); /* Initialize header */ DragAndDropSvc::VBOXDNDHGACTIONMSG Msg; RT_ZERO(Msg); Msg.hdr.u32ClientID = uClientId; Msg.hdr.u32Function = uMsg; Msg.hdr.cParms = 7; /* Initialize parameter */ Msg.uScreenId.SetUInt32(0); Msg.uX.SetUInt32(0); Msg.uY.SetUInt32(0); Msg.uDefAction.SetUInt32(0); Msg.uAllActions.SetUInt32(0); Msg.pvFormats.SetPtr(pszFormats, cbFormats); Msg.cFormats.SetUInt32(0); /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.hdr.result; if (RT_SUCCESS(rc)) { /* Fetch results */ rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc); rc = Msg.uX.GetUInt32(puX); AssertRC(rc); rc = Msg.uY.GetUInt32(puY); AssertRC(rc); rc = Msg.uDefAction.GetUInt32(puDefAction); AssertRC(rc); rc = Msg.uAllActions.GetUInt32(puAllActions); AssertRC(rc); rc = Msg.cFormats.GetUInt32(pcbFormatsRecv); AssertRC(rc); /* A little bit paranoia */ AssertReturn(cbFormats >= *pcbFormatsRecv, VERR_TOO_MUCH_DATA); } } return rc; }
/** * Disconnect from an HGCM service. * * @returns VBox status code. * @param idClient The client id returned by VbglR3InfoSvcConnect(). */ VBGLR3DECL(int) VbglR3HGCMDisconnect(HGCMCLIENTID idClient) { VBoxGuestHGCMDisconnectInfo Info; Info.result = VERR_WRONG_ORDER; Info.u32ClientID = idClient; int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info)); if (RT_SUCCESS(rc)) rc = Info.result; return rc; }
/** * Disconnect from the shared folder service. * * @returns VBox status code. * @param u32ClientId The client id returned by VbglR3InfoSvcConnect(). */ VBGLR3DECL(int) VbglR3SharedFolderDisconnect(uint32_t u32ClientId) { VBoxGuestHGCMDisconnectInfo Info; Info.result = VERR_WRONG_ORDER; Info.u32ClientID = u32ClientId; int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info)); if (RT_SUCCESS(rc)) rc = Info.result; return rc; }
VBGLR3DECL(int) VbglR3DnDDisconnect(uint32_t u32ClientId) { /* Initialize header */ VBoxGuestHGCMDisconnectInfo Info; Info.result = VERR_WRONG_ORDER; Info.u32ClientID = u32ClientId; /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info)); if (RT_SUCCESS(rc)) rc = Info.result; return rc; }
VBGLR3DECL(void) VbglR3HostChannelDetach(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId) { VBoxHostChannelDetach parms; parms.hdr.result = VERR_WRONG_ORDER; parms.hdr.u32ClientID = u32HGCMClientId; parms.hdr.u32Function = VBOX_HOST_CHANNEL_FN_DETACH; parms.hdr.cParms = 1; VbglHGCMParmUInt32Set(&parms.handle, u32ChannelHandle); vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(parms)), &parms, sizeof(parms)); }
static int vbglR3DnDHGProcessCancelMessage(uint32_t uClientId) { /* Initialize header */ DragAndDropSvc::VBOXDNDHGCANCELMSG Msg; RT_ZERO(Msg); Msg.hdr.u32ClientID = uClientId; Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_CANCEL; Msg.hdr.cParms = 0; /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) rc = Msg.hdr.result; return rc; }
VBGLR3DECL(int) VbglR3DnDGHSendData(void *pvData, uint32_t cbData) { DO(("DATA: %x (%u)\n", pvData, cbData)); /* Validate input */ AssertPtrReturn(pvData, VERR_INVALID_POINTER); AssertReturn(cbData, VERR_INVALID_PARAMETER); /* Todo: URI support. Currently only data is send over to the host. For URI * support basically the same as in the H->G case (see * HostServices/DragAndDrop/dndmanager.h/cpp) has to be done: * 1. Parse the urilist * 2. Recursively send "create dir" and "transfer file" msg to the host * 3. Patch the urilist by removing all base dirnames * 4. On the host all needs to received and the urilist patched afterwards * to point to the new location */ /* Initialize header */ DragAndDropSvc::VBOXDNDGHSENDDATAMSG Msg; RT_ZERO(Msg); Msg.hdr.result = VERR_WRONG_ORDER; Msg.hdr.u32ClientID = g_clientId; Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DATA; Msg.hdr.cParms = 2; Msg.uSize.SetUInt32(cbData); int rc = VINF_SUCCESS; uint32_t cbMax = _1M; uint32_t cbSend = 0; while(cbSend < cbData) { /* Initialize parameter */ uint32_t cbToSend = RT_MIN(cbData - cbSend, cbMax); Msg.pData.SetPtr(static_cast<uint8_t*>(pvData) + cbSend, cbToSend); /* Do request */ rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.hdr.result; /* Did the host cancel the event? */ if (rc == VERR_CANCELLED) break; } else break; cbSend += cbToSend; // RTThreadSleep(500); } return rc; }
/** * Send guest clipboard data to the host. * * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message * from the host. * * @returns VBox status code. * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). * @param fFormat The format of the data. * @param pv The data. * @param cb The size of the data. */ VBGLR3DECL(int) VbglR3ClipboardWriteData(uint32_t u32ClientId, uint32_t fFormat, void *pv, uint32_t cb) { VBoxClipboardWriteData Msg; Msg.hdr.result = VERR_WRONG_ORDER; Msg.hdr.u32ClientID = u32ClientId; Msg.hdr.u32Function = VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA; Msg.hdr.cParms = 2; VbglHGCMParmUInt32Set(&Msg.format, fFormat); VbglHGCMParmPtrSet(&Msg.ptr, pv, cb); int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) rc = Msg.hdr.result; return rc; }
/** * Advertises guest clipboard formats to the host. * * @returns VBox status code. * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). * @param fFormats The formats to advertise. */ VBGLR3DECL(int) VbglR3ClipboardReportFormats(uint32_t u32ClientId, uint32_t fFormats) { VBoxClipboardFormats Msg; Msg.hdr.result = VERR_WRONG_ORDER; Msg.hdr.u32ClientID = u32ClientId; Msg.hdr.u32Function = VBOX_SHARED_CLIPBOARD_FN_FORMATS; Msg.hdr.cParms = 1; VbglHGCMParmUInt32Set(&Msg.formats, fFormats); int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) rc = Msg.hdr.result; return rc; }
static int vbglR3DnDHGProcessSendFileMessage(uint32_t uClientId, char *pszFilename, uint32_t cbFilename, uint32_t *pcbFilenameRecv, void *pvData, uint32_t cbData, uint32_t *pcbDataRecv, uint32_t *pfMode) { /* Validate input */ AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); AssertReturn(cbFilename, VERR_INVALID_PARAMETER); AssertPtrReturn(pcbFilenameRecv, VERR_INVALID_POINTER); AssertPtrReturn(pvData, VERR_INVALID_POINTER); AssertReturn(cbData, VERR_INVALID_PARAMETER); AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER); AssertPtrReturn(pfMode, VERR_INVALID_POINTER); /* Initialize header */ DragAndDropSvc::VBOXDNDHGSENDFILEMSG Msg; RT_ZERO(Msg); Msg.hdr.u32ClientID = uClientId; Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_FILE; Msg.hdr.cParms = 5; /* Initialize parameter */ Msg.pvName.SetPtr(pszFilename, cbFilename); Msg.cName.SetUInt32(0); Msg.pvData.SetPtr(pvData, cbData); Msg.cData.SetUInt32(0); Msg.fMode.SetUInt32(0); /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.hdr.result; if (RT_SUCCESS(rc)) { /* Fetch results */ rc = Msg.cName.GetUInt32(pcbFilenameRecv); AssertRC(rc); rc = Msg.cData.GetUInt32(pcbDataRecv); AssertRC(rc); rc = Msg.fMode.GetUInt32(pfMode); AssertRC(rc); /* A little bit paranoia */ AssertReturn(cbFilename >= *pcbFilenameRecv, VERR_TOO_MUCH_DATA); AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA); } } return rc; }
VBGLR3DECL(int) VbglR3HostChannelQuery(const char *pszName, uint32_t u32HGCMClientId, uint32_t u32Code, void *pvParm, uint32_t cbParm, void *pvData, uint32_t cbData, uint32_t *pu32SizeDataReturned) { /* Make a heap copy of the name, because HGCM can not use some of other memory types. */ size_t cbName = strlen(pszName) + 1; char *pszCopy = (char *)RTMemAlloc(cbName); if (pszCopy == NULL) { return VERR_NO_MEMORY; } memcpy(pszCopy, pszName, cbName); VBoxHostChannelQuery parms; parms.hdr.result = VERR_WRONG_ORDER; parms.hdr.u32ClientID = u32HGCMClientId; parms.hdr.u32Function = VBOX_HOST_CHANNEL_FN_QUERY; parms.hdr.cParms = 5; VbglHGCMParmPtrSet(&parms.name, pszCopy, (uint32_t)cbName); VbglHGCMParmUInt32Set(&parms.code, u32Code); VbglHGCMParmPtrSet(&parms.parm, pvParm, cbParm); VbglHGCMParmPtrSet(&parms.data, pvData, cbData); VbglHGCMParmUInt32Set(&parms.sizeDataReturned, 0); int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(parms)), &parms, sizeof(parms)); if (RT_SUCCESS(rc)) { rc = parms.hdr.result; if (RT_SUCCESS(rc)) { *pu32SizeDataReturned = parms.sizeDataReturned.u.value32; } } RTMemFree(pszCopy); return rc; }
VBGLR3DECL(int) VbglR3DnDHGAcknowledgeOperation(uint32_t uAction) { DO(("ACK: %u\n", uAction)); /* Initialize header */ DragAndDropSvc::VBOXDNDHGACKOPMSG Msg; RT_ZERO(Msg); Msg.hdr.result = VERR_WRONG_ORDER; Msg.hdr.u32ClientID = g_clientId; Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_ACK_OP; Msg.hdr.cParms = 1; /* Initialize parameter */ Msg.uAction.SetUInt32(uAction); /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) rc = Msg.hdr.result; return rc; }
/** * Connects to the shared folder service. * * @returns VBox status code * @param pu32ClientId Where to put the client id on success. The client id * must be passed to all the other calls to the service. */ VBGLR3DECL(int) VbglR3SharedFolderConnect(uint32_t *pu32ClientId) { VBoxGuestHGCMConnectInfo Info; Info.result = VERR_WRONG_ORDER; Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing; RT_ZERO(Info.Loc.u); strcpy(Info.Loc.u.host.achName, "VBoxSharedFolders"); Info.u32ClientID = UINT32_MAX; /* try make valgrind shut up. */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info)); if (RT_SUCCESS(rc)) { rc = Info.result; if (RT_SUCCESS(rc)) *pu32ClientId = Info.u32ClientID; } return rc; }
VBGLR3DECL(int) VbglR3DnDGHErrorEvent(int rcOp) { DO(("GH_ERROR\n")); /* Initialize header */ DragAndDropSvc::VBOXDNDGHEVTERRORMSG Msg; RT_ZERO(Msg); Msg.hdr.result = VERR_WRONG_ORDER; Msg.hdr.u32ClientID = g_clientId; Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_EVT_ERROR; Msg.hdr.cParms = 1; /* Initialize parameter */ Msg.uRC.SetUInt32(rcOp); /* Do request */ int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) rc = Msg.hdr.result; return rc; }
VBGLR3DECL(int) VbglR3HostChannelEventCancel(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId) { VBoxHostChannelEventCancel parms; parms.hdr.result = VERR_WRONG_ORDER; parms.hdr.u32ClientID = u32HGCMClientId; parms.hdr.u32Function = VBOX_HOST_CHANNEL_FN_EVENT_CANCEL; parms.hdr.cParms = 0; int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(parms)), &parms, sizeof(parms)); if (RT_SUCCESS(rc)) { rc = parms.hdr.result; } return rc; }