Changeset 79672 in vbox for trunk/src/VBox/HostServices/SharedClipboard
- Timestamp:
- Jul 10, 2019 1:02:50 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 131985
- Location:
- trunk/src/VBox/HostServices/SharedClipboard
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp
r79630 r79672 73 73 } 74 74 75 DECLCALLBACK(int) vboxSvcClipboardURIGetRoots(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 76 char **ppapszRoots, uint32_t *pcRoots) 77 { 78 LogFlowFuncEnter(); 79 80 PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pCtx->pvUser; 81 AssertPtr(pClient); 82 83 int rc; 84 85 size_t cbRootsRecv = 0; 86 87 char *pszRoots = NULL; 88 uint32_t cRoots = 0; 89 90 /* There might be more than one message needed for retrieving all root items. */ 91 for (;;) 92 { 93 PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOTS, 94 VBOX_SHARED_CLIPBOARD_CPARMS_ROOTS); 95 if (pMsg) 96 { 97 HGCMSvcSetU32(&pMsg->m_paParms[0], 0 /* uContextID */); 98 HGCMSvcSetU32(&pMsg->m_paParms[1], 0 /* fRoots */); 99 HGCMSvcSetU32(&pMsg->m_paParms[2], 0 /* fMore */); 100 HGCMSvcSetU32(&pMsg->m_paParms[3], 0 /* cRoots */); 101 102 uint32_t cbData = _64K; 103 void *pvData = RTMemAlloc(cbData); 104 AssertPtrBreakStmt(pvData, rc = VERR_NO_MEMORY); 105 106 HGCMSvcSetU32(&pMsg->m_paParms[4], cbData); 107 HGCMSvcSetPv (&pMsg->m_paParms[5], pvData, cbData); 108 109 rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */); 110 if (RT_SUCCESS(rc)) 111 { 112 int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, 113 SHAREDCLIPBOARDURITRANSFEREVENTTYPE_GET_ROOTS); 114 AssertRC(rc2); 115 116 vboxSvcClipboardClientWakeup(pClient); 117 } 118 } 119 else 120 rc = VERR_NO_MEMORY; 121 122 if (RT_SUCCESS(rc)) 123 { 124 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload; 125 rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_GET_ROOTS, 126 30 * 1000 /* Timeout in ms */, &pPayload); 127 if (RT_SUCCESS(rc)) 128 { 129 PVBOXCLIPBOARDROOTS pRoots = (PVBOXCLIPBOARDROOTS)pPayload->pvData; 130 Assert(pPayload->cbData == sizeof(VBOXCLIPBOARDROOTS)); 131 132 LogFlowFunc(("cbRoots=%RU32, fRoots=%RU32, fMore=%RTbool\n", pRoots->cbRoots, pRoots->fRoots, pRoots->fMore)); 133 134 if (!pRoots->cbRoots) 135 break; 136 AssertPtr(pRoots->pszRoots); 137 138 if (pszRoots == NULL) 139 pszRoots = (char *)RTMemDup((void *)pRoots->pszRoots, pRoots->cbRoots); 140 else 141 pszRoots = (char *)RTMemRealloc(pszRoots, cbRootsRecv + pRoots->cbRoots); 142 143 AssertPtrBreakStmt(pszRoots, rc = VERR_NO_MEMORY); 144 145 cbRootsRecv += pRoots->cbRoots; 146 147 if (cbRootsRecv > _32M) /* Don't allow more than 32MB root entries for now. */ 148 { 149 rc = VERR_ALLOCATION_TOO_BIG; /** @todo Find a better rc. */ 150 break; 151 } 152 153 cRoots += pRoots->cRoots; 154 155 const bool fDone = !RT_BOOL(pRoots->fMore); /* More root entries to be retrieved? Otherwise bail out. */ 156 157 SharedClipboardURITransferPayloadFree(pPayload); 158 159 if (fDone) 160 break; 161 } 162 } 163 164 if (RT_FAILURE(rc)) 165 break; 166 } 167 168 if (RT_SUCCESS(rc)) 169 { 170 LogFlowFunc(("cRoots=%RU32\n", cRoots)); 171 172 *ppapszRoots = pszRoots; 173 *pcRoots = cRoots; 174 } 175 else 176 { 177 RTMemFree(pszRoots); 178 pszRoots = NULL; 179 } 180 181 LogFlowFuncLeave(); 182 return rc; 183 } 184 75 185 DECLCALLBACK(int) vboxSvcClipboardURIListOpen(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 76 186 PVBOXCLIPBOARDLISTOPENPARMS pOpenParms, PSHAREDCLIPBOARDLISTHANDLE phList) … … 403 513 break; 404 514 } 515 } 516 } 517 else 518 rc = VERR_INVALID_PARAMETER; 519 520 LogFlowFuncLeaveRC(rc); 521 return rc; 522 } 523 524 int VBoxSvcClipboardURIGetRoots(uint32_t cParms, VBOXHGCMSVCPARM paParms[], 525 PVBOXCLIPBOARDROOTS pRoots) 526 { 527 int rc; 528 529 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_ROOTS) 530 { 531 /* Note: Context ID (paParms[0]) not used yet. */ 532 rc = HGCMSvcGetU32(&paParms[1], &pRoots->fRoots); 533 if (RT_SUCCESS(rc)) 534 { 535 uint32_t fMore; 536 rc = HGCMSvcGetU32(&paParms[2], &fMore); 537 if (RT_SUCCESS(rc)) 538 pRoots->fMore = RT_BOOL(fMore); 539 } 540 if (RT_SUCCESS(rc)) 541 rc = HGCMSvcGetU32(&paParms[3], &pRoots->cRoots); 542 if (RT_SUCCESS(rc)) 543 { 544 uint32_t cbRoots; 545 rc = HGCMSvcGetU32(&paParms[4], &cbRoots); 546 if (RT_SUCCESS(rc)) 547 rc = HGCMSvcGetPv(&paParms[5], (void **)&pRoots->pszRoots, &pRoots->cbRoots); 548 549 AssertReturn(cbRoots == pRoots->cbRoots, VERR_INVALID_PARAMETER); 405 550 } 406 551 } … … 582 727 rc = HGCMSvcGetU32(&paParms[2], &pListEntry->fInfo); 583 728 if (RT_SUCCESS(rc)) 584 rc = HGCMSvcGetU32(&paParms[3], &pListEntry->cbInfo); 585 if (RT_SUCCESS(rc)) 586 rc = HGCMSvcGetPv(&paParms[4], &pListEntry->pvInfo, &pListEntry->cbInfo); 729 rc = HGCMSvcGetPv(&paParms[3], (void **)&pListEntry->pszName, &pListEntry->cbName); 730 if (RT_SUCCESS(rc)) 731 { 732 uint32_t cbInfo; 733 rc = HGCMSvcGetU32(&paParms[4], &cbInfo); 734 if (RT_SUCCESS(rc)) 735 { 736 rc = HGCMSvcGetPv(&paParms[5], &pListEntry->pvInfo, &pListEntry->cbInfo); 737 AssertReturn(cbInfo == pListEntry->cbInfo, VERR_INVALID_PARAMETER); 738 } 739 } 587 740 588 741 if (RT_SUCCESS(rc)) … … 846 999 if (enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ) 847 1000 { 1001 creationCtx.Interface.pfnGetRoots = vboxSvcClipboardURIGetRoots; 848 1002 creationCtx.Interface.pfnListHdrRead = vboxSvcClipboardURIListHdrRead; 849 1003 creationCtx.Interface.pfnListEntryRead = vboxSvcClipboardURIListEntryRead; … … 921 1075 { 922 1076 rc = VBoxSvcClipboardURITransferHandleReply(pClient, pTransfer, cParms, paParms); 1077 break; 1078 } 1079 1080 case VBOX_SHARED_CLIPBOARD_GUEST_FN_ROOTS: 1081 { 1082 VBOXCLIPBOARDROOTS Roots; 1083 rc = VBoxSvcClipboardURIGetRoots(cParms, paParms, &Roots); 1084 if (RT_SUCCESS(rc)) 1085 { 1086 void *pvData = SharedClipboardURIRootsDup(&Roots); 1087 uint32_t cbData = sizeof(VBOXCLIPBOARDROOTS); 1088 1089 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload; 1090 rc = SharedClipboardURITransferPayloadAlloc(SHAREDCLIPBOARDURITRANSFEREVENTTYPE_GET_ROOTS, 1091 pvData, cbData, &pPayload); 1092 if (RT_SUCCESS(rc)) 1093 rc = SharedClipboardURITransferEventSignal(pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_GET_ROOTS, 1094 pPayload); 1095 } 923 1096 break; 924 1097 } -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r79632 r79672 507 507 * Return information about the first message if one is pending in the list. 508 508 */ 509 PVBOXCLIPBOARDCLIENTMSG pFirstMsg = pClient->pData->queueMsg.first(); 510 if (pFirstMsg) 511 { 512 LogFlowFunc(("First message is: %RU32 %s (%RU32 parms)\n", 513 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms)); 514 515 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_uMsg == idMsgExpected || idMsgExpected == UINT32_MAX, 516 ("idMsg=%u (%s) cParms=%u, caller expected %u (%s) and %u\n", 517 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_uMsg, 518 idMsgExpected, VBoxSvcClipboardHostMsgToStr(idMsgExpected), cParms), 519 VERR_MISMATCH); 520 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_cParms == cParms, 521 ("idMsg=%u (%s) cParms=%u, caller expected %u (%s) and %u\n", 522 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms, 523 idMsgExpected, VBoxSvcClipboardHostMsgToStr(idMsgExpected), cParms), 524 VERR_WRONG_PARAMETER_COUNT); 525 526 /* Check the parameter types. */ 527 for (uint32_t i = 0; i < cParms; i++) 528 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_paParms[i].type == paParms[i].type, 529 ("param #%u: type %u, caller expected %u (idMsg=%u %s)\n", i, pFirstMsg->m_paParms[i].type, 530 paParms[i].type, pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg)), 531 VERR_WRONG_PARAMETER_TYPE); 532 /* 533 * Copy out the parameters. 534 * 535 * No assertions on buffer overflows, and keep going till the end so we can 536 * communicate all the required buffer sizes. 537 */ 538 int rc = VINF_SUCCESS; 539 for (uint32_t i = 0; i < cParms; i++) 540 switch (pFirstMsg->m_paParms[i].type) 541 { 542 case VBOX_HGCM_SVC_PARM_32BIT: 543 paParms[i].u.uint32 = pFirstMsg->m_paParms[i].u.uint32; 544 break; 545 546 case VBOX_HGCM_SVC_PARM_64BIT: 547 paParms[i].u.uint64 = pFirstMsg->m_paParms[i].u.uint64; 548 break; 549 550 case VBOX_HGCM_SVC_PARM_PTR: 509 if (!pClient->pData->queueMsg.isEmpty()) 510 { 511 PVBOXCLIPBOARDCLIENTMSG pFirstMsg = pClient->pData->queueMsg.first(); 512 if (pFirstMsg) 513 { 514 LogFlowFunc(("First message is: %RU32 %s (%RU32 parms)\n", 515 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms)); 516 517 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_uMsg == idMsgExpected || idMsgExpected == UINT32_MAX, 518 ("idMsg=%u (%s) cParms=%u, caller expected %u (%s) and %u\n", 519 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms, 520 idMsgExpected, VBoxSvcClipboardHostMsgToStr(idMsgExpected), cParms), 521 VERR_MISMATCH); 522 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_cParms == cParms, 523 ("idMsg=%u (%s) cParms=%u, caller expected %u (%s) and %u\n", 524 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms, 525 idMsgExpected, VBoxSvcClipboardHostMsgToStr(idMsgExpected), cParms), 526 VERR_WRONG_PARAMETER_COUNT); 527 528 /* Check the parameter types. */ 529 for (uint32_t i = 0; i < cParms; i++) 530 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_paParms[i].type == paParms[i].type, 531 ("param #%u: type %u, caller expected %u (idMsg=%u %s)\n", i, pFirstMsg->m_paParms[i].type, 532 paParms[i].type, pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg)), 533 VERR_WRONG_PARAMETER_TYPE); 534 /* 535 * Copy out the parameters. 536 * 537 * No assertions on buffer overflows, and keep going till the end so we can 538 * communicate all the required buffer sizes. 539 */ 540 int rc = VINF_SUCCESS; 541 for (uint32_t i = 0; i < cParms; i++) 542 switch (pFirstMsg->m_paParms[i].type) 551 543 { 552 uint32_t const cbSrc = pFirstMsg->m_paParms[i].u.pointer.size; 553 uint32_t const cbDst = paParms[i].u.pointer.size; 554 paParms[i].u.pointer.size = cbSrc; /** @todo Check if this is safe in other layers... 555 * Update: Safe, yes, but VMMDevHGCM doesn't pass it along. */ 556 if (cbSrc <= cbDst) 557 memcpy(paParms[i].u.pointer.addr, pFirstMsg->m_paParms[i].u.pointer.addr, cbSrc); 558 else 559 rc = VERR_BUFFER_OVERFLOW; 560 break; 544 case VBOX_HGCM_SVC_PARM_32BIT: 545 paParms[i].u.uint32 = pFirstMsg->m_paParms[i].u.uint32; 546 break; 547 548 case VBOX_HGCM_SVC_PARM_64BIT: 549 paParms[i].u.uint64 = pFirstMsg->m_paParms[i].u.uint64; 550 break; 551 552 case VBOX_HGCM_SVC_PARM_PTR: 553 { 554 uint32_t const cbSrc = pFirstMsg->m_paParms[i].u.pointer.size; 555 uint32_t const cbDst = paParms[i].u.pointer.size; 556 paParms[i].u.pointer.size = cbSrc; /** @todo Check if this is safe in other layers... 557 * Update: Safe, yes, but VMMDevHGCM doesn't pass it along. */ 558 if (cbSrc <= cbDst) 559 memcpy(paParms[i].u.pointer.addr, pFirstMsg->m_paParms[i].u.pointer.addr, cbSrc); 560 else 561 { 562 AssertMsgFailed(("#%u: cbSrc=%RU32 is bigger than cbDst=%RU32\n", i, cbSrc, cbDst)); 563 rc = VERR_BUFFER_OVERFLOW; 564 } 565 break; 566 } 567 568 default: 569 AssertMsgFailed(("#%u: %u\n", i, pFirstMsg->m_paParms[i].type)); 570 rc = VERR_INTERNAL_ERROR; 571 break; 561 572 } 562 563 default: 564 AssertMsgFailed(("#%u: %u\n", i, pFirstMsg->m_paParms[i].type)); 565 rc = VERR_INTERNAL_ERROR; 566 break; 573 if (RT_SUCCESS(rc)) 574 { 575 /* 576 * Complete the message and remove the pending message unless the 577 * guest raced us and cancelled this call in the meantime. 578 */ 579 AssertPtr(g_pHelpers); 580 rc = g_pHelpers->pfnCallComplete(hCall, rc); 581 582 LogFlowFunc(("[Client %RU32] pfnCallComplete -> %Rrc\n", pClient->uClientID, rc)); 583 584 if (rc != VERR_CANCELLED) 585 { 586 pClient->pData->queueMsg.removeFirst(); 587 vboxSvcClipboardMsgFree(pFirstMsg); 588 } 589 590 return VINF_HGCM_ASYNC_EXECUTE; /* The caller must not complete it. */ 567 591 } 568 if (RT_SUCCESS(rc)) 569 { 570 /* 571 * Complete the message and remove the pending message unless the 572 * guest raced us and cancelled this call in the meantime. 573 */ 574 AssertPtr(g_pHelpers); 575 rc = g_pHelpers->pfnCallComplete(hCall, rc); 576 577 LogFlowFunc(("[Client %RU32] pfnCallComplete -> %Rrc\n", pClient->uClientID, rc)); 578 579 if (rc != VERR_CANCELLED) 580 { 581 pClient->pData->queueMsg.removeFirst(); 582 vboxSvcClipboardMsgFree(pFirstMsg); 583 } 584 585 return VINF_HGCM_ASYNC_EXECUTE; /* The caller must not complete it. */ 592 593 LogFlowFunc(("[Client %RU32] Returning %Rrc\n", pClient->uClientID, rc)); 594 return rc; 586 595 } 587 588 LogFlowFunc(("[Client %RU32] Returning %Rrc\n", pClient->uClientID, rc));589 return rc;590 596 } 591 597 … … 1391 1397 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 1392 1398 rc = vboxSvcClipboardURIHandler(pClient, callHandle, u32Function, cParms, paParms, tsArrival); 1393 if (RT_SUCCESS(rc)) 1394 { 1395 /* The URI handler does deferring on its own. */ 1396 fDefer = true; 1397 } 1399 1400 /* The URI handler does deferring on its own, so never do any call completion here. */ 1401 fDefer = true; 1398 1402 #else 1399 1403 rc = VERR_NOT_IMPLEMENTED;
Note:
See TracChangeset
for help on using the changeset viewer.