/** * 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; }
/** * 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; }
/** * 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; }