- Timestamp:
- Sep 2, 2020 5:29:20 PM (4 years ago)
- Location:
- trunk/src/VBox/HostServices/SharedClipboard
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
r86002 r86006 99 99 100 100 /** 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 */ 104 typedef 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. */ 116 typedef SHCLCLIENTLEGACYCID *PSHCLCLIENTLEGACYCID; 117 118 /** 101 119 * Strucutre for keeping legacy state, required for keeping backwards compatibility 102 120 * to old(er) Guest Additions. … … 104 122 typedef struct SHCLCLIENTLEGACYSTATE 105 123 { 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; 110 129 } SHCLCLIENTLEGACYSTATE; 111 130 … … 135 154 /** Client state flags of type SHCLCLIENTSTATE_FLAGS_. */ 136 155 uint32_t fFlags; 137 /** Legacy cruft we have to keep to support old(er) Guest Additions. */138 SHCLCLIENTLEGACYSTATE Legacy;139 156 /** POD (plain old data) state. */ 140 157 SHCLCLIENTPODSTATE POD; … … 158 175 /** Number of allocated messages (updated atomically, not under critsect). */ 159 176 uint32_t volatile cAllocatedMessages; 177 /** Legacy cruft we have to keep to support old(er) Guest Additions. */ 178 SHCLCLIENTLEGACYSTATE Legacy; 160 179 /** The client's own event source. 161 180 * Needed for events which are not bound to a specific transfer. */ -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r86002 r86006 251 251 * @{ */ 252 252 /** 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) 254 256 /** Adds the client's POD state and client state flags. 255 257 * @since 6.1 RC1 */ … … 380 382 shClSvcMsgFree(pClient, pMsg); 381 383 } 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; 382 392 } 383 393 … … 556 566 /* Assign the client ID. */ 557 567 pClient->State.uClientID = uClientID; 568 558 569 RTListInit(&pClient->MsgQueue); 559 570 pClient->cAllocatedMessages = 0; 571 572 RTListInit(&pClient->Legacy.lstCID); 573 pClient->Legacy.cCID = 0; 560 574 561 575 LogFlowFunc(("[Client %RU32]\n", pClient->State.uClientID)); … … 1207 1221 SHCLEVENTID idEvent = NIL_SHCLEVENTID; 1208 1222 1223 /* Generate a separate message for every (valid) format we support. */ 1209 1224 while (fFormats) 1210 1225 { … … 1247 1262 rc = VINF_SUCCESS; 1248 1263 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). */ 1250 1265 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) 1251 1266 { 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); 1254 1268 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 } 1256 1280 } 1257 1281 … … 1664 1688 return VERR_ACCESS_DENIED; 1665 1689 1690 const bool fReportsContextID = RT_BOOL(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID); 1691 1666 1692 /* 1667 1693 * Digest parameters. … … 1670 1696 * switch around so it's plain sailing compared to the DATA_READ message. 1671 1697 */ 1672 ASSERT_GUEST_RETURN( pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID1698 ASSERT_GUEST_RETURN(fReportsContextID 1673 1699 ? cParms == VBOX_SHCL_CPARMS_DATA_WRITE || cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B 1674 1700 : cParms == VBOX_SHCL_CPARMS_DATA_WRITE_OLD, … … 1684 1710 iParm++; 1685 1711 } 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); 1690 1763 } 1691 1764 … … 1695 1768 ("Wrong context ID: %#RX64, expected %#RX64\n", cmdCtx.uContextID, idCtxExpected), 1696 1769 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);1722 1770 1723 1771 /* … … 2124 2172 pClientState->Transfers.enmTransferDir = SHCLTRANSFERDIR_UNKNOWN; 2125 2173 #endif 2126 2127 pClientState->Legacy.idCtxWriteData = UINT64_MAX;2128 2174 } 2129 2175 … … 2213 2259 2214 2260 #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 */ 2267 static 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 2215 2275 /** 2216 2276 * SSM descriptor table for the SHCLCLIENTSTATE structure. … … 2315 2375 2316 2376 /* Serialize the client's internal message queue. */ 2377 /** @todo r=andy Why not using pClient->cAllocatedMessages here? */ 2317 2378 uint32_t cMsgs = 0; 2318 2379 PSHCLCLIENTMSG pMsg; 2319 2380 RTListForEach(&pClient->MsgQueue, pMsg, SHCLCLIENTMSG, ListEntry) 2320 {2321 2381 cMsgs += 1; 2322 }2323 2382 2324 2383 rc = SSMR3PutU64(pSSM, cMsgs); … … 2334 2393 } 2335 2394 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 } 2336 2404 #else /* UNIT_TEST */ 2337 2405 RT_NOREF3(u32ClientID, pvClient, pSSM); … … 2444 2512 2445 2513 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 } 2446 2531 } 2447 2532 }
Note:
See TracChangeset
for help on using the changeset viewer.