VirtualBox

Ignore:
Timestamp:
Jul 10, 2019 1:02:50 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
131985
Message:

Shared Clipboard/URI: More code for root entries handling.

Location:
trunk/src/VBox/HostServices/SharedClipboard
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp

    r79630 r79672  
    7373}
    7474
     75DECLCALLBACK(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
    75185DECLCALLBACK(int) vboxSvcClipboardURIListOpen(PSHAREDCLIPBOARDPROVIDERCTX pCtx,
    76186                                              PVBOXCLIPBOARDLISTOPENPARMS pOpenParms, PSHAREDCLIPBOARDLISTHANDLE phList)
     
    403513                    break;
    404514            }
     515        }
     516    }
     517    else
     518        rc = VERR_INVALID_PARAMETER;
     519
     520    LogFlowFuncLeaveRC(rc);
     521    return rc;
     522}
     523
     524int 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);
    405550        }
    406551    }
     
    582727            rc = HGCMSvcGetU32(&paParms[2], &pListEntry->fInfo);
    583728        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        }
    587740
    588741        if (RT_SUCCESS(rc))
     
    846999                        if (enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
    8471000                        {
     1001                            creationCtx.Interface.pfnGetRoots      = vboxSvcClipboardURIGetRoots;
    8481002                            creationCtx.Interface.pfnListHdrRead   = vboxSvcClipboardURIListHdrRead;
    8491003                            creationCtx.Interface.pfnListEntryRead = vboxSvcClipboardURIListEntryRead;
     
    9211075        {
    9221076            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            }
    9231096            break;
    9241097        }
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r79632 r79672  
    507507     * Return information about the first message if one is pending in the list.
    508508     */
    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)
    551543                {
    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;
    561572                }
    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. */
    567591            }
    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;
    586595        }
    587 
    588         LogFlowFunc(("[Client %RU32] Returning %Rrc\n", pClient->uClientID, rc));
    589         return rc;
    590596    }
    591597
     
    13911397#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    13921398            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;
    13981402#else
    13991403            rc = VERR_NOT_IMPLEMENTED;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette