- Timestamp:
- May 22, 2015 4:29:25 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
r55844 r56036 53 53 } VBVAPARTIALRECORD; 54 54 55 typedef struct VBVADATA 56 { 57 struct 58 { 59 VBVABUFFER *pVBVA; /* Pointer to the guest memory with the VBVABUFFER. */ 60 uint8_t *pu8Data; /* For convenience, pointer to the guest ring buffer (VBVABUFFER::au8Data). */ 61 } guest; 62 uint32_t u32VBVAOffset; /* VBVABUFFER offset in the guest VRAM. */ 63 VBVAPARTIALRECORD partialRecord; /* Partial record temporary storage. */ 64 uint32_t off32Data; /* The offset where the data starts in the VBVABUFFER. 65 * The host code uses it instead of VBVABUFFER::off32Data. 66 */ 67 uint32_t indexRecordFirst; /* Index of the first filled record in VBVABUFFER::aRecords. */ 68 uint32_t cbPartialWriteThreshold; /* Copy of VBVABUFFER::cbPartialWriteThreshold used by host code. */ 69 uint32_t cbData; /* Copy of VBVABUFFER::cbData used by host code. */ 70 } VBVADATA; 71 55 72 typedef struct VBVAVIEW 56 73 { 57 74 VBVAINFOVIEW view; 58 75 VBVAINFOSCREEN screen; 59 VBVABUFFER *pVBVA; 60 uint32_t u32VBVAOffset; 61 VBVAPARTIALRECORD partialRecord; 76 VBVADATA vbva; 62 77 } VBVAVIEW; 63 78 … … 80 95 { 81 96 uint32_t cViews; 82 VBVAVIEW aViews[ 64 /* @todo SchemaDefs::MaxGuestMonitors*/];97 VBVAVIEW aViews[VBOX_VIDEO_MAX_SCREENS]; 83 98 VBVAMOUSESHAPEINFO mouseShapeInfo; 84 99 bool fPaused; … … 89 104 90 105 106 static void vbvaDataCleanup(VBVADATA *pVBVAData) 107 { 108 if (pVBVAData->guest.pVBVA) 109 { 110 RT_ZERO(pVBVAData->guest.pVBVA->hostFlags); 111 } 112 113 RTMemFree(pVBVAData->partialRecord.pu8); 114 115 RT_ZERO(*pVBVAData); 116 pVBVAData->u32VBVAOffset = HGSMIOFFSET_VOID; 117 } 91 118 92 119 /** Copies @a cb bytes from the VBVA ring buffer to the @a pu8Dst. 93 120 * Used for partial records or for records which cross the ring boundary. 94 121 */ 95 static void vbvaFetchBytes (VBVABUFFER *pVBVA, uint8_t *pu8Dst, uint32_t cb) 96 { 97 /** @todo replace the 'if' with an assert. The caller must ensure this condition. */ 98 if (cb >= pVBVA->cbData) 99 { 100 AssertMsgFailed (("cb = 0x%08X, ring buffer size 0x%08X", cb, pVBVA->cbData)); 101 return; 102 } 103 104 const uint32_t u32BytesTillBoundary = pVBVA->cbData - pVBVA->off32Data; 105 const uint8_t *src = &pVBVA->au8Data[pVBVA->off32Data]; 122 static bool vbvaFetchBytes(VBVADATA *pVBVAData, uint8_t *pu8Dst, uint32_t cb) 123 { 124 if (cb >= pVBVAData->cbData) 125 { 126 AssertMsgFailed(("cb = 0x%08X, ring buffer size 0x%08X", cb, pVBVAData->cbData)); 127 return false; 128 } 129 130 const uint32_t u32BytesTillBoundary = pVBVAData->cbData - pVBVAData->off32Data; 131 const uint8_t *pu8Src = &pVBVAData->guest.pu8Data[pVBVAData->off32Data]; 106 132 const int32_t i32Diff = cb - u32BytesTillBoundary; 107 133 … … 109 135 { 110 136 /* Chunk will not cross buffer boundary. */ 111 memcpy (pu8Dst, src, cb);137 memcpy(pu8Dst, pu8Src, cb); 112 138 } 113 139 else 114 140 { 115 141 /* Chunk crosses buffer boundary. */ 116 memcpy (pu8Dst, src, u32BytesTillBoundary); 117 memcpy (pu8Dst + u32BytesTillBoundary, &pVBVA->au8Data[0], i32Diff); 118 } 119 120 /* Advance data offset. */ 121 pVBVA->off32Data = (pVBVA->off32Data + cb) % pVBVA->cbData; 122 123 return; 124 } 125 126 127 static bool vbvaPartialRead (VBVAPARTIALRECORD *pPartialRecord, uint32_t cbRecord, VBVABUFFER *pVBVA) 128 { 142 memcpy(pu8Dst, pu8Src, u32BytesTillBoundary); 143 memcpy(pu8Dst + u32BytesTillBoundary, &pVBVAData->guest.pu8Data[0], i32Diff); 144 } 145 146 /* Advance data offset and sync with guest. */ 147 pVBVAData->off32Data = (pVBVAData->off32Data + cb) % pVBVAData->cbData; 148 pVBVAData->guest.pVBVA->off32Data = pVBVAData->off32Data; 149 return true; 150 } 151 152 153 static bool vbvaPartialRead(uint32_t cbRecord, VBVADATA *pVBVAData) 154 { 155 VBVAPARTIALRECORD *pPartialRecord = &pVBVAData->partialRecord; 129 156 uint8_t *pu8New; 130 157 … … 132 159 pPartialRecord->pu8, pPartialRecord->cb, cbRecord)); 133 160 161 Assert(cbRecord > pPartialRecord->cb); /* Caller ensures this. */ 162 163 const uint32_t cbChunk = cbRecord - pPartialRecord->cb; 164 if (cbChunk >= pVBVAData->cbData) 165 { 166 return false; 167 } 168 134 169 if (pPartialRecord->pu8) 135 170 { 136 Assert 137 pu8New = (uint8_t *)RTMemRealloc 171 Assert(pPartialRecord->cb); 172 pu8New = (uint8_t *)RTMemRealloc(pPartialRecord->pu8, cbRecord); 138 173 } 139 174 else 140 175 { 141 Assert 142 pu8New = (uint8_t *)RTMemAlloc 176 Assert(!pPartialRecord->cb); 177 pu8New = (uint8_t *)RTMemAlloc(cbRecord); 143 178 } 144 179 … … 149 184 cbRecord)); 150 185 151 if (pPartialRecord->pu8)152 {153 RTMemFree (pPartialRecord->pu8);154 }155 156 pPartialRecord->pu8 = NULL;157 pPartialRecord->cb = 0;158 159 186 return false; 160 187 } 161 188 162 189 /* Fetch data from the ring buffer. */ 163 vbvaFetchBytes (pVBVA, pu8New + pPartialRecord->cb, cbRecord - pPartialRecord->cb); 190 if (!vbvaFetchBytes(pVBVAData, pu8New + pPartialRecord->cb, cbChunk)) 191 { 192 return false; 193 } 164 194 165 195 pPartialRecord->pu8 = pu8New; … … 172 202 * For crossing boundary - allocate a buffer from heap. 173 203 */ 174 static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA, VBVACMDHDR **ppHdr, uint32_t *pcbCmd) 175 { 176 uint32_t indexRecordFirst = pVBVA->indexRecordFirst; 177 uint32_t indexRecordFree = pVBVA->indexRecordFree; 204 static bool vbvaFetchCmd(VBVADATA *pVBVAData, VBVACMDHDR **ppHdr, uint32_t *pcbCmd) 205 { 206 VBVAPARTIALRECORD *pPartialRecord = &pVBVAData->partialRecord; 207 uint32_t indexRecordFirst = pVBVAData->indexRecordFirst; 208 const uint32_t indexRecordFree = ASMAtomicReadU32(&pVBVAData->guest.pVBVA->indexRecordFree); 178 209 179 210 LOGVBVABUFFER(("first = %d, free = %d\n", 180 211 indexRecordFirst, indexRecordFree)); 181 212 213 if (indexRecordFree >= RT_ELEMENTS(pVBVAData->guest.pVBVA->aRecords)) 214 { 215 return false; 216 } 217 182 218 if (indexRecordFirst == indexRecordFree) 183 219 { … … 186 222 } 187 223 188 uint32_t cbRecordCurrent = ASMAtomicReadU32(&pVBVA ->aRecords[indexRecordFirst].cbRecord);224 uint32_t cbRecordCurrent = ASMAtomicReadU32(&pVBVAData->guest.pVBVA->aRecords[indexRecordFirst].cbRecord); 189 225 190 226 LOGVBVABUFFER(("cbRecord = 0x%08X, pPartialRecord->cb = 0x%08X\n", cbRecordCurrent, pPartialRecord->cb)); 191 227 192 228 uint32_t cbRecord = cbRecordCurrent & ~VBVA_F_RECORD_PARTIAL; 229 230 if (cbRecord > VBVA_MAX_RECORD_SIZE) 231 { 232 return false; 233 } 193 234 194 235 if (pPartialRecord->cb) … … 203 244 { 204 245 /* New data has been added to the record. */ 205 if (!vbvaPartialRead (pPartialRecord, cbRecord, pVBVA))246 if (!vbvaPartialRead(cbRecord, pVBVAData)) 206 247 { 207 248 return false; … … 218 259 pPartialRecord->cb = 0; 219 260 220 /* Advance the record index. */ 221 pVBVA->indexRecordFirst = (indexRecordFirst + 1) % RT_ELEMENTS(pVBVA->aRecords); 261 /* Advance the record index and sync with guest. */ 262 pVBVAData->indexRecordFirst = (indexRecordFirst + 1) % RT_ELEMENTS(pVBVAData->guest.pVBVA->aRecords); 263 pVBVAData->guest.pVBVA->indexRecordFirst = pVBVAData->indexRecordFirst; 222 264 223 265 LOGVBVABUFFER(("partial done ok, data = %d, free = %d\n", 224 pVBVA ->off32Data,pVBVA->off32Free));266 pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free)); 225 267 } 226 268 … … 236 278 * be accumulated in an allocated buffer. 237 279 */ 238 if (cbRecord >= pVBVA ->cbData - pVBVA->cbPartialWriteThreshold)280 if (cbRecord >= pVBVAData->cbData - pVBVAData->cbPartialWriteThreshold) 239 281 { 240 282 /* Partial read must be started. */ 241 if (!vbvaPartialRead (pPartialRecord, cbRecord, pVBVA))283 if (!vbvaPartialRead(cbRecord, pVBVAData)) 242 284 { 243 285 return false; … … 252 294 253 295 /* Current record is complete. If it is not empty, process it. */ 296 if (cbRecord >= pVBVAData->cbData) 297 { 298 return false; 299 } 300 254 301 if (cbRecord) 255 302 { 256 /* The size of largest contiguous chunk in the ring b iffer. */257 uint32_t u32BytesTillBoundary = pVBVA ->cbData - pVBVA->off32Data;303 /* The size of largest contiguous chunk in the ring buffer. */ 304 uint32_t u32BytesTillBoundary = pVBVAData->cbData - pVBVAData->off32Data; 258 305 259 306 /* The pointer to data in the ring buffer. */ 260 uint8_t * src = &pVBVA->au8Data[pVBVA->off32Data];307 uint8_t *pu8Src = &pVBVAData->guest.pu8Data[pVBVAData->off32Data]; 261 308 262 309 /* Fetch or point the data. */ … … 264 311 { 265 312 /* The command does not cross buffer boundary. Return address in the buffer. */ 266 *ppHdr = (VBVACMDHDR *)src; 267 268 /* Advance data offset. */ 269 pVBVA->off32Data = (pVBVA->off32Data + cbRecord) % pVBVA->cbData; 313 *ppHdr = (VBVACMDHDR *)pu8Src; 314 315 /* Advance data offset and sync with guest. */ 316 pVBVAData->off32Data = (pVBVAData->off32Data + cbRecord) % pVBVAData->cbData; 317 pVBVAData->guest.pVBVA->off32Data = pVBVAData->off32Data; 270 318 } 271 319 else 272 320 { 273 321 /* The command crosses buffer boundary. Rare case, so not optimized. */ 274 uint8_t * dst = (uint8_t *)RTMemAlloc(cbRecord);275 276 if (! dst)322 uint8_t *pu8Dst = (uint8_t *)RTMemAlloc(cbRecord); 323 324 if (!pu8Dst) 277 325 { 278 326 LogFlowFunc (("could not allocate %d bytes from heap!!!\n", cbRecord)); 279 pVBVA->off32Data = (pVBVA->off32Data + cbRecord) % pVBVA->cbData;280 327 return false; 281 328 } 282 329 283 vbvaFetchBytes (pVBVA, dst, cbRecord);284 285 *ppHdr = (VBVACMDHDR *) dst;286 287 LOGVBVABUFFER(("Allocated from heap %p\n", dst));330 vbvaFetchBytes(pVBVAData, pu8Dst, cbRecord); 331 332 *ppHdr = (VBVACMDHDR *)pu8Dst; 333 334 LOGVBVABUFFER(("Allocated from heap %p\n", pu8Dst)); 288 335 } 289 336 } … … 291 338 *pcbCmd = cbRecord; 292 339 293 /* Advance the record index. */ 294 pVBVA->indexRecordFirst = (indexRecordFirst + 1) % RT_ELEMENTS(pVBVA->aRecords); 340 /* Advance the record index and sync with guest. */ 341 pVBVAData->indexRecordFirst = (indexRecordFirst + 1) % RT_ELEMENTS(pVBVAData->guest.pVBVA->aRecords); 342 pVBVAData->guest.pVBVA->indexRecordFirst = pVBVAData->indexRecordFirst; 295 343 296 344 LOGVBVABUFFER(("done ok, data = %d, free = %d\n", 297 pVBVA ->off32Data,pVBVA->off32Free));345 pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free)); 298 346 299 347 return true; 300 348 } 301 349 302 static void vbvaReleaseCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA, VBVACMDHDR *pHdr, uint32_t cbCmd) 303 { 304 uint8_t *au8RingBuffer = &pVBVA->au8Data[0]; 350 static void vbvaReleaseCmd(VBVADATA *pVBVAData, VBVACMDHDR *pHdr, uint32_t cbCmd) 351 { 352 VBVAPARTIALRECORD *pPartialRecord = &pVBVAData->partialRecord; 353 uint8_t *au8RingBuffer = pVBVAData->guest.pu8Data; 305 354 306 355 if ( (uint8_t *)pHdr >= au8RingBuffer 307 && (uint8_t *)pHdr < &au8RingBuffer[pVBVA ->cbData])356 && (uint8_t *)pHdr < &au8RingBuffer[pVBVAData->cbData]) 308 357 { 309 358 /* The pointer is inside ring buffer. Must be continuous chunk. */ 310 Assert (pVBVA->cbData - ((uint8_t *)pHdr - au8RingBuffer) >= cbCmd);359 Assert(pVBVAData->cbData - ((uint8_t *)pHdr - au8RingBuffer) >= cbCmd); 311 360 312 361 /* Do nothing. */ … … 326 375 else 327 376 { 328 Assert (!pPartialRecord->pu8 && pPartialRecord->cb == 0); 329 } 330 331 RTMemFree (pHdr); 332 } 333 334 return; 335 } 336 337 static int vbvaFlushProcess (unsigned uScreenId, PVGASTATE pVGAState, VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA) 377 Assert(!pPartialRecord->pu8 && pPartialRecord->cb == 0); 378 } 379 380 RTMemFree(pHdr); 381 } 382 } 383 384 static int vbvaFlushProcess(unsigned uScreenId, PVGASTATE pVGAState, VBVADATA *pVBVAData) 338 385 { 339 386 LOGVBVABUFFER(("uScreenId %d, indexRecordFirst = %d, indexRecordFree = %d, off32Data = %d, off32Free = %d\n", 340 uScreenId, pVBVA->indexRecordFirst, pVBVA->indexRecordFree, pVBVA->off32Data, pVBVA->off32Free)); 387 uScreenId, pVBVAData->indexRecordFirst, pVBVAData->guest.pVBVA->indexRecordFree, 388 pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free)); 341 389 struct { 342 390 /* The rectangle that includes all dirty rectangles. */ … … 357 405 358 406 /* Fetch the command data. */ 359 if (!vbvaFetchCmd (pPartialRecord, pVBVA, &phdr, &cbCmd))407 if (!vbvaFetchCmd(pVBVAData, &phdr, &cbCmd)) 360 408 { 361 409 LogFunc(("unable to fetch command. off32Data = %d, off32Free = %d!!!\n", 362 pVBVA->off32Data, pVBVA->off32Free)); 363 364 /* @todo old code disabled VBVA processing here. */ 410 pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free)); 411 365 412 return VERR_NOT_SUPPORTED; 366 413 } … … 372 419 } 373 420 421 if (cbCmd < sizeof(VBVACMDHDR)) 422 { 423 LogFunc(("short command. off32Data = %d, off32Free = %d, cbCmd %d!!!\n", 424 pVBVAData->off32Data, pVBVAData->guest.pVBVA->off32Free, cbCmd)); 425 426 return VERR_NOT_SUPPORTED; 427 } 428 374 429 if (cbCmd != 0) 375 430 { 376 431 if (!fUpdate) 377 432 { 378 pVGAState->pDrv->pfnVBVAUpdateBegin 433 pVGAState->pDrv->pfnVBVAUpdateBegin(pVGAState->pDrv, uScreenId); 379 434 fUpdate = true; 380 435 } 381 436 382 437 /* Updates the rectangle and sends the command to the VRDP server. */ 383 pVGAState->pDrv->pfnVBVAUpdateProcess 438 pVGAState->pDrv->pfnVBVAUpdateProcess(pVGAState->pDrv, uScreenId, phdr, cbCmd); 384 439 385 440 int32_t xRight = phdr->x + phdr->w; … … 391 446 cbCmd, phdr->x, phdr->y, phdr->w, phdr->h)); 392 447 LogRel3(("%s: update command cbCmd = %d, x=%d, y=%d, w=%d, h=%d\n", 393 __PRETTY_FUNCTION__, cbCmd, phdr->x, phdr->y, phdr->w, 394 phdr->h)); 448 __FUNCTION__, cbCmd, phdr->x, phdr->y, phdr->w, phdr->h)); 395 449 396 450 /* Collect all rects into one. */ … … 429 483 } 430 484 431 vbvaReleaseCmd (pPartialRecord, pVBVA, phdr, cbCmd);485 vbvaReleaseCmd(pVBVAData, phdr, cbCmd); 432 486 } 433 487 … … 437 491 { 438 492 LogRel3(("%s: sending update screen=%d, x=%d, y=%d, w=%d, h=%d\n", 439 __ PRETTY_FUNCTION__, uScreenId, dirtyRect.xLeft,493 __FUNCTION__, uScreenId, dirtyRect.xLeft, 440 494 dirtyRect.yTop, dirtyRect.xRight - dirtyRect.xLeft, 441 495 dirtyRect.yBottom - dirtyRect.yTop)); 442 pVGAState->pDrv->pfnVBVAUpdateEnd 443 496 pVGAState->pDrv->pfnVBVAUpdateEnd(pVGAState->pDrv, uScreenId, dirtyRect.xLeft, dirtyRect.yTop, 497 dirtyRect.xRight - dirtyRect.xLeft, dirtyRect.yBottom - dirtyRect.yTop); 444 498 } 445 499 else 446 500 { 447 pVGAState->pDrv->pfnVBVAUpdateEnd 501 pVGAState->pDrv->pfnVBVAUpdateEnd(pVGAState->pDrv, uScreenId, 0, 0, 0, 0); 448 502 } 449 503 } … … 452 506 } 453 507 454 static int vbvaFlush (PVGASTATE pVGAState, VBVACONTEXT *pCtx) 455 { 508 static int vbvaFlush(PVGASTATE pVGAState, VBVACONTEXT *pCtx) 509 { 510 int rc = VINF_SUCCESS; 511 456 512 unsigned uScreenId; 457 458 513 for (uScreenId = 0; uScreenId < pCtx->cViews; uScreenId++) 459 514 { 460 VBVAPARTIALRECORD *pPartialRecord = &pCtx->aViews[uScreenId].partialRecord; 461 VBVABUFFER *pVBVA = pCtx->aViews[uScreenId].pVBVA; 462 463 if (pVBVA) 464 { 465 vbvaFlushProcess (uScreenId, pVGAState, pPartialRecord, pVBVA); 466 } 467 } 468 469 /* @todo rc */ 470 return VINF_SUCCESS; 471 } 472 473 static int vbvaResize (PVGASTATE pVGAState, VBVAVIEW *pView, const VBVAINFOSCREEN *pNewScreen) 474 { 475 /* Verify pNewScreen. */ 476 /* @todo */ 515 VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva; 516 517 if (pVBVAData->guest.pVBVA) 518 { 519 rc = vbvaFlushProcess(uScreenId, pVGAState, pVBVAData); 520 if (RT_FAILURE(rc)) 521 { 522 break; 523 } 524 } 525 } 526 527 if (RT_FAILURE(rc)) 528 { 529 /* Turn off VBVA processing. */ 530 LogRel(("VBVA: disabling\n", rc)); 531 for (uScreenId = 0; uScreenId < pCtx->cViews; uScreenId++) 532 { 533 VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva; 534 if (pVBVAData->guest.pVBVA) 535 { 536 vbvaDataCleanup(pVBVAData); 537 pVGAState->pDrv->pfnVBVADisable(pVGAState->pDrv, uScreenId); 538 } 539 } 540 } 541 542 return rc; 543 } 544 545 static int vbvaResize(PVGASTATE pVGAState, VBVAVIEW *pView, const VBVAINFOSCREEN *pNewScreen) 546 { 547 /* Callers ensure that pNewScreen contains valid data. */ 477 548 478 549 /* Apply these changes. */ … … 480 551 481 552 uint8_t *pu8VRAM = pVGAState->vram_ptrR3 + pView->view.u32ViewOffset; 482 483 int rc = pVGAState->pDrv->pfnVBVAResize (pVGAState->pDrv, &pView->view, &pView->screen, pu8VRAM); 484 485 /* @todo process VINF_VGA_RESIZE_IN_PROGRESS? */ 486 487 return rc; 488 } 489 490 static int vbvaEnable (unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx, VBVABUFFER *pVBVA, uint32_t u32Offset, bool fRestored) 491 { 492 /* @todo old code did a UpdateDisplayAll at this place. */ 493 553 return pVGAState->pDrv->pfnVBVAResize (pVGAState->pDrv, &pView->view, &pView->screen, pu8VRAM); 554 } 555 556 static int vbvaEnable(unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx, VBVABUFFER *pVBVA, uint32_t u32Offset, bool fRestored) 557 { 494 558 int rc; 495 559 560 /* Check if VBVABUFFER content makes sense. */ 561 const VBVABUFFER parms = *pVBVA; 562 563 uint32_t cbVBVABuffer = RT_UOFFSETOF(VBVABUFFER, au8Data) + parms.cbData; 564 if ( parms.cbData > UINT32_MAX - RT_UOFFSETOF(VBVABUFFER, au8Data) 565 || cbVBVABuffer > pVGAState->vram_size 566 || u32Offset > pVGAState->vram_size - cbVBVABuffer) 567 { 568 return VERR_INVALID_PARAMETER; 569 } 570 571 if ( parms.off32Data != 0 572 || parms.off32Free != 0 573 || parms.indexRecordFirst != 0 574 || parms.indexRecordFree != 0 575 || parms.cbPartialWriteThreshold >= parms.cbData 576 || parms.cbPartialWriteThreshold == 0) 577 { 578 return VERR_INVALID_PARAMETER; 579 } 580 496 581 if (pVGAState->pDrv->pfnVBVAEnable) 497 582 { 498 pVBVA->hostFlags.u32HostEvents = 0; 499 pVBVA->hostFlags.u32SupportedOrders = 0; 500 501 rc = pVGAState->pDrv->pfnVBVAEnable (pVGAState->pDrv, uScreenId, &pVBVA->hostFlags, false); 583 RT_ZERO(pVBVA->hostFlags); 584 rc = pVGAState->pDrv->pfnVBVAEnable(pVGAState->pDrv, uScreenId, &pVBVA->hostFlags, false); 502 585 } 503 586 else … … 506 589 } 507 590 508 if (RT_SUCCESS 591 if (RT_SUCCESS(rc)) 509 592 { 510 593 /* pVBVA->hostFlags has been set up by pfnVBVAEnable. */ 511 594 LogFlowFunc(("u32HostEvents 0x%08X, u32SupportedOrders 0x%08X\n", 512 595 pVBVA->hostFlags.u32HostEvents, pVBVA->hostFlags.u32SupportedOrders)); 596 597 VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva; 598 pVBVAData->guest.pVBVA = pVBVA; 599 pVBVAData->guest.pu8Data = &pVBVA->au8Data[0]; 600 pVBVAData->u32VBVAOffset = u32Offset; 601 pVBVAData->off32Data = 0; 602 pVBVAData->indexRecordFirst = 0; 603 pVBVAData->cbPartialWriteThreshold = parms.cbPartialWriteThreshold; 604 pVBVAData->cbData = parms.cbData; 513 605 514 606 if (!fRestored) … … 520 612 * when partialRecord might be loaded already from the saved state. 521 613 */ 522 pCtx->aViews[uScreenId].partialRecord.pu8 = NULL; 523 pCtx->aViews[uScreenId].partialRecord.cb = 0; 524 } 525 526 pCtx->aViews[uScreenId].pVBVA = pVBVA; 527 pCtx->aViews[uScreenId].u32VBVAOffset = u32Offset; 614 pVBVAData->partialRecord.pu8 = NULL; 615 pVBVAData->partialRecord.cb = 0; 616 } 528 617 529 618 /* VBVA is working so disable the pause. */ … … 539 628 vbvaFlush (pVGAState, pCtx); 540 629 541 VBVAVIEW *pView = &pCtx->aViews[uScreenId]; 542 543 if (pView->pVBVA) 544 { 545 pView->pVBVA->hostFlags.u32HostEvents = 0; 546 pView->pVBVA->hostFlags.u32SupportedOrders = 0; 547 548 pView->partialRecord.pu8 = NULL; 549 pView->partialRecord.cb = 0; 550 551 pView->pVBVA = NULL; 552 pView->u32VBVAOffset = HGSMIOFFSET_VOID; 553 } 554 555 pVGAState->pDrv->pfnVBVADisable (pVGAState->pDrv, uScreenId); 630 VBVADATA *pVBVAData = &pCtx->aViews[uScreenId].vbva; 631 vbvaDataCleanup(pVBVAData); 632 633 pVGAState->pDrv->pfnVBVADisable(pVGAState->pDrv, uScreenId); 556 634 return VINF_SUCCESS; 557 635 } … … 568 646 { 569 647 VBVAVIEW * pView = &pCtx->aViews[0]; 570 if (pView-> pVBVA)648 if (pView->vbva.guest.pVBVA) 571 649 return true; 572 650 } … … 594 672 #endif 595 673 596 static int vbvaUpdateMousePointerShape(PVGASTATE pVGAState, VBVAMOUSESHAPEINFO *pMouseShapeInfo, bool fShape, const uint8_t *pu8Shape) 597 { 598 int rc; 599 LogFlowFunc(("pVGAState %p, pMouseShapeInfo %p, fShape %d, pu8Shape %p\n", 600 pVGAState, pMouseShapeInfo, fShape, pu8Shape)); 674 static int vbvaUpdateMousePointerShape(PVGASTATE pVGAState, VBVAMOUSESHAPEINFO *pMouseShapeInfo, bool fShape) 675 { 676 LogFlowFunc(("pVGAState %p, pMouseShapeInfo %p, fShape %d\n", 677 pVGAState, pMouseShapeInfo, fShape)); 601 678 #ifdef DEBUG_sunlover 602 679 dumpMouseShapeInfo(pMouseShapeInfo); 603 680 #endif 604 681 605 if (fShape && pu8Shape != NULL) 682 if (pVGAState->pDrv->pfnVBVAMousePointerShape == NULL) 683 { 684 return VERR_NOT_SUPPORTED; 685 } 686 687 int rc; 688 if (fShape && pMouseShapeInfo->pu8Shape != NULL) 606 689 { 607 690 rc = pVGAState->pDrv->pfnVBVAMousePointerShape (pVGAState->pDrv, … … 612 695 pMouseShapeInfo->u32Width, 613 696 pMouseShapeInfo->u32Height, 614 p u8Shape);697 pMouseShapeInfo->pu8Shape); 615 698 } 616 699 else … … 627 710 } 628 711 629 static int vbvaMousePointerShape (PVGASTATE pVGAState, VBVACONTEXT *pCtx, const VBVAMOUSEPOINTERSHAPE *pShape, HGSMISIZE cbShape) 630 { 631 bool fVisible = (pShape->fu32Flags & VBOX_MOUSE_POINTER_VISIBLE) != 0; 632 bool fAlpha = (pShape->fu32Flags & VBOX_MOUSE_POINTER_ALPHA) != 0; 633 bool fShape = (pShape->fu32Flags & VBOX_MOUSE_POINTER_SHAPE) != 0; 712 static int vbvaMousePointerShape(PVGASTATE pVGAState, VBVACONTEXT *pCtx, const VBVAMOUSEPOINTERSHAPE *pShape, HGSMISIZE cbShape) 713 { 714 const VBVAMOUSEPOINTERSHAPE parms = *pShape; 715 716 LogFlowFunc(("VBVA_MOUSE_POINTER_SHAPE: i32Result 0x%x, fu32Flags 0x%x, hot spot %d,%d, size %dx%d\n", 717 parms.i32Result, 718 parms.fu32Flags, 719 parms.u32HotX, 720 parms.u32HotY, 721 parms.u32Width, 722 parms.u32Height)); 723 724 const bool fVisible = RT_BOOL(parms.fu32Flags & VBOX_MOUSE_POINTER_VISIBLE); 725 const bool fAlpha = RT_BOOL(parms.fu32Flags & VBOX_MOUSE_POINTER_ALPHA); 726 const bool fShape = RT_BOOL(parms.fu32Flags & VBOX_MOUSE_POINTER_SHAPE); 634 727 635 728 HGSMISIZE cbPointerData = 0; … … 637 730 if (fShape) 638 731 { 639 if (p Shape->u32Width > 8192 || pShape->u32Height > 8192)732 if (parms.u32Width > 8192 || parms.u32Height > 8192) 640 733 { 641 734 Log(("vbvaMousePointerShape: unsupported size %ux%u\n", 642 p Shape->u32Width, pShape->u32Height));735 parms.u32Width, parms.u32Height)); 643 736 return VERR_INVALID_PARAMETER; 644 737 } 645 738 646 cbPointerData = ((((p Shape->u32Width + 7) / 8) * pShape->u32Height + 3) & ~3)647 + p Shape->u32Width * 4 * pShape->u32Height;648 } 649 650 if (cbPointerData > cbShape - RT_ OFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data))739 cbPointerData = ((((parms.u32Width + 7) / 8) * parms.u32Height + 3) & ~3) 740 + parms.u32Width * 4 * parms.u32Height; 741 } 742 743 if (cbPointerData > cbShape - RT_UOFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data)) 651 744 { 652 745 Log(("vbvaMousePointerShape: calculated pointer data size is too big (%d bytes, limit %d)\n", 653 cbPointerData, cbShape - RT_ OFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data)));746 cbPointerData, cbShape - RT_UOFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data))); 654 747 return VERR_INVALID_PARAMETER; 655 748 } … … 662 755 { 663 756 /* Data related to shape. */ 664 pCtx->mouseShapeInfo.u32HotX = p Shape->u32HotX;665 pCtx->mouseShapeInfo.u32HotY = p Shape->u32HotY;666 pCtx->mouseShapeInfo.u32Width = p Shape->u32Width;667 pCtx->mouseShapeInfo.u32Height = p Shape->u32Height;757 pCtx->mouseShapeInfo.u32HotX = parms.u32HotX; 758 pCtx->mouseShapeInfo.u32HotY = parms.u32HotY; 759 pCtx->mouseShapeInfo.u32Width = parms.u32Width; 760 pCtx->mouseShapeInfo.u32Height = parms.u32Height; 668 761 669 762 /* Reallocate memory buffer if necessary. */ … … 685 778 if (pCtx->mouseShapeInfo.pu8Shape) 686 779 { 687 memcpy 780 memcpy(pCtx->mouseShapeInfo.pu8Shape, &pShape->au8Data[0], cbPointerData); 688 781 pCtx->mouseShapeInfo.cbShape = cbPointerData; 689 782 } 690 783 } 691 784 692 if (pVGAState->pDrv->pfnVBVAMousePointerShape == NULL) 693 { 694 return VERR_NOT_SUPPORTED; 695 } 696 697 int rc = vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, fShape, &pShape->au8Data[0]); 785 int rc = vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, fShape); 698 786 699 787 return rc; 700 788 } 701 789 702 static u nsigned vbvaViewFromOffset (PHGSMIINSTANCE pIns,VBVACONTEXT *pCtx, const void *pvBuffer)790 static uint32_t vbvaViewFromBufferPtr(PHGSMIINSTANCE pIns, const VBVACONTEXT *pCtx, const void *pvBuffer) 703 791 { 704 792 /* Check which view contains the buffer. */ 705 HGSMIOFFSET offBuffer = HGSMIPointerToOffsetHost 793 HGSMIOFFSET offBuffer = HGSMIPointerToOffsetHost(pIns, pvBuffer); 706 794 707 795 if (offBuffer != HGSMIOFFSET_VOID) 708 796 { 709 797 unsigned uScreenId; 710 711 798 for (uScreenId = 0; uScreenId < pCtx->cViews; uScreenId++) 712 799 { 713 VBVAINFOVIEW *pView = &pCtx->aViews[uScreenId].view;800 const VBVAINFOVIEW *pView = &pCtx->aViews[uScreenId].view; 714 801 715 802 if ( pView->u32ViewSize > 0 … … 722 809 } 723 810 724 return ~0U;811 return UINT32_C(~0); 725 812 } 726 813 … … 754 841 Log((" VBVA o 0x%x p %p\n", 755 842 pView->u32VBVAOffset, 756 pView-> pVBVA));843 pView->vbva.guest.pVBVA)); 757 844 758 845 Log((" PR cb 0x%x p %p\n", … … 1555 1642 AssertRCReturn(rc, rc); 1556 1643 1557 rc = SSMR3PutU32 (pSSM, pView-> pVBVA? pView->u32VBVAOffset: HGSMIOFFSET_VOID);1558 AssertRCReturn(rc, rc); 1559 1560 rc = SSMR3PutU32 (pSSM, pView-> partialRecord.cb);1561 AssertRCReturn(rc, rc); 1562 1563 if (pView-> partialRecord.cb > 0)1564 { 1565 rc = SSMR3PutMem (pSSM, pView-> partialRecord.pu8, pView->partialRecord.cb);1644 rc = SSMR3PutU32 (pSSM, pView->vbva.guest.pVBVA? pView->vbva.u32VBVAOffset: HGSMIOFFSET_VOID); 1645 AssertRCReturn(rc, rc); 1646 1647 rc = SSMR3PutU32 (pSSM, pView->vbva.partialRecord.cb); 1648 AssertRCReturn(rc, rc); 1649 1650 if (pView->vbva.partialRecord.cb > 0) 1651 { 1652 rc = SSMR3PutMem (pSSM, pView->vbva.partialRecord.pu8, pView->vbva.partialRecord.cb); 1566 1653 AssertRCReturn(rc, rc); 1567 1654 } … … 1741 1828 AssertRCReturn(rc, rc); 1742 1829 1743 rc = SSMR3GetU32 (pSSM, &pView-> u32VBVAOffset);1744 AssertRCReturn(rc, rc); 1745 1746 rc = SSMR3GetU32 (pSSM, &pView-> partialRecord.cb);1747 AssertRCReturn(rc, rc); 1748 1749 if (pView-> partialRecord.cb == 0)1750 { 1751 pView-> partialRecord.pu8 = NULL;1830 rc = SSMR3GetU32 (pSSM, &pView->vbva.u32VBVAOffset); 1831 AssertRCReturn(rc, rc); 1832 1833 rc = SSMR3GetU32 (pSSM, &pView->vbva.partialRecord.cb); 1834 AssertRCReturn(rc, rc); 1835 1836 if (pView->vbva.partialRecord.cb == 0) 1837 { 1838 pView->vbva.partialRecord.pu8 = NULL; 1752 1839 } 1753 1840 else 1754 1841 { 1755 Assert(pView-> partialRecord.pu8 == NULL); /* Should be it. */1756 1757 uint8_t *pu8 = (uint8_t *)RTMemAlloc (pView->partialRecord.cb);1842 Assert(pView->vbva.partialRecord.pu8 == NULL); /* Should be it. */ 1843 1844 uint8_t *pu8 = (uint8_t *)RTMemAlloc(pView->vbva.partialRecord.cb); 1758 1845 1759 1846 if (!pu8) … … 1762 1849 } 1763 1850 1764 pView-> partialRecord.pu8 = pu8;1765 1766 rc = SSMR3GetMem (pSSM, pView-> partialRecord.pu8, pView->partialRecord.cb);1851 pView->vbva.partialRecord.pu8 = pu8; 1852 1853 rc = SSMR3GetMem (pSSM, pView->vbva.partialRecord.pu8, pView->vbva.partialRecord.cb); 1767 1854 AssertRCReturn(rc, rc); 1768 1855 } 1769 1856 1770 if (pView-> u32VBVAOffset == HGSMIOFFSET_VOID)1771 { 1772 pView-> pVBVA = NULL;1857 if (pView->vbva.u32VBVAOffset == HGSMIOFFSET_VOID) 1858 { 1859 pView->vbva.guest.pVBVA = NULL; 1773 1860 } 1774 1861 else 1775 1862 { 1776 pView-> pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost (pIns, pView->u32VBVAOffset);1863 pView->vbva.guest.pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pIns, pView->vbva.u32VBVAOffset); 1777 1864 } 1778 1865 } … … 1945 2032 VBVAVIEW *pView = &pCtx->aViews[iView]; 1946 2033 1947 if (pView-> pVBVA)2034 if (pView->vbva.guest.pVBVA) 1948 2035 { 1949 2036 #ifdef VBOX_WITH_CRHGSMI 1950 2037 Assert(!vboxCmdVBVAIsEnabled(pVGAState)); 1951 2038 #endif 1952 vbvaEnable (iView, pVGAState, pCtx, pView-> pVBVA, pView->u32VBVAOffset, true /* fRestored */);2039 vbvaEnable (iView, pVGAState, pCtx, pView->vbva.guest.pVBVA, pView->vbva.u32VBVAOffset, true /* fRestored */); 1953 2040 vbvaResize (pVGAState, pView, &pView->screen); 1954 2041 } … … 1957 2044 if (pCtx->mouseShapeInfo.fSet) 1958 2045 { 1959 vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, true , pCtx->mouseShapeInfo.pu8Shape);2046 vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, true); 1960 2047 } 1961 2048 } … … 1991 2078 } 1992 2079 1993 int VBVAInfoView(PVGASTATE pVGAState, const VBVAINFOVIEW *pView) 1994 { 1995 LogFlowFunc(("VBVA_INFO_VIEW: u32ViewIndex %d, u32ViewOffset 0x%x, u32ViewSize 0x%x, u32MaxScreenSize 0x%x\n", 1996 pView->u32ViewIndex, pView->u32ViewOffset, pView->u32ViewSize, pView->u32MaxScreenSize)); 1997 2080 static int vbvaHandleQueryConf32(PVGASTATE pVGAState, VBVACONF32 *pConf32) 2081 { 2082 int rc = VINF_SUCCESS; 1998 2083 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 1999 2084 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns); 2000 2085 2001 if ( pView->u32ViewIndex < pCtx->cViews 2002 && pView->u32ViewOffset <= pVGAState->vram_size 2003 && pView->u32ViewSize <= pVGAState->vram_size 2004 && pView->u32ViewOffset <= pVGAState->vram_size - pView->u32ViewSize 2005 && pView->u32MaxScreenSize <= pView->u32ViewSize) 2006 { 2007 pCtx->aViews[pView->u32ViewIndex].view = *pView; 2008 return VINF_SUCCESS; 2009 } 2010 2011 LogRelFlow(("VBVA_INFO_VIEW: invalid data: index %d(%d), offset 0x%x, size 0x%x, max 0x%x, vram size 0x%x\n", 2012 pView->u32ViewIndex, pCtx->cViews, pView->u32ViewOffset, pView->u32ViewSize, 2013 pView->u32MaxScreenSize, pVGAState->vram_size)); 2014 return VERR_INVALID_PARAMETER; 2015 } 2016 2017 int VBVAInfoScreen(PVGASTATE pVGAState, const VBVAINFOSCREEN *pScreen) 2018 { 2019 LogRel(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n", 2020 pScreen->u32ViewIndex, pScreen->i32OriginX, pScreen->i32OriginY, 2021 pScreen->u32Width, pScreen->u32Height, 2022 pScreen->u32LineSize, pScreen->u16BitsPerPixel, pScreen->u16Flags)); 2086 const uint32_t u32Index = pConf32->u32Index; 2087 2088 LogFlowFunc(("VBVA_QUERY_CONF32: u32Index %d, u32Value 0x%x\n", 2089 u32Index, pConf32->u32Value)); 2090 2091 if (u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT) 2092 { 2093 pConf32->u32Value = pCtx->cViews; 2094 } 2095 else if (u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE) 2096 { 2097 /* @todo a value calculated from the vram size */ 2098 pConf32->u32Value = 64*_1K; 2099 } 2100 else if ( u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING 2101 || u32Index == VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING) 2102 { 2103 pConf32->u32Value = VINF_SUCCESS; 2104 } 2105 else if (u32Index == VBOX_VBVA_CONF32_CURSOR_CAPABILITIES) 2106 { 2107 pConf32->u32Value = pVGAState->fHostCursorCapabilities; 2108 } 2109 else if (u32Index == VBOX_VBVA_CONF32_SCREEN_FLAGS) 2110 { 2111 pConf32->u32Value = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED | VBVA_SCREEN_F_BLANK; 2112 } 2113 else if (u32Index == VBOX_VBVA_CONF32_MAX_RECORD_SIZE) 2114 { 2115 pConf32->u32Value = VBVA_MAX_RECORD_SIZE; 2116 } 2117 else 2118 { 2119 Log(("Unsupported VBVA_QUERY_CONF32 index %d!!!\n", 2120 u32Index)); 2121 rc = VERR_INVALID_PARAMETER; 2122 } 2123 2124 return rc; 2125 } 2126 2127 static int vbvaHandleSetConf32(PVGASTATE pVGAState, VBVACONF32 *pConf32) 2128 { 2129 NOREF(pVGAState); 2130 2131 int rc = VINF_SUCCESS; 2132 const VBVACONF32 parms = *pConf32; 2133 2134 LogFlowFunc(("VBVA_SET_CONF32: u32Index %d, u32Value 0x%x\n", 2135 parms.u32Index, parms.u32Value)); 2136 2137 if (parms.u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT) 2138 { 2139 /* do nothing. this is a const. */ 2140 } 2141 else if (parms.u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE) 2142 { 2143 /* do nothing. this is a const. */ 2144 } 2145 else 2146 { 2147 Log(("Unsupported VBVA_SET_CONF32 index %d!!!\n", 2148 parms.u32Index)); 2149 rc = VERR_INVALID_PARAMETER; 2150 } 2151 2152 return rc; 2153 } 2154 2155 static int vbvaHandleInfoHeap(PVGASTATE pVGAState, const VBVAINFOHEAP *pInfoHeap) 2156 { 2157 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 2158 2159 const VBVAINFOHEAP parms = *pInfoHeap; 2160 LogFlowFunc(("VBVA_INFO_HEAP: offset 0x%x, size 0x%x\n", 2161 parms.u32HeapOffset, parms.u32HeapSize)); 2162 2163 return HGSMIHostHeapSetup(pIns, parms.u32HeapOffset, parms.u32HeapSize); 2164 } 2165 2166 int VBVAInfoView(PVGASTATE pVGAState, const VBVAINFOVIEW *pView) 2167 { 2168 const VBVAINFOVIEW view = *pView; 2169 2170 LogFlowFunc(("VBVA_INFO_VIEW: u32ViewIndex %d, u32ViewOffset 0x%x, u32ViewSize 0x%x, u32MaxScreenSize 0x%x\n", 2171 view.u32ViewIndex, view.u32ViewOffset, view.u32ViewSize, view.u32MaxScreenSize)); 2023 2172 2024 2173 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 2025 2174 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns); 2026 2175 2027 /* Allow pScreen->u16BitsPerPixel == 0 because legacy guest code used it for screen blanking. */ 2028 if ( pScreen->u32ViewIndex < pCtx->cViews 2029 && pScreen->u16BitsPerPixel <= 32 2030 && pScreen->u32Width <= UINT16_MAX 2031 && pScreen->u32Height <= UINT16_MAX 2032 && pScreen->u32LineSize <= UINT16_MAX * 4) 2033 { 2034 const VBVAINFOVIEW *pView = &pCtx->aViews[pScreen->u32ViewIndex].view; 2035 const uint32_t u32BytesPerPixel = (pScreen->u16BitsPerPixel + 7) / 8; 2036 if (pScreen->u32Width <= pScreen->u32LineSize / (u32BytesPerPixel? u32BytesPerPixel: 1)) 2037 { 2038 const uint64_t u64ScreenSize = (uint64_t)pScreen->u32LineSize * pScreen->u32Height; 2039 if ( pScreen->u32StartOffset <= pView->u32ViewSize 2176 if ( view.u32ViewIndex < pCtx->cViews 2177 && view.u32ViewOffset <= pVGAState->vram_size 2178 && view.u32ViewSize <= pVGAState->vram_size 2179 && view.u32ViewOffset <= pVGAState->vram_size - view.u32ViewSize 2180 && view.u32MaxScreenSize <= view.u32ViewSize) 2181 { 2182 pCtx->aViews[view.u32ViewIndex].view = view; 2183 return VINF_SUCCESS; 2184 } 2185 2186 LogRelFlow(("VBVA_INFO_VIEW: invalid data: index %d(%d), offset 0x%x, size 0x%x, max 0x%x, vram size 0x%x\n", 2187 view.u32ViewIndex, pCtx->cViews, view.u32ViewOffset, view.u32ViewSize, 2188 view.u32MaxScreenSize, pVGAState->vram_size)); 2189 return VERR_INVALID_PARAMETER; 2190 } 2191 2192 int VBVAInfoScreen(PVGASTATE pVGAState, const VBVAINFOSCREEN *pScreen) 2193 { 2194 const VBVAINFOSCREEN screen = *pScreen; 2195 2196 LogRel(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n", 2197 screen.u32ViewIndex, screen.i32OriginX, screen.i32OriginY, 2198 screen.u32Width, screen.u32Height, 2199 screen.u32LineSize, screen.u16BitsPerPixel, screen.u16Flags)); 2200 2201 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 2202 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns); 2203 2204 /* Allow screen.u16BitsPerPixel == 0 because legacy guest code used it for screen blanking. */ 2205 if ( screen.u32ViewIndex < pCtx->cViews 2206 && screen.u16BitsPerPixel <= 32 2207 && screen.u32Width <= UINT16_MAX 2208 && screen.u32Height <= UINT16_MAX 2209 && screen.u32LineSize <= UINT16_MAX * 4) 2210 { 2211 const VBVAINFOVIEW *pView = &pCtx->aViews[screen.u32ViewIndex].view; 2212 const uint32_t u32BytesPerPixel = (screen.u16BitsPerPixel + 7) / 8; 2213 if (screen.u32Width <= screen.u32LineSize / (u32BytesPerPixel? u32BytesPerPixel: 1)) 2214 { 2215 const uint64_t u64ScreenSize = (uint64_t)screen.u32LineSize * screen.u32Height; 2216 if ( screen.u32StartOffset <= pView->u32ViewSize 2040 2217 && u64ScreenSize <= pView->u32MaxScreenSize 2041 && pScreen->u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize)2042 { 2043 vbvaResize(pVGAState, &pCtx->aViews[ pScreen->u32ViewIndex], pScreen);2218 && screen.u32StartOffset <= pView->u32ViewSize - (uint32_t)u64ScreenSize) 2219 { 2220 vbvaResize(pVGAState, &pCtx->aViews[screen.u32ViewIndex], &screen); 2044 2221 return VINF_SUCCESS; 2045 2222 } … … 2052 2229 { 2053 2230 LogRelFlow(("VBVA_INFO_SCREEN: invalid data: index %RU32(%RU32)\n", 2054 pScreen->u32ViewIndex, pCtx->cViews));2231 screen.u32ViewIndex, pCtx->cViews)); 2055 2232 } 2056 2233 … … 2075 2252 } 2076 2253 2254 static int vbvaHandleEnable(PVGASTATE pVGAState, const VBVAENABLE *pVbvaEnable, uint32_t u32ScreenId) 2255 { 2256 int rc = VINF_SUCCESS; 2257 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 2258 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns); 2259 2260 if (u32ScreenId > pCtx->cViews) 2261 { 2262 return VERR_INVALID_PARAMETER; 2263 } 2264 2265 const VBVAENABLE parms = *pVbvaEnable; 2266 2267 LogFlowFunc(("VBVA_ENABLE[%d]: u32Flags 0x%x u32Offset 0x%x\n", 2268 u32ScreenId, parms.u32Flags, parms.u32Offset)); 2269 2270 if ((parms.u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_ENABLE) 2271 { 2272 uint32_t u32Offset = parms.u32Offset; 2273 if (u32Offset < pVGAState->vram_size) 2274 { 2275 /* Guest reported offset either absolute or relative to view. */ 2276 if (parms.u32Flags & VBVA_F_ABSOFFSET) 2277 { 2278 /* Offset from VRAM start. */ 2279 if ( pVGAState->vram_size < RT_UOFFSETOF(VBVABUFFER, au8Data) 2280 || u32Offset > pVGAState->vram_size - RT_UOFFSETOF(VBVABUFFER, au8Data)) 2281 { 2282 rc = VERR_INVALID_PARAMETER; 2283 } 2284 } 2285 else 2286 { 2287 /* Offset from the view start. */ 2288 const VBVAINFOVIEW *pView = &pCtx->aViews[u32ScreenId].view; 2289 if ( pVGAState->vram_size - u32Offset < pView->u32ViewOffset 2290 || pView->u32ViewSize < RT_UOFFSETOF(VBVABUFFER, au8Data) 2291 || u32Offset > pView->u32ViewSize - RT_UOFFSETOF(VBVABUFFER, au8Data)) 2292 { 2293 rc = VERR_INVALID_PARAMETER; 2294 } 2295 else 2296 { 2297 u32Offset += pView->u32ViewOffset; 2298 } 2299 } 2300 } 2301 else 2302 { 2303 rc = VERR_INVALID_PARAMETER; 2304 } 2305 2306 if (RT_SUCCESS(rc)) 2307 { 2308 VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pIns, u32Offset); 2309 if (pVBVA) 2310 { 2311 /* Process any pending orders and empty the VBVA ring buffer. */ 2312 vbvaFlush(pVGAState, pCtx); 2313 2314 rc = vbvaEnable(u32ScreenId, pVGAState, pCtx, pVBVA, u32Offset, false /* fRestored */); 2315 } 2316 else 2317 { 2318 Log(("Invalid VBVABUFFER offset 0x%x!!!\n", 2319 parms.u32Offset)); 2320 rc = VERR_INVALID_PARAMETER; 2321 } 2322 } 2323 } 2324 else if ((parms.u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_DISABLE) 2325 { 2326 rc = vbvaDisable(u32ScreenId, pVGAState, pCtx); 2327 } 2328 else 2329 { 2330 Log(("Invalid VBVA_ENABLE flags 0x%x!!!\n", 2331 parms.u32Flags)); 2332 rc = VERR_INVALID_PARAMETER; 2333 } 2334 2335 return rc; 2336 } 2337 2338 static int vbvaHandleQueryModeHints(PVGASTATE pVGAState, const VBVAQUERYMODEHINTS *pQueryModeHints, HGSMISIZE cbBuffer) 2339 { 2340 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 2341 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns); 2342 2343 const VBVAQUERYMODEHINTS parms = *pQueryModeHints; 2344 2345 LogRelFlowFunc(("VBVA_QUERY_MODE_HINTS: cHintsQueried=%RU16, cbHintStructureGuest=%RU16\n", 2346 parms.cHintsQueried, parms.cbHintStructureGuest)); 2347 2348 if (cbBuffer < sizeof(VBVAQUERYMODEHINTS) 2349 + (uint64_t)parms.cHintsQueried * parms.cbHintStructureGuest) 2350 { 2351 return VERR_INVALID_PARAMETER; 2352 } 2353 2354 uint8_t *pbHint = (uint8_t *)pQueryModeHints + sizeof(VBVAQUERYMODEHINTS); 2355 memset(pbHint, ~0, cbBuffer - sizeof(VBVAQUERYMODEHINTS)); 2356 2357 unsigned iHint; 2358 for (iHint = 0; iHint < parms.cHintsQueried 2359 && iHint < VBOX_VIDEO_MAX_SCREENS; ++iHint) 2360 { 2361 memcpy(pbHint, &pCtx->aModeHints[iHint], 2362 RT_MIN(parms.cbHintStructureGuest, sizeof(VBVAMODEHINT))); 2363 pbHint += parms.cbHintStructureGuest; 2364 Assert(pbHint - (uint8_t *)pQueryModeHints <= cbBuffer); 2365 } 2366 2367 return VINF_SUCCESS; 2368 } 2077 2369 2078 2370 /* … … 2098 2390 } 2099 2391 2100 /* The guest submitted a buffer. @todo Verify all guest data. */ 2101 static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer) 2392 /** The guest submitted a command buffer. Verify the buffer size and invoke corresponding handler. 2393 * 2394 * @return VBox status. 2395 * @param pvHandler The VBVA channel context. 2396 * @param u16ChannelInfo Command code. 2397 * @param pvBuffer HGSMI buffer with command data. 2398 * @param cbBuffer Size of command data. 2399 */ 2400 static DECLCALLBACK(int) vbvaChannelHandler(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer) 2102 2401 { 2103 2402 int rc = VINF_SUCCESS; 2104 2403 2105 2404 LogFlowFunc(("pvHandler %p, u16ChannelInfo %d, pvBuffer %p, cbBuffer %u\n", 2106 pvHandler, u16ChannelInfo, pvBuffer, cbBuffer));2405 pvHandler, u16ChannelInfo, pvBuffer, cbBuffer)); 2107 2406 2108 2407 PVGASTATE pVGAState = (PVGASTATE)pvHandler; 2109 2408 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 2110 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext 2409 VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pIns); 2111 2410 2112 2411 switch (u16ChannelInfo) 2113 2412 { 2413 #ifdef VBOX_WITH_CRHGSMI 2114 2414 case VBVA_CMDVBVA_SUBMIT: 2115 2415 { 2116 # ifdef VBOX_WITH_CRHGSMI2117 2416 rc = vboxCmdVBVACmdSubmit(pVGAState); 2118 #endif 2119 break; 2120 } 2417 } break; 2418 2121 2419 case VBVA_CMDVBVA_FLUSH: 2122 2420 { 2123 # ifdef VBOX_WITH_CRHGSMI 2124 rc =vboxCmdVBVACmdFlush(pVGAState); 2125 #endif 2126 break; 2127 } 2421 rc = vboxCmdVBVACmdFlush(pVGAState); 2422 } break; 2423 2128 2424 case VBVA_CMDVBVA_CTL: 2129 2425 { 2130 #ifdef VBOX_WITH_CRHGSMI 2131 if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof (VBOXCMDVBVA_CTL)) 2132 { 2133 Log(("buffer too small\n")); 2134 #ifdef DEBUG_misha 2135 AssertMsgFailed(("buffer too small\n")); 2136 #endif 2426 if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof(VBOXCMDVBVA_CTL)) 2427 { 2137 2428 rc = VERR_INVALID_PARAMETER; 2138 2429 break; 2139 2430 } 2431 2140 2432 VBOXCMDVBVA_CTL *pCtl = (VBOXCMDVBVA_CTL*)VBoxSHGSMIBufferData((PVBOXSHGSMIHEADER)pvBuffer); 2141 2433 rc = vboxCmdVBVACmdCtl(pVGAState, pCtl, cbBuffer - VBoxSHGSMIBufferHeaderSize()); 2142 #endif 2143 break; 2144 } 2434 } break; 2435 #endif /* VBOX_WITH_CRHGSMI */ 2436 2145 2437 #ifdef VBOX_WITH_VDMA 2146 2438 case VBVA_VDMA_CMD: 2147 2439 { 2148 if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof 2440 if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof(VBOXVDMACBUF_DR)) 2149 2441 { 2150 2442 rc = VERR_INVALID_PARAMETER; 2151 2443 break; 2152 2444 } 2153 PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)VBoxSHGSMIBufferData ((PVBOXSHGSMIHEADER)pvBuffer); 2445 2446 PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)VBoxSHGSMIBufferData((PVBOXSHGSMIHEADER)pvBuffer); 2154 2447 vboxVDMACommand(pVGAState->pVdma, pCmd, cbBuffer - VBoxSHGSMIBufferHeaderSize()); 2155 rc = VINF_SUCCESS; 2156 break; 2157 } 2448 } break; 2449 2158 2450 case VBVA_VDMA_CTL: 2159 2451 { 2160 if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof 2452 if (cbBuffer < VBoxSHGSMIBufferHeaderSize() + sizeof(VBOXVDMA_CTL)) 2161 2453 { 2162 2454 rc = VERR_INVALID_PARAMETER; 2163 2455 break; 2164 2456 } 2165 PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMIBufferData ((PVBOXSHGSMIHEADER)pvBuffer); 2457 2458 PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMIBufferData((PVBOXSHGSMIHEADER)pvBuffer); 2166 2459 vboxVDMAControl(pVGAState->pVdma, pCmd, cbBuffer - VBoxSHGSMIBufferHeaderSize()); 2167 rc = VINF_SUCCESS; 2168 break; 2169 } 2170 #endif 2460 } break; 2461 #endif /* VBOX_WITH_VDMA */ 2462 2171 2463 case VBVA_QUERY_CONF32: 2172 2464 { 2173 if (cbBuffer < sizeof 2465 if (cbBuffer < sizeof(VBVACONF32)) 2174 2466 { 2175 2467 rc = VERR_INVALID_PARAMETER; … … 2178 2470 2179 2471 VBVACONF32 *pConf32 = (VBVACONF32 *)pvBuffer; 2180 LogFlowFunc(("VBVA_QUERY_CONF32: u32Index %d, u32Value 0x%x\n", 2181 pConf32->u32Index, pConf32->u32Value)); 2182 2183 if (pConf32->u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT) 2184 { 2185 pConf32->u32Value = pCtx->cViews; 2186 } 2187 else if (pConf32->u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE) 2188 { 2189 /* @todo a value calculated from the vram size */ 2190 pConf32->u32Value = 64*_1K; 2191 } 2192 else if ( pConf32->u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING 2193 || pConf32->u32Index == VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING) 2194 { 2195 pConf32->u32Value = VINF_SUCCESS; 2196 } 2197 else if (pConf32->u32Index == VBOX_VBVA_CONF32_CURSOR_CAPABILITIES) 2198 { 2199 pConf32->u32Value = pVGAState->fHostCursorCapabilities; 2200 } 2201 else if (pConf32->u32Index == VBOX_VBVA_CONF32_SCREEN_FLAGS) 2202 { 2203 pConf32->u32Value = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED | VBVA_SCREEN_F_BLANK; 2204 } 2205 else 2206 { 2207 Log(("Unsupported VBVA_QUERY_CONF32 index %d!!!\n", 2208 pConf32->u32Index)); 2209 rc = VERR_INVALID_PARAMETER; 2210 } 2472 rc = vbvaHandleQueryConf32(pVGAState, pConf32); 2211 2473 } break; 2212 2474 2213 2475 case VBVA_SET_CONF32: 2214 2476 { 2215 if (cbBuffer < sizeof 2477 if (cbBuffer < sizeof(VBVACONF32)) 2216 2478 { 2217 2479 rc = VERR_INVALID_PARAMETER; … … 2220 2482 2221 2483 VBVACONF32 *pConf32 = (VBVACONF32 *)pvBuffer; 2222 LogFlowFunc(("VBVA_SET_CONF32: u32Index %d, u32Value 0x%x\n", 2223 pConf32->u32Index, pConf32->u32Value)); 2224 2225 if (pConf32->u32Index == VBOX_VBVA_CONF32_MONITOR_COUNT) 2226 { 2227 /* do nothing. this is a const. */ 2228 } 2229 else if (pConf32->u32Index == VBOX_VBVA_CONF32_HOST_HEAP_SIZE) 2230 { 2231 /* do nothing. this is a const. */ 2232 } 2233 else 2234 { 2235 Log(("Unsupported VBVA_SET_CONF32 index %d!!!\n", 2236 pConf32->u32Index)); 2237 rc = VERR_INVALID_PARAMETER; 2238 } 2484 rc = vbvaHandleSetConf32(pVGAState, pConf32); 2239 2485 } break; 2240 2486 … … 2248 2494 break; 2249 2495 } 2250 #endif 2496 #endif /* VBOX_WITH_CRHGSMI */ 2251 2497 2252 2498 /* Expect at least one VBVAINFOVIEW structure. */ … … 2263 2509 ++pView, cbBuffer -= sizeof(VBVAINFOVIEW)) 2264 2510 { 2265 VBVAINFOVIEW view = *pView; 2266 rc = VBVAInfoView(pVGAState, &view); 2511 rc = VBVAInfoView(pVGAState, pView); 2267 2512 if (RT_FAILURE(rc)) 2268 2513 break; … … 2272 2517 case VBVA_INFO_HEAP: 2273 2518 { 2274 if (cbBuffer < sizeof 2519 if (cbBuffer < sizeof(VBVAINFOHEAP)) 2275 2520 { 2276 2521 rc = VERR_INVALID_PARAMETER; … … 2278 2523 } 2279 2524 2280 VBVAINFOHEAP *pHeap = (VBVAINFOHEAP *)pvBuffer; 2281 LogFlowFunc(("VBVA_INFO_HEAP: offset 0x%x, size 0x%x\n", 2282 pHeap->u32HeapOffset, pHeap->u32HeapSize)); 2283 2284 rc = HGSMIHostHeapSetup(pIns, pHeap->u32HeapOffset, pHeap->u32HeapSize); 2525 const VBVAINFOHEAP *pInfoHeap = (VBVAINFOHEAP *)pvBuffer; 2526 rc = vbvaHandleInfoHeap(pVGAState, pInfoHeap); 2285 2527 } break; 2286 2528 2287 2529 case VBVA_FLUSH: 2288 2530 { 2289 if (cbBuffer < sizeof 2531 if (cbBuffer < sizeof(VBVAFLUSH)) 2290 2532 { 2291 2533 rc = VERR_INVALID_PARAMETER; … … 2293 2535 } 2294 2536 2295 VBVAFLUSH *pFlush = (VBVAFLUSH *)pvBuffer; 2296 LogFlowFunc(("VBVA_FLUSH: u32Reserved 0x%x\n", 2297 pFlush->u32Reserved)); 2298 2299 rc = vbvaFlush (pVGAState, pCtx); 2537 // const VBVAFLUSH *pVbvaFlush = (VBVAFLUSH *)pvBuffer; 2538 rc = vbvaFlush(pVGAState, pCtx); 2300 2539 } break; 2301 2540 … … 2309 2548 break; 2310 2549 } 2311 #endif 2550 #endif /* VBOX_WITH_CRHGSMI */ 2312 2551 2313 2552 if (cbBuffer < sizeof(VBVAINFOSCREEN)) … … 2317 2556 } 2318 2557 2319 VBVAINFOSCREEN Screen = *(VBVAINFOSCREEN *)pvBuffer;2320 rc = VBVAInfoScreen(pVGAState, &Screen);2558 const VBVAINFOSCREEN *pInfoScreen = (VBVAINFOSCREEN *)pvBuffer; 2559 rc = VBVAInfoScreen(pVGAState, pInfoScreen); 2321 2560 } break; 2322 2561 … … 2330 2569 break; 2331 2570 } 2332 #endif 2333 2334 if (cbBuffer < sizeof 2571 #endif /* VBOX_WITH_CRHGSMI */ 2572 2573 if (cbBuffer < sizeof(VBVAENABLE)) 2335 2574 { 2336 2575 rc = VERR_INVALID_PARAMETER; … … 2338 2577 } 2339 2578 2340 VBVAENABLE *pEnable = (VBVAENABLE *)pvBuffer; 2341 unsigned uScreenId; 2342 if (pEnable->u32Flags & VBVA_F_EXTENDED) 2343 { 2344 if (cbBuffer < sizeof (VBVAENABLE_EX)) 2579 VBVAENABLE *pVbvaEnable = (VBVAENABLE *)pvBuffer; 2580 2581 uint32_t u32ScreenId; 2582 const uint32_t u32Flags = pVbvaEnable->u32Flags; 2583 if (u32Flags & VBVA_F_EXTENDED) 2584 { 2585 if (cbBuffer < sizeof(VBVAENABLE_EX)) 2345 2586 { 2346 2587 rc = VERR_INVALID_PARAMETER; … … 2348 2589 } 2349 2590 2350 VBVAENABLE_EX *pEnableEx = (VBVAENABLE_EX *)pvBuffer;2351 u ScreenId = pEnableEx->u32ScreenId;2591 const VBVAENABLE_EX *pEnableEx = (VBVAENABLE_EX *)pvBuffer; 2592 u32ScreenId = pEnableEx->u32ScreenId; 2352 2593 } 2353 2594 else 2354 2595 { 2355 uScreenId = vbvaViewFromOffset (pIns, pCtx, pvBuffer); 2356 } 2357 2358 if (uScreenId == ~0U) 2596 u32ScreenId = vbvaViewFromBufferPtr(pIns, pCtx, pvBuffer); 2597 } 2598 2599 rc = vbvaHandleEnable(pVGAState, pVbvaEnable, u32ScreenId); 2600 2601 pVbvaEnable->i32Result = rc; 2602 } break; 2603 2604 case VBVA_MOUSE_POINTER_SHAPE: 2605 { 2606 if (cbBuffer < sizeof(VBVAMOUSEPOINTERSHAPE)) 2359 2607 { 2360 2608 rc = VERR_INVALID_PARAMETER; … … 2362 2610 } 2363 2611 2364 LogFlowFunc(("VBVA_ENABLE[%d]: u32Flags 0x%x u32Offset 0x%x\n", 2365 uScreenId, pEnable->u32Flags, pEnable->u32Offset)); 2366 2367 if ((pEnable->u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_ENABLE) 2368 { 2369 /* Guest reported offset relative to view. */ 2370 uint32_t u32Offset = pEnable->u32Offset; 2371 if (!(pEnable->u32Flags & VBVA_F_ABSOFFSET)) 2372 { 2373 u32Offset += pCtx->aViews[uScreenId].view.u32ViewOffset; 2374 } 2375 2376 VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost (pIns, u32Offset); 2377 2378 if (pVBVA) 2379 { 2380 /* Process any pending orders and empty the VBVA ring buffer. */ 2381 vbvaFlush (pVGAState, pCtx); 2382 2383 rc = vbvaEnable (uScreenId, pVGAState, pCtx, pVBVA, u32Offset, false /* fRestored */); 2384 } 2385 else 2386 { 2387 Log(("Invalid VBVABUFFER offset 0x%x!!!\n", 2388 pEnable->u32Offset)); 2389 rc = VERR_INVALID_PARAMETER; 2390 } 2391 } 2392 else if ((pEnable->u32Flags & (VBVA_F_ENABLE | VBVA_F_DISABLE)) == VBVA_F_DISABLE) 2393 { 2394 rc = vbvaDisable (uScreenId, pVGAState, pCtx); 2395 } 2396 else 2397 { 2398 Log(("Invalid VBVA_ENABLE flags 0x%x!!!\n", 2399 pEnable->u32Flags)); 2400 rc = VERR_INVALID_PARAMETER; 2401 } 2402 2403 pEnable->i32Result = rc; 2612 VBVAMOUSEPOINTERSHAPE *pShape = (VBVAMOUSEPOINTERSHAPE *)pvBuffer; 2613 rc = vbvaMousePointerShape(pVGAState, pCtx, pShape, cbBuffer); 2614 2615 pShape->i32Result = rc; 2404 2616 } break; 2405 2617 2406 case VBVA_MOUSE_POINTER_SHAPE: 2407 { 2408 if (cbBuffer < sizeof (VBVAMOUSEPOINTERSHAPE)) 2618 2619 #ifdef VBOX_WITH_VIDEOHWACCEL 2620 case VBVA_VHWA_CMD: 2621 { 2622 if (cbBuffer < sizeof(VBOXVHWACMD)) 2409 2623 { 2410 2624 rc = VERR_INVALID_PARAMETER; 2411 2625 break; 2412 2626 } 2413 2414 VBVAMOUSEPOINTERSHAPE *pShape = (VBVAMOUSEPOINTERSHAPE *)pvBuffer; 2415 2416 LogFlowFunc(("VBVA_MOUSE_POINTER_SHAPE: i32Result 0x%x, fu32Flags 0x%x, hot spot %d,%d, size %dx%d\n", 2417 pShape->i32Result, 2418 pShape->fu32Flags, 2419 pShape->u32HotX, 2420 pShape->u32HotY, 2421 pShape->u32Width, 2422 pShape->u32Height)); 2423 2424 rc = vbvaMousePointerShape (pVGAState, pCtx, pShape, cbBuffer); 2425 2426 pShape->i32Result = rc; 2627 vbvaVHWAHandleCommand(pVGAState, (PVBOXVHWACMD)pvBuffer); 2427 2628 } break; 2428 2429 2430 #ifdef VBOX_WITH_VIDEOHWACCEL 2431 case VBVA_VHWA_CMD: 2432 { 2433 if (cbBuffer < sizeof (VBOXVHWACMD)) 2434 { 2435 rc = VERR_INVALID_PARAMETER; 2436 break; 2437 } 2438 vbvaVHWAHandleCommand(pVGAState, (PVBOXVHWACMD)pvBuffer); 2439 rc = VINF_SUCCESS; 2440 break; 2441 } break; 2442 #endif 2629 #endif /* VBOX_WITH_VIDEOHWACCEL */ 2443 2630 2444 2631 #ifdef VBOX_WITH_WDDM 2445 2632 case VBVA_INFO_CAPS: 2446 2633 { 2447 if (cbBuffer < sizeof 2634 if (cbBuffer < sizeof(VBVACAPS)) 2448 2635 { 2449 2636 rc = VERR_INVALID_PARAMETER; … … 2454 2641 pVGAState->fGuestCaps = pCaps->fCaps; 2455 2642 pVGAState->pDrv->pfnVBVAGuestCapabilityUpdate(pVGAState->pDrv, 2456 p Caps->fCaps);2643 pVGAState->fGuestCaps); 2457 2644 pCaps->rc = VINF_SUCCESS; 2458 2645 } break; 2459 #endif 2646 #endif /* VBOX_WITH_WDDM */ 2647 2460 2648 case VBVA_SCANLINE_CFG: 2461 2649 { 2462 if (cbBuffer < sizeof 2650 if (cbBuffer < sizeof(VBVASCANLINECFG)) 2463 2651 { 2464 2652 rc = VERR_INVALID_PARAMETER; … … 2478 2666 break; 2479 2667 } 2480 VBVAQUERYMODEHINTS *pModeHintQuery = (VBVAQUERYMODEHINTS*)pvBuffer; 2481 LogRelFlowFunc(("VBVA_QUERY_MODE_HINTS: cHintsQueried=%u, cbHintStructureGuest=%u\n", 2482 (unsigned)pModeHintQuery->cHintsQueried, 2483 (unsigned)pModeHintQuery->cbHintStructureGuest)); 2484 if (cbBuffer < sizeof (VBVAQUERYMODEHINTS) 2485 + (uint64_t)pModeHintQuery->cHintsQueried 2486 * pModeHintQuery->cbHintStructureGuest) 2487 { 2488 pModeHintQuery->rc = VERR_INVALID_PARAMETER; 2489 break; 2490 } 2491 pModeHintQuery->rc = VINF_SUCCESS; 2492 uint8_t *pbHint = (uint8_t *)pvBuffer + sizeof(VBVAQUERYMODEHINTS); 2493 memset(pbHint, ~0, cbBuffer - sizeof(VBVAQUERYMODEHINTS)); 2494 unsigned iHint; 2495 for (iHint = 0; iHint < pModeHintQuery->cHintsQueried 2496 && iHint < VBOX_VIDEO_MAX_SCREENS; ++iHint) 2497 { 2498 memcpy(pbHint, &pCtx->aModeHints[iHint], 2499 RT_MIN(pModeHintQuery->cbHintStructureGuest, 2500 sizeof(VBVAMODEHINT))); 2501 pbHint += pModeHintQuery->cbHintStructureGuest; 2502 Assert(pbHint - (uint8_t *)pvBuffer <= cbBuffer); 2503 } 2668 2669 VBVAQUERYMODEHINTS *pQueryModeHints = (VBVAQUERYMODEHINTS*)pvBuffer; 2670 rc = vbvaHandleQueryModeHints(pVGAState, pQueryModeHints, cbBuffer); 2671 pQueryModeHints->rc = rc; 2504 2672 } break; 2505 2673 2506 2674 case VBVA_REPORT_INPUT_MAPPING: 2507 2675 { 2508 if (cbBuffer !=sizeof(VBVAREPORTINPUTMAPPING))2676 if (cbBuffer < sizeof(VBVAREPORTINPUTMAPPING)) 2509 2677 { 2510 2678 rc = VERR_INVALID_PARAMETER; 2511 2679 break; 2512 2680 } 2513 VBVAREPORTINPUTMAPPING *pReport = (VBVAREPORTINPUTMAPPING *)pvBuffer; 2514 LogRelFlowFunc(("VBVA_REPORT_INPUT_MAPPING: x=%u, y=%u, cx=%u, cy=%u\n", (unsigned)pReport->x, (unsigned)pReport->y, 2515 (unsigned)pReport->cx, (unsigned)pReport->cy)); 2516 pVGAState->pDrv->pfnVBVAInputMappingUpdate(pVGAState->pDrv, pReport->x, pReport->y, pReport->cx, pReport->cy); 2681 2682 const VBVAREPORTINPUTMAPPING inputMapping = *(VBVAREPORTINPUTMAPPING *)pvBuffer; 2683 LogRelFlowFunc(("VBVA_REPORT_INPUT_MAPPING: x=%RI32, y=%RI32, cx=%RU32, cy=%RU32\n", 2684 inputMapping.x, inputMapping.y, inputMapping.cx, inputMapping.cy)); 2685 pVGAState->pDrv->pfnVBVAInputMappingUpdate(pVGAState->pDrv, 2686 inputMapping.x, inputMapping.y, 2687 inputMapping.cx, inputMapping.cy); 2517 2688 } break; 2518 2689 2519 2690 case VBVA_CURSOR_POSITION: 2520 2691 { 2521 if (cbBuffer !=sizeof(VBVACURSORPOSITION))2692 if (cbBuffer < sizeof(VBVACURSORPOSITION)) 2522 2693 { 2523 2694 rc = VERR_INVALID_PARAMETER; 2524 2695 break; 2525 2696 } 2526 VBVACURSORPOSITION *pReport 2527 = (VBVACURSORPOSITION *)pvBuffer; 2528 LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=%RTbool", 2529 RT_BOOL(pReport->fReportPosition))); 2530 if (RT_BOOL(pReport->fReportPosition)) 2531 LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=true, x=%u, y=%u\n", 2532 (unsigned)pReport->x, (unsigned)pReport->y)); 2533 else 2534 LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=false\n")); 2697 2698 VBVACURSORPOSITION *pReport = (VBVACURSORPOSITION *)pvBuffer; 2699 2700 LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=%RTbool, x=%RU32, y=%RU32\n", 2701 RT_BOOL(pReport->fReportPosition), pReport->x, pReport->y)); 2702 2535 2703 pReport->x = pCtx->xCursor; 2536 2704 pReport->y = pCtx->yCursor; … … 2618 2786 if (RT_SUCCESS (rc)) 2619 2787 { 2620 if (!pCtx->aViews[0]. pVBVA)2788 if (!pCtx->aViews[0].vbva.guest.pVBVA) 2621 2789 { 2622 2790 /* VBVA is not enabled for the first view, so VGA device must do updates. */
Note:
See TracChangeset
for help on using the changeset viewer.