VirtualBox

Ignore:
Timestamp:
Oct 24, 2021 12:42:46 PM (3 years ago)
Author:
vboxsync
Message:

SharedClipboard: Corrected another pvData assertion preventing zero byte replies from getting thru in the VBOX_SHCL_GUEST_FN_DATA_WRITE path, causing waiting host clipboard code to get stuck waiting/timeout. Introduced in r135860, possibly by accident and probably not help by zero documentation around ShClSvcGuestDataSignal at that time. Made the code signal the waiter even if we fail to duplicate the data. bugref:10094

File:
1 edited

Legend:

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

    r91749 r92017  
    13411341 *
    13421342 * @returns VBox status code. Returns VERR_NOT_FOUND when related event ID was not found.
    1343  * @param   pClient             Client the guest clipboard data was received for.
    1344  * @param   pCmdCtx             Client command context to use.
     1343 * @param   pClient             Client the guest clipboard data was received from.
     1344 * @param   pCmdCtx             Client command context.
    13451345 * @param   uFormat             Clipboard format of data received.
    1346  * @param   pvData              Pointer to clipboard data received.
     1346 * @param   pvData              Pointer to clipboard data received.  This can be
     1347 *                              NULL if @a cbData is zero.
    13471348 * @param   cbData              Size (in bytes) of clipboard data received.
    1348  */
    1349 int ShClSvcGuestDataSignal(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
    1350                            SHCLFORMAT uFormat, void *pvData, uint32_t cbData)
    1351 {
     1349 *                              This can be zero.
     1350 */
     1351int ShClSvcGuestDataSignal(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData)
     1352{
     1353    LogFlowFuncEnter();
     1354    RT_NOREF(uFormat);
     1355
     1356    /*
     1357     * Validate intput.
     1358     */
    13521359    AssertPtrReturn(pClient, VERR_INVALID_POINTER);
    13531360    AssertPtrReturn(pCmdCtx, VERR_INVALID_POINTER);
    1354     AssertPtrReturn(pvData,  VERR_INVALID_POINTER);
    1355 
    1356     RT_NOREF(uFormat);
    1357 
    1358     LogFlowFuncEnter();
     1361    if (cbData > 0)
     1362        AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    13591363
    13601364    const SHCLEVENTID idEvent = VBOX_SHCL_CONTEXTID_GET_EVENT(pCmdCtx->uContextID);
    1361 
    1362     AssertMsgReturn(idEvent != NIL_SHCLEVENTID,
    1363                     ("Event %RU64 empty within supplied context ID\n", idEvent), VERR_WRONG_ORDER);
    1364 #ifdef VBOX_STRICT
    1365     AssertMsgReturn(ShClEventGet(&pClient->EventSrc, idEvent) != NULL,
    1366                     ("Event %RU64 not found, even if context ID was around\n", idEvent), VERR_NOT_FOUND);
    1367 #endif
    1368 
     1365    AssertMsgReturn(idEvent != NIL_SHCLEVENTID, ("NIL event in context ID %#RX64\n", pCmdCtx->uContextID), VERR_WRONG_ORDER);
     1366    AssertMsg(ShClEventGet(&pClient->EventSrc, idEvent) != NULL, ("Event %#x not found\n", idEvent));
     1367
     1368    /*
     1369     * Make a copy of the data so we can attach it to the signal.
     1370     *
     1371     * Note! We still signal the waiter should we run out of memory,
     1372     *       because otherwise it will be stuck waiting.
     1373     */
    13691374    int rc = VINF_SUCCESS;
    1370 
    13711375    PSHCLEVENTPAYLOAD pPayload = NULL;
    1372     if (cbData)
     1376    if (cbData > 0)
    13731377        rc = ShClPayloadAlloc(idEvent, pvData, cbData, &pPayload);
    13741378
    1375     if (RT_SUCCESS(rc))
    1376     {
    1377         RTCritSectEnter(&pClient->CritSect);
    1378         rc = ShClEventSignal(&pClient->EventSrc, idEvent, pPayload);
    1379         RTCritSectLeave(&pClient->CritSect);
    1380         if (RT_FAILURE(rc))
    1381             ShClPayloadFree(pPayload);
    1382 
    1383         /* No one holding a reference to the event anymore? Unregister it. */
    1384         if (ShClEventGetRefs(&pClient->EventSrc, idEvent) == 0)
    1385         {
    1386             int rc2 = ShClEventUnregister(&pClient->EventSrc, idEvent);
    1387             if (RT_SUCCESS(rc))
    1388                 rc = rc2;
    1389         }
    1390     }
    1391 
    1392     if (RT_FAILURE(rc))
    1393         LogRel(("Shared Clipboard: Signalling of guest clipboard data to the host failed with %Rrc\n", rc));
     1379    /*
     1380     * Signal the event.
     1381     */
     1382    RTCritSectEnter(&pClient->CritSect);
     1383    int rc2 = ShClEventSignal(&pClient->EventSrc, idEvent, pPayload);
     1384    RTCritSectLeave(&pClient->CritSect);
     1385    if (RT_FAILURE(rc2))
     1386    {
     1387        rc = rc2;
     1388        ShClPayloadFree(pPayload);
     1389        LogRel(("Shared Clipboard: Signalling of guest clipboard data to the host failed: %Rrc\n", rc));
     1390    }
     1391
     1392    /*
     1393     * No one holding a reference to the event anymore? Unregister it.
     1394     */
     1395    /** @todo r=bird: This isn't how reference counting is supposed to be
     1396     *        implemented, is it now? */
     1397    if (ShClEventGetRefs(&pClient->EventSrc, idEvent) == 0)
     1398    {
     1399        rc2 = ShClEventUnregister(&pClient->EventSrc, idEvent);
     1400        if (RT_SUCCESS(rc))
     1401            rc = rc2;
     1402    }
    13941403
    13951404    LogFlowFuncLeaveRC(rc);
Note: See TracChangeset for help on using the changeset viewer.

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