int suplibOsPageAlloc(PSUPLIBDATA pThis, size_t cPages, void **ppvPages) { NOREF(pThis); *ppvPages = RTMemPageAllocZ(cPages << PAGE_SHIFT); if (*ppvPages) return VINF_SUCCESS; return RTErrConvertFromErrno(errno); }
/** * Allocate memory for host buffer and receive it. * * @param u32ClientId Host connection. * @param fFormat Buffer data format. * @param pData Where to store received data. * @param cbDataSize The size of the received data. * @param cbMemSize The actual size of memory occupied by *pData. * * @returns IPRT status code. */ static int vbclClipboardReadHostData(uint32_t u32ClientId, uint32_t fFormat, void **pData, uint32_t *cbDataSize, uint32_t *cbMemSize) { int rc; AssertReturn(pData && cbDataSize && cbMemSize, VERR_INVALID_PARAMETER); uint32_t cbDataSizeInternal = _4K; uint32_t cbMemSizeInternal = cbDataSizeInternal; void *pDataInternal = RTMemPageAllocZ(cbDataSizeInternal); if (!pDataInternal) return VERR_NO_MEMORY; rc = VbglR3ClipboardReadData(u32ClientId, fFormat, pDataInternal, cbMemSizeInternal, &cbDataSizeInternal); if (rc == VINF_BUFFER_OVERFLOW) { /* Reallocate bigger buffer and receive all the data */ RTMemPageFree(pDataInternal, cbMemSizeInternal); cbDataSizeInternal = cbMemSizeInternal = RT_ALIGN_32(cbDataSizeInternal, PAGE_SIZE); pDataInternal = RTMemPageAllocZ(cbMemSizeInternal); if (!pDataInternal) return VERR_NO_MEMORY; rc = VbglR3ClipboardReadData(u32ClientId, fFormat, pDataInternal, cbMemSizeInternal, &cbDataSizeInternal); } /* Error occurred of zero-sized buffer */ if (RT_FAILURE(rc)) { RTMemPageFree(pDataInternal, cbMemSizeInternal); return VERR_NO_MEMORY; } *pData = pDataInternal; *cbDataSize = cbDataSizeInternal; *cbMemSize = cbMemSizeInternal; return rc; }
/** * Search for content of specified type in guest clipboard buffer and put * it into newly allocated buffer. * * @param pPasteboard Guest PasteBoard reference. * @param fFormat Data formats we are looking for. * @param ppvData Where to return pointer to the received data. M * @param pcbData Where to return the size of the data. * @param pcbAlloc Where to return the size of the memory block * *ppvData pointes to. (Usually greater than *cbData * because the allocation is page aligned.) * @returns IPRT status code. */ static int vbclClipboardReadGuestData(PasteboardRef pPasteboard, CFStringRef sFormat, void **ppvData, uint32_t *pcbData, uint32_t *pcbAlloc) { ItemCount cItems, iItem; OSStatus rc; void *pvData = NULL; uint32_t cbData = 0; uint32_t cbAlloc = 0; AssertPtrReturn(ppvData, VERR_INVALID_POINTER); AssertPtrReturn(pcbData, VERR_INVALID_POINTER); AssertPtrReturn(pcbAlloc, VERR_INVALID_POINTER); rc = PasteboardGetItemCount(pPasteboard, &cItems); AssertReturn(rc == noErr, VERR_INVALID_PARAMETER); AssertReturn(cItems > 0, VERR_INVALID_PARAMETER); /* Walk through all the items in PasteBoard in order to find that one that correcponds to requested data format. */ for (iItem = 1; iItem <= cItems; iItem++) { PasteboardItemID iItemID; CFDataRef flavorData; /* Now, get the item's flavors that corresponds to requested type. */ rc = PasteboardGetItemIdentifier(pPasteboard, iItem, &iItemID); AssertReturn(rc == noErr, VERR_INVALID_PARAMETER); rc = PasteboardCopyItemFlavorData(pPasteboard, iItemID, sFormat, &flavorData); if (rc == noErr) { void *flavorDataPtr = (void *)CFDataGetBytePtr(flavorData); cbData = CFDataGetLength(flavorData); if (flavorDataPtr && cbData > 0) { cbAlloc = RT_ALIGN_32(cbData, PAGE_SIZE); pvData = RTMemPageAllocZ(cbAlloc); if (pvData) memcpy(pvData, flavorDataPtr, cbData); } CFRelease(flavorData); /* Found first matching item, no more search. */ break; } } /* Found match */ if (pvData) { *ppvData = pvData; *pcbData = cbData; *pcbAlloc = cbAlloc; return VINF_SUCCESS; } return VERR_INVALID_PARAMETER; }