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) 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; }
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; }
/** * 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; }
VBGLR3DECL(int) VbglR3HostChannelControl(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId, uint32_t u32Code, void *pvParm, uint32_t cbParm, void *pvData, uint32_t cbData, uint32_t *pu32SizeDataReturned) { VBoxHostChannelControl parms; parms.hdr.result = VERR_WRONG_ORDER; parms.hdr.u32ClientID = u32HGCMClientId; parms.hdr.u32Function = VBOX_HOST_CHANNEL_FN_CONTROL; parms.hdr.cParms = 5; VbglHGCMParmUInt32Set(&parms.handle, u32ChannelHandle); 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; } } 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; }
/** * Get the real name of a shared folder. * * @returns VBox status code. * @param u32ClientId The client id returned by VbglR3InvsSvcConnect(). * @param u32Root Root ID of shared folder to get the name for. * @param ppszName Where to return the name string. This shall be * freed by calling RTStrFree. */ VBGLR3DECL(int) VbglR3SharedFolderGetName(uint32_t u32ClientId, uint32_t u32Root, char **ppszName) { AssertPtr(ppszName); VBoxSFQueryMapName Msg; Msg.callInfo.result = VERR_WRONG_ORDER; Msg.callInfo.u32ClientID = u32ClientId; Msg.callInfo.u32Function = SHFL_FN_QUERY_MAP_NAME; Msg.callInfo.cParms = 2; int rc; uint32_t cbString = SHFLSTRING_HEADER_SIZE + SHFL_MAX_LEN; PSHFLSTRING pString = (PSHFLSTRING)RTMemAlloc(cbString); if (pString) { if (!ShflStringInitBuffer(pString, cbString)) { RTMemFree(pString); return VERR_INVALID_PARAMETER; } VbglHGCMParmUInt32Set(&Msg.root, u32Root); VbglHGCMParmPtrSet(&Msg.name, pString, cbString); rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.callInfo.result; if (RT_SUCCESS(rc)) { *ppszName = NULL; rc = RTUtf16ToUtf8(&pString->String.ucs2[0], ppszName); } } RTMemFree(pString); } else rc = VERR_INVALID_PARAMETER; return rc; }
VBGLR3DECL(int) VbglR3HostChannelAttach(uint32_t *pu32ChannelHandle, uint32_t u32HGCMClientId, const char *pszName, uint32_t u32Flags) { /* 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); VBoxHostChannelAttach parms; parms.hdr.result = VERR_WRONG_ORDER; parms.hdr.u32ClientID = u32HGCMClientId; parms.hdr.u32Function = VBOX_HOST_CHANNEL_FN_ATTACH; parms.hdr.cParms = 3; VbglHGCMParmPtrSet(&parms.name, pszCopy, (uint32_t)cbName); VbglHGCMParmUInt32Set(&parms.flags, u32Flags); VbglHGCMParmUInt32Set(&parms.handle, 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; } } RTMemFree(pszCopy); return rc; }
VBGLR3DECL(int) VbglR3HostChannelSend(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId, void *pvData, uint32_t cbData) { VBoxHostChannelSend parms; parms.hdr.result = VERR_WRONG_ORDER; parms.hdr.u32ClientID = u32HGCMClientId; parms.hdr.u32Function = VBOX_HOST_CHANNEL_FN_SEND; parms.hdr.cParms = 2; VbglHGCMParmUInt32Set(&parms.handle, u32ChannelHandle); VbglHGCMParmPtrSet(&parms.data, pvData, cbData); int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(parms)), &parms, sizeof(parms)); if (RT_SUCCESS(rc)) { rc = parms.hdr.result; } return rc; }
/** * Get the list of available shared folders. * * @returns VBox status code. * @param u32ClientId The client id returned by VbglR3SharedFolderConnect(). * @param fAutoMountOnly Flag whether only auto-mounted shared folders * should be reported. * @param ppaMappings Allocated array which will retrieve the mapping info. Needs * to be freed with VbglR3SharedFolderFreeMappings() later. * @param pcMappings The number of mappings returned in @a ppaMappings. */ VBGLR3DECL(int) VbglR3SharedFolderGetMappings(uint32_t u32ClientId, bool fAutoMountOnly, PVBGLR3SHAREDFOLDERMAPPING *ppaMappings, uint32_t *pcMappings) { AssertPtrReturn(pcMappings, VERR_INVALID_PARAMETER); AssertPtrReturn(ppaMappings, VERR_INVALID_PARAMETER); *pcMappings = 0; *ppaMappings = NULL; VBoxSFQueryMappings Msg; Msg.callInfo.result = VERR_WRONG_ORDER; Msg.callInfo.u32ClientID = u32ClientId; Msg.callInfo.u32Function = SHFL_FN_QUERY_MAPPINGS; Msg.callInfo.cParms = 3; /* Set the mapping flags. */ uint32_t u32Flags = 0; /** @todo SHFL_MF_UTF8 is not implemented yet. */ if (fAutoMountOnly) /* We only want the mappings which get auto-mounted. */ u32Flags |= SHFL_MF_AUTOMOUNT; VbglHGCMParmUInt32Set(&Msg.flags, u32Flags); /* * Prepare and get the actual mappings from the host service. */ int rc = VINF_SUCCESS; uint32_t cMappings = 8; /* Should be a good default value. */ uint32_t cbSize = cMappings * sizeof(VBGLR3SHAREDFOLDERMAPPING); VBGLR3SHAREDFOLDERMAPPING *ppaMappingsTemp = (PVBGLR3SHAREDFOLDERMAPPING)RTMemAllocZ(cbSize); if (!ppaMappingsTemp) return VERR_NO_MEMORY; do { VbglHGCMParmUInt32Set(&Msg.numberOfMappings, cMappings); VbglHGCMParmPtrSet(&Msg.mappings, ppaMappingsTemp, cbSize); rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.callInfo.result; if (RT_SUCCESS(rc)) { VbglHGCMParmUInt32Get(&Msg.numberOfMappings, pcMappings); /* Do we have more mappings than we have allocated space for? */ if (rc == VINF_BUFFER_OVERFLOW) { cMappings = *pcMappings; cbSize = cMappings * sizeof(VBGLR3SHAREDFOLDERMAPPING); void *pvNew = RTMemRealloc(ppaMappingsTemp, cbSize); AssertPtrBreakStmt(pvNew, rc = VERR_NO_MEMORY); ppaMappingsTemp = (PVBGLR3SHAREDFOLDERMAPPING)pvNew; } } } } while (rc == VINF_BUFFER_OVERFLOW); if ( RT_FAILURE(rc) || !*pcMappings) { RTMemFree(ppaMappingsTemp); ppaMappingsTemp = NULL; } /* In this case, just return success with 0 mappings */ if ( rc == VERR_INVALID_PARAMETER && fAutoMountOnly) rc = VINF_SUCCESS; *ppaMappings = ppaMappingsTemp; return rc; }