VirtualBox

Changeset 86006 in vbox for trunk/src


Ignore:
Timestamp:
Sep 2, 2020 5:29:20 PM (4 years ago)
Author:
vboxsync
Message:

Shared Clipboard/Host Service: Use and check for a context ID (CID) in ShClSvcGuestDataRequest() / shClSvcClientWriteData() for old(er) Guest Additions; follow-up for r140195. bugref:9437

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h

    r86002 r86006  
    9999
    100100/**
     101 * Strucutre needed to support backwards compatbility for old(er) Guest Additions (< 6.1),
     102 * which did not know the context ID concept then.
     103 */
     104typedef struct SHCLCLIENTLEGACYCID
     105{
     106    /** List node. */
     107    RTLISTNODE Node;
     108    /** The actual context ID. */
     109    uint64_t   uCID;
     110    /** Not used yet; useful to have it in the saved state though. */
     111    uint32_t   enmType;
     112    /** @todo Add an union here as soon as we utilize \a enmType. */
     113    SHCLFORMAT uFormat;
     114} SHCLCLIENTLEGACYCID;
     115/** Pointer to a SHCLCLIENTLEGACYCID struct. */
     116typedef SHCLCLIENTLEGACYCID *PSHCLCLIENTLEGACYCID;
     117
     118/**
    101119 * Strucutre for keeping legacy state, required for keeping backwards compatibility
    102120 * to old(er) Guest Additions.
     
    104122typedef struct SHCLCLIENTLEGACYSTATE
    105123{
    106     /** Context ID required for an incoming VBOX_SHCL_GUEST_FN_DATA_WRITE call. Set to UINT64_MAX if not in use.
    107      *  Required for:
    108      *      - Guest Additions < 6.1. */
    109     uint64_t idCtxWriteData;
     124    /** List of context IDs (of type SHCLCLIENTLEGACYCID) for older Guest Additions which (< 6.1)
     125     *  which did not know the concept of context IDs. */
     126    RTLISTANCHOR lstCID;
     127    /** Number of context IDs currently in \a lstCID. */
     128    uint16_t     cCID;
    110129} SHCLCLIENTLEGACYSTATE;
    111130
     
    135154    /** Client state flags of type SHCLCLIENTSTATE_FLAGS_. */
    136155    uint32_t                fFlags;
    137     /** Legacy cruft we have to keep to support old(er) Guest Additions. */
    138     SHCLCLIENTLEGACYSTATE   Legacy;
    139156    /** POD (plain old data) state. */
    140157    SHCLCLIENTPODSTATE      POD;
     
    158175    /** Number of allocated messages (updated atomically, not under critsect). */
    159176    uint32_t volatile           cAllocatedMessages;
     177    /** Legacy cruft we have to keep to support old(er) Guest Additions. */
     178    SHCLCLIENTLEGACYSTATE       Legacy;
    160179    /** The client's own event source.
    161180     *  Needed for events which are not bound to a specific transfer. */
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r86002 r86006  
    251251 * @{ */
    252252/** The current saved state version. */
    253 #define VBOX_SHCL_SAVED_STATE_VER_CURRENT   VBOX_SHCL_SAVED_STATE_VER_6_1RC1
     253#define VBOX_SHCL_SAVED_STATE_VER_CURRENT   VBOX_SHCL_SAVED_STATE_LEGACY_CID
     254/** Adds the legacy context ID list. */
     255#define VBOX_SHCL_SAVED_STATE_LEGACY_CID    UINT32_C(0x80000005)
    254256/** Adds the client's POD state and client state flags.
    255257 * @since 6.1 RC1 */
     
    380382        shClSvcMsgFree(pClient, pMsg);
    381383    }
     384    /** @todo r=andy Don't we also need to reset pClient->cAllocatedMessages here? */
     385
     386    while (!RTListIsEmpty(&pClient->Legacy.lstCID))
     387    {
     388        PSHCLCLIENTLEGACYCID pCID = RTListRemoveFirst(&pClient->Legacy.lstCID, SHCLCLIENTLEGACYCID, Node);
     389        RTMemFree(pCID);
     390    }
     391    pClient->Legacy.cCID = 0;
    382392}
    383393
     
    556566    /* Assign the client ID. */
    557567    pClient->State.uClientID = uClientID;
     568
    558569    RTListInit(&pClient->MsgQueue);
    559570    pClient->cAllocatedMessages = 0;
     571
     572    RTListInit(&pClient->Legacy.lstCID);
     573    pClient->Legacy.cCID = 0;
    560574
    561575    LogFlowFunc(("[Client %RU32]\n", pClient->State.uClientID));
     
    12071221    SHCLEVENTID idEvent = NIL_SHCLEVENTID;
    12081222
     1223    /* Generate a separate message for every (valid) format we support. */
    12091224    while (fFormats)
    12101225    {
     
    12471262                rc = VINF_SUCCESS;
    12481263
    1249                 /* Save the context ID in our legacy cruft if we have to deal with old(er) Guest Additions (< 6.1.). */
     1264                /* Save the context ID in our legacy cruft if we have to deal with old(er) Guest Additions (< 6.1). */
    12501265                if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID))
    12511266                {
    1252                     /* Only one data request at a time is supported. */
    1253                     AssertStmt(pClient->State.Legacy.idCtxWriteData == UINT64_MAX, rc = VERR_WRONG_ORDER);
     1267                    AssertStmt(pClient->Legacy.cCID < 4096, rc = VERR_TOO_MUCH_DATA);
    12541268                    if (RT_SUCCESS(rc))
    1255                         pClient->State.Legacy.idCtxWriteData = uCID;
     1269                    {
     1270                        PSHCLCLIENTLEGACYCID pCID = (PSHCLCLIENTLEGACYCID)RTMemAlloc(sizeof(SHCLCLIENTLEGACYCID));
     1271                        if (pCID)
     1272                        {
     1273                            pCID->uCID = uCID;
     1274                            RTListAppend(&pClient->Legacy.lstCID, &pCID->Node);
     1275                            pClient->Legacy.cCID++;
     1276                        }
     1277                        else
     1278                            rc = VERR_NO_MEMORY;
     1279                    }
    12561280                }
    12571281
     
    16641688        return VERR_ACCESS_DENIED;
    16651689
     1690    const bool fReportsContextID = RT_BOOL(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID);
     1691
    16661692    /*
    16671693     * Digest parameters.
     
    16701696     * switch around so it's plain sailing compared to the DATA_READ message.
    16711697     */
    1672     ASSERT_GUEST_RETURN(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID
     1698    ASSERT_GUEST_RETURN(fReportsContextID
    16731699                        ? cParms == VBOX_SHCL_CPARMS_DATA_WRITE || cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B
    16741700                        : cParms == VBOX_SHCL_CPARMS_DATA_WRITE_OLD,
     
    16841710        iParm++;
    16851711    }
    1686     else /* Older Guest Additions (< 6.1) did not supply a context ID. Dig it out of our legacy cruft. */
    1687     {
    1688         cmdCtx.uContextID = pClient->State.Legacy.idCtxWriteData;
    1689         pClient->State.Legacy.idCtxWriteData = UINT64_MAX; /* Reset. */
     1712    else
     1713    {
     1714        /* Older Guest Additions (< 6.1) did not supply a context ID.
     1715         * We dig it out from our saved context ID list then a bit down below. */
     1716    }
     1717
     1718    if (cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B)
     1719    {
     1720        ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE);
     1721        ASSERT_GUEST_RETURN(paParms[iParm].u.uint32 == 0, VERR_INVALID_FLAGS);
     1722        iParm++;
     1723    }
     1724
     1725    SHCLFORMAT  uFormat = VBOX_SHCL_FMT_NONE;
     1726    uint32_t    cbData  = 0;
     1727    void       *pvData  = NULL;
     1728
     1729    ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE); /* Format bit. */
     1730    uFormat = paParms[iParm].u.uint32;
     1731    iParm++;
     1732    if (cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B)
     1733    {
     1734        ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE); /* "cbData" - duplicates buffer size. */
     1735        iParm++;
     1736    }
     1737    ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_PTR, VERR_WRONG_PARAMETER_TYPE); /* Data buffer */
     1738    pvData = paParms[iParm].u.pointer.addr;
     1739    cbData = paParms[iParm].u.pointer.size;
     1740    iParm++;
     1741    Assert(iParm == cParms);
     1742
     1743    /*
     1744     * Handle / check context ID.
     1745     */
     1746    if (!fReportsContextID) /* Do we have to deal with old(er) GAs (< 6.1) which don't support context IDs? Dig out the context ID then. */
     1747    {
     1748        PSHCLCLIENTLEGACYCID pCID = NULL;
     1749        RTListForEach(&pClient->Legacy.lstCID, pCID, SHCLCLIENTLEGACYCID, Node) /* Slow, but does the job for now. */
     1750        {
     1751            if (pCID->uFormat == uFormat)
     1752                break;
     1753        }
     1754
     1755        ASSERT_GUEST_MSG_RETURN(pCID != NULL, ("Context ID for format %#x not found\n", uFormat), VERR_INVALID_CONTEXT);
     1756        cmdCtx.uContextID = pCID->uCID;
     1757
     1758        /* Not needed anymore; clean up. */
     1759        Assert(pClient->Legacy.cCID);
     1760        pClient->Legacy.cCID--;
     1761        RTListNodeRemove(&pCID->Node);
     1762        RTMemFree(pCID);
    16901763    }
    16911764
     
    16951768                            ("Wrong context ID: %#RX64, expected %#RX64\n", cmdCtx.uContextID, idCtxExpected),
    16961769                            VERR_INVALID_CONTEXT);
    1697 
    1698     if (cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B)
    1699     {
    1700         ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE);
    1701         ASSERT_GUEST_RETURN(paParms[iParm].u.uint32 == 0, VERR_INVALID_FLAGS);
    1702         iParm++;
    1703     }
    1704 
    1705     SHCLFORMAT  uFormat = VBOX_SHCL_FMT_NONE;
    1706     uint32_t    cbData  = 0;
    1707     void       *pvData  = NULL;
    1708 
    1709     ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE); /* Format bit. */
    1710     uFormat = paParms[iParm].u.uint32;
    1711     iParm++;
    1712     if (cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B)
    1713     {
    1714         ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE); /* "cbData" - duplicates buffer size. */
    1715         iParm++;
    1716     }
    1717     ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_PTR, VERR_WRONG_PARAMETER_TYPE); /* Data buffer */
    1718     pvData = paParms[iParm].u.pointer.addr;
    1719     cbData = paParms[iParm].u.pointer.size;
    1720     iParm++;
    1721     Assert(iParm == cParms);
    17221770
    17231771    /*
     
    21242172    pClientState->Transfers.enmTransferDir = SHCLTRANSFERDIR_UNKNOWN;
    21252173#endif
    2126 
    2127     pClientState->Legacy.idCtxWriteData    = UINT64_MAX;
    21282174}
    21292175
     
    22132259
    22142260#ifndef UNIT_TEST
     2261
     2262/**
     2263 * SSM descriptor table for the SHCLCLIENTLEGACYCID structure.
     2264 *
     2265 * @note Saving the ListEntry attribute is not necessary, as this gets used on runtime only.
     2266 */
     2267static SSMFIELD const s_aShClSSMClientLegacyCID[] =
     2268{
     2269    SSMFIELD_ENTRY(SHCLCLIENTLEGACYCID, uCID),
     2270    SSMFIELD_ENTRY(SHCLCLIENTLEGACYCID, enmType),
     2271    SSMFIELD_ENTRY(SHCLCLIENTLEGACYCID, uFormat),
     2272    SSMFIELD_ENTRY_TERM()
     2273};
     2274
    22152275/**
    22162276 * SSM descriptor table for the SHCLCLIENTSTATE structure.
     
    23152375
    23162376    /* Serialize the client's internal message queue. */
     2377    /** @todo r=andy Why not using pClient->cAllocatedMessages here? */
    23172378    uint32_t cMsgs = 0;
    23182379    PSHCLCLIENTMSG pMsg;
    23192380    RTListForEach(&pClient->MsgQueue, pMsg, SHCLCLIENTMSG, ListEntry)
    2320     {
    23212381        cMsgs += 1;
    2322     }
    23232382
    23242383    rc = SSMR3PutU64(pSSM, cMsgs);
     
    23342393    }
    23352394
     2395    rc = SSMR3PutU64(pSSM, pClient->Legacy.cCID);
     2396    AssertRCReturn(rc, rc);
     2397
     2398    PSHCLCLIENTLEGACYCID pCID;
     2399    RTListForEach(&pClient->Legacy.lstCID, pCID, SHCLCLIENTLEGACYCID, Node)
     2400    {
     2401        rc = SSMR3PutStructEx(pSSM, pCID, sizeof(SHCLCLIENTLEGACYCID), 0 /*fFlags*/, &s_aShClSSMClientLegacyCID[0], NULL);
     2402        AssertRCReturn(rc, rc);
     2403    }
    23362404#else  /* UNIT_TEST */
    23372405    RT_NOREF3(u32ClientID, pvClient, pSSM);
     
    24442512
    24452513            shClSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     2514        }
     2515
     2516        if (lenOrVer >= VBOX_SHCL_SAVED_STATE_LEGACY_CID)
     2517        {
     2518            uint64_t cCID;
     2519            rc = SSMR3GetU64(pSSM, &cCID);
     2520            AssertRCReturn(rc, rc);
     2521            AssertLogRelMsgReturn(cCID < _16K, ("Too many context IDs: %u (%x)\n", cCID, cCID), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     2522
     2523            for (uint64_t i = 0; i < cCID; i++)
     2524            {
     2525                PSHCLCLIENTLEGACYCID pCID = (PSHCLCLIENTLEGACYCID)RTMemAlloc(sizeof(SHCLCLIENTLEGACYCID));
     2526                AssertPtrReturn(pCID, VERR_NO_MEMORY);
     2527
     2528                SSMR3GetStructEx(pSSM, pCID, sizeof(SHCLCLIENTLEGACYCID), 0 /* fFlags */, &s_aShClSSMClientLegacyCID[0], NULL);
     2529                RTListAppend(&pClient->Legacy.lstCID, &pCID->Node);
     2530            }
    24462531        }
    24472532    }
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