static int vboxHwBufferWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const void *p, uint32_t cb) { VBVARECORD *pRecord; uint32_t cbHwBufferAvail; uint32_t cbWritten = 0; VBVABUFFER *pVBVA = pVbva->pVBVA; Assert(pVBVA); if (!pVBVA || pVbva->fHwBufferOverflow) { return VERR_INVALID_STATE; } Assert (pVBVA->indexRecordFirst != pVBVA->indexRecordFree); pRecord = pVbva->pRecord; Assert (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL)); // LOGF(("VW %d", cb)); cbHwBufferAvail = vboxHwBufferAvail (pVBVA); while (cb > 0) { uint32_t cbChunk = cb; // LOG(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n", // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten)); if (cbChunk >= cbHwBufferAvail) { LOG(("1) avail %d, chunk %d", cbHwBufferAvail, cbChunk)); vboxHwBufferFlush (pDevExt, pVbva); cbHwBufferAvail = vboxHwBufferAvail (pVBVA); if (cbChunk >= cbHwBufferAvail) { LOG(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.", cb, cbHwBufferAvail)); if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold) { LOGREL(("Buffer overflow!!!")); pVbva->fHwBufferOverflow = TRUE; Assert(FALSE); return VERR_NO_MEMORY; } cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold; } } Assert(cbChunk <= cb); Assert(cbChunk <= vboxHwBufferAvail (pVBVA)); vboxHwBufferPlaceDataAt (pVbva->pVBVA, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free); pVBVA->off32Free = (pVBVA->off32Free + cbChunk) % pVBVA->cbData; pRecord->cbRecord += cbChunk; cbHwBufferAvail -= cbChunk; cb -= cbChunk; cbWritten += cbChunk; } return VINF_SUCCESS; }
static bool vboxHwBufferWrite(PVBVABUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, const void *p, uint32_t cb) { VBVARECORD *pRecord; uint32_t cbHwBufferAvail; uint32_t cbWritten = 0; VBVABUFFER *pVBVA = pCtx->pVBVA; Assert(pVBVA); if (!pVBVA || pCtx->fHwBufferOverflow) { return false; } Assert(pVBVA->indexRecordFirst != pVBVA->indexRecordFree); pRecord = pCtx->pRecord; Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL)); // LogFunc(("%d\n", cb)); cbHwBufferAvail = vboxHwBufferAvail (pVBVA); while (cb > 0) { uint32_t cbChunk = cb; // LogFunc(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n", // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten)); if (cbChunk >= cbHwBufferAvail) { LogFunc(("1) avail %d, chunk %d\n", cbHwBufferAvail, cbChunk)); vboxHwBufferFlush (pHGSMICtx); cbHwBufferAvail = vboxHwBufferAvail (pVBVA); if (cbChunk >= cbHwBufferAvail) { LogFunc(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.\n", cb, cbHwBufferAvail)); if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold) { LogFunc(("Buffer overflow!!!\n")); pCtx->fHwBufferOverflow = true; Assert(false); return false; } cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold; } } Assert(cbChunk <= cb); Assert(cbChunk <= vboxHwBufferAvail (pVBVA)); vboxHwBufferPlaceDataAt (pCtx, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free); pVBVA->off32Free = (pVBVA->off32Free + cbChunk) % pVBVA->cbData; pRecord->cbRecord += cbChunk; cbHwBufferAvail -= cbChunk; cb -= cbChunk; cbWritten += cbChunk; } return true; }