Changeset 81768 in vbox for trunk/src/VBox/HostServices
- Timestamp:
- Nov 11, 2019 4:36:41 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134559
- Location:
- trunk/src/VBox/HostServices/SharedClipboard
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
r81746 r81768 72 72 SHCLTRANSFERDIR enmTransferDir; 73 73 } SHCLCLIENTTRANSFERSTATE, *PSHCLCLIENTTRANSFERSTATE; 74 75 /** 76 * Structure for holding a single POD (plain old data) transfer. 77 * This mostly is plain text, but also can be stuff like bitmap (BMP) or other binary data. 78 */ 79 typedef struct SHCLCLIENTPODSTATE 80 { 81 /** POD transfer direction. */ 82 SHCLTRANSFERDIR enmDir; 83 /** Format of the data to be read / written. */ 84 SHCLFORMAT uFormat; 85 /** How much data (in bytes) to read/write for the current operation. */ 86 uint64_t cbToReadWriteTotal; 87 /** How much data (in bytes) already has been read/written for the current operation. */ 88 uint64_t cbReadWritten; 89 /** Timestamp (in ms) of Last read/write operation. */ 90 uint64_t tsLastReadWrittenMs; 91 } SHCLCLIENTPODSTATE, *PSHCLCLIENTPODSTATE; 92 93 /** No Shared Clipboard client flags defined. */ 94 #define SHCLCLIENTSTATE_FLAGS_NONE 0 95 /** Client has a guest read operation active. */ 96 #define SHCLCLIENTSTATE_FLAGS_READ_ACTIVE RT_BIT(0) 97 /** Client has a guest write operation active. */ 98 #define SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE RT_BIT(1) 74 99 75 100 /** … … 96 121 /** Where the transfer sources its data from. */ 97 122 SHCLSOURCE enmSource; 123 /** Client state flags of type SHCLCLIENTSTATE_FLAGS_. */ 124 uint32_t fFlags; 125 /** POD (plain old data) state. */ 126 SHCLCLIENTPODSTATE POD; 98 127 /** The client's transfers state. */ 99 128 SHCLCLIENTTRANSFERSTATE Transfers; -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
r81746 r81768 170 170 void **ppvData, uint32_t *pcbData) 171 171 { 172 LogFlowFunc(("cfFormat=%u\n", cfFormat));173 174 172 SHCLDATAREQ dataReq; 175 173 RT_ZERO(dataReq); … … 177 175 dataReq.uFmt = SharedClipboardWinClipboardFormatToVBox(cfFormat); 178 176 dataReq.cbSize = _64K; /** @todo Make this more dynamic. */ 177 178 LogFlowFunc(("cfFormat=%u -> uFmt=0x%x\n", cfFormat, dataReq.uFmt)); 179 180 if (dataReq.uFmt == VBOX_SHCL_FMT_NONE) 181 { 182 LogRel2(("Shared Clipbaord: Windows format %u not supported, ingoring\n", cfFormat)); 183 return VERR_NOT_SUPPORTED; 184 } 179 185 180 186 SHCLEVENTID uEvent = 0; -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r81746 r81768 462 462 uint32_t uSrcFmt = VBOX_SHCL_FMT_NONE; 463 463 uint32_t uDstFmt = VBOX_SHCL_FMT_NONE; 464 rc = HGCMSvcGetU32(&pMsg->paParms[ 1] /* uFormat */, &uSrcFmt);464 rc = HGCMSvcGetU32(&pMsg->paParms[2] /* uFormat */, &uSrcFmt); 465 465 if (RT_SUCCESS(rc)) 466 466 { … … 474 474 AssertStmt(uSrcFmt == VBOX_SHCL_FMT_NONE, uSrcFmt = VBOX_SHCL_FMT_NONE); 475 475 476 LogFlowFunc(("uSrcFmt=0x%x, uDstFmt=0x%x\n", uSrcFmt, uDstFmt)); 477 476 478 /* Remove format we're going to return from the queued message. */ 477 479 uSrcFmt &= ~uDstFmt; 478 HGCMSvcSetU32(&pMsg->paParms[ 1], uSrcFmt);480 HGCMSvcSetU32(&pMsg->paParms[2], uSrcFmt); 479 481 480 482 /* Only report back one format at a time. */ … … 1010 1012 fDonePending = true; 1011 1013 } 1012 else if (pClient->Pending.uType == VBOX_SHCL_GUEST_FN_GET_HOST_MSG_OLD) /* Legacy */1014 else if (pClient->Pending.uType == VBOX_SHCL_GUEST_FN_GET_HOST_MSG_OLD) /* Legacy, Guest Additions < 6.1. */ 1013 1015 { 1014 1016 bool fRemove; … … 1073 1075 1074 1076 PSHCLCLIENTMSG pMsgReadData = shclSvcMsgAlloc(VBOX_SHCL_HOST_MSG_READ_DATA, 1075 VBOX_SHCL_CPARMS_READ_DATA );1077 VBOX_SHCL_CPARMS_READ_DATA_REQ); 1076 1078 if (pMsgReadData) 1077 1079 { 1078 1080 const SHCLEVENTID uEvent = ShClEventIDGenerate(&pClient->Events); 1081 1082 LogFlowFunc(("uFmt=0x%x\n", pDataReq->uFmt)); 1079 1083 1080 1084 HGCMSvcSetU64(&pMsgReadData->paParms[0], VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, 1081 1085 pClient->Events.uID, uEvent)); 1082 HGCMSvcSetU32(&pMsgReadData->paParms[1], pDataReq->uFmt); 1083 HGCMSvcSetU32(&pMsgReadData->paParms[2], pClient->State.cbChunkSize); 1086 HGCMSvcSetU32(&pMsgReadData->paParms[1], 0 /* fFlags */); 1087 HGCMSvcSetU32(&pMsgReadData->paParms[2], pDataReq->uFmt); 1088 HGCMSvcSetU32(&pMsgReadData->paParms[3], pClient->State.cbChunkSize); 1084 1089 1085 1090 rc = shclSvcMsgAdd(pClient, pMsgReadData, true /* fAppend */); … … 1117 1122 1118 1123 SHCLEVENTID uEvent; 1119 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy */1124 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy, Guest Additions < 6.1. */ 1120 1125 { 1121 1126 /* Older Guest Additions (<= VBox 6.0) did not have any context ID handling, so we ASSUME that the last event registered … … 1178 1183 { 1179 1184 #endif 1185 pClient->State.fFlags |= SHCLCLIENTSTATE_FLAGS_READ_ACTIVE; 1186 1180 1187 rc = shclSvcClientWakeup(pClient); 1181 1182 1188 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 1183 1189 } … … 1192 1198 } 1193 1199 1194 int shclSvcGetDataWrite(PSHCLCLIENT pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 1200 int shClSvcGetDataRead(PSHCLCLIENT pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 1201 { 1202 LogFlowFuncEnter(); 1203 1204 if ( ShClSvcGetMode() != VBOX_SHCL_MODE_HOST_TO_GUEST 1205 && ShClSvcGetMode() != VBOX_SHCL_MODE_BIDIRECTIONAL) 1206 { 1207 return VERR_ACCESS_DENIED; 1208 } 1209 1210 /* Is the guest supposed to read any clipboard data from the host? */ 1211 if (!(pClient->State.fFlags & SHCLCLIENTSTATE_FLAGS_READ_ACTIVE)) 1212 return VERR_WRONG_ORDER; 1213 1214 int rc; 1215 1216 SHCLCLIENTCMDCTX cmdCtx; 1217 RT_ZERO(cmdCtx); 1218 1219 SHCLDATABLOCK dataBlock; 1220 RT_ZERO(dataBlock); 1221 1222 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy, Guest Additions < 6.1. */ 1223 { 1224 if (cParms != 3) 1225 { 1226 rc = VERR_INVALID_PARAMETER; 1227 } 1228 else 1229 { 1230 rc = HGCMSvcGetU32(&paParms[0], &dataBlock.uFormat); 1231 if (RT_SUCCESS(rc)) 1232 { 1233 if (pClient->State.POD.uFormat == VBOX_SHCL_FMT_NONE) 1234 pClient->State.POD.uFormat = dataBlock.uFormat; 1235 1236 if (dataBlock.uFormat != pClient->State.POD.uFormat) 1237 { 1238 LogFlowFunc(("Invalid format (pClient->State.POD.uFormat=%RU32 vs dataBlock.uFormat=%RU32\n", 1239 pClient->State.POD.uFormat = dataBlock.uFormat)); 1240 1241 rc = VERR_INVALID_PARAMETER; 1242 } 1243 else 1244 { 1245 rc = HGCMSvcGetBuf(&paParms[1], &dataBlock.pvData, &dataBlock.cbData); 1246 } 1247 } 1248 } 1249 } 1250 else 1251 { 1252 if (cParms < VBOX_SHCL_CPARMS_READ_DATA) 1253 { 1254 rc = VERR_INVALID_PARAMETER; 1255 } 1256 else 1257 { 1258 /** @todo Handle paParms[1] flags. */ 1259 1260 rc = HGCMSvcGetU32(&paParms[2], &dataBlock.uFormat); 1261 if (RT_SUCCESS(rc)) 1262 { 1263 uint32_t cbData; 1264 rc = HGCMSvcGetU32(&paParms[3], &cbData); 1265 if (RT_SUCCESS(rc)) 1266 { 1267 rc = HGCMSvcGetBuf(&paParms[4], &dataBlock.pvData, &dataBlock.cbData); 1268 if (RT_SUCCESS(rc)) 1269 { 1270 if (cbData != dataBlock.cbData) 1271 { 1272 LogFlowFunc(("Invalid data (cbData=%RU32 vs dataBlock.cbData=%RU32)\n", cbData, dataBlock.cbData)); 1273 rc = VERR_INVALID_PARAMETER; 1274 } 1275 } 1276 } 1277 } 1278 } 1279 } 1280 1281 if (RT_SUCCESS(rc)) 1282 { 1283 uint32_t cbActual = 0; 1284 1285 /* If there is a service extension active, try reading data from it first. */ 1286 if (g_ExtState.pfnExtension) 1287 { 1288 SHCLEXTPARMS parms; 1289 RT_ZERO(parms); 1290 1291 parms.uFormat = pClient->State.POD.uFormat; 1292 parms.u.pvData = dataBlock.pvData; 1293 parms.cbData = dataBlock.cbData; 1294 1295 g_ExtState.fReadingData = true; 1296 1297 /* Read clipboard data from the extension. */ 1298 rc = g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_DATA_READ, 1299 &parms, sizeof(parms)); 1300 1301 LogFlowFunc(("g_ExtState.fDelayedAnnouncement=%RTbool, g_ExtState.uDelayedFormats=0x%x\n", 1302 g_ExtState.fDelayedAnnouncement, g_ExtState.uDelayedFormats)); 1303 1304 /* Did the extension send the clipboard formats yet? 1305 * Otherwise, do this now. */ 1306 if (g_ExtState.fDelayedAnnouncement) 1307 { 1308 SHCLFORMATDATA formatData; 1309 RT_ZERO(formatData); 1310 1311 formatData.uFormats = g_ExtState.uDelayedFormats; 1312 Assert(formatData.uFormats != VBOX_SHCL_FMT_NONE); /* There better is *any* format here now. */ 1313 1314 int rc2 = ShClSvcFormatsReport(pClient, &formatData); 1315 AssertRC(rc2); 1316 1317 g_ExtState.fDelayedAnnouncement = false; 1318 g_ExtState.uDelayedFormats = 0; 1319 } 1320 1321 g_ExtState.fReadingData = false; 1322 1323 if (RT_SUCCESS(rc)) 1324 { 1325 cbActual = parms.cbData; 1326 } 1327 } 1328 1329 /* Note: The host clipboard *always* has precedence over the service extension above, 1330 * so data which has been read above might get overridden by the host clipboard eventually. */ 1331 1332 if (RT_SUCCESS(rc)) 1333 { 1334 rc = ShClSvcImplReadData(pClient, &cmdCtx, &dataBlock, &cbActual); 1335 if (RT_SUCCESS(rc)) 1336 { 1337 LogFlowFunc(("cbData=%RU32, cbActual=%RU32\n", dataBlock.cbData, cbActual)); 1338 1339 /* Return the actual size required to fullfil the request. */ 1340 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy, Guest Additions < 6.1. */ 1341 { 1342 HGCMSvcSetU32(&paParms[2], cbActual); 1343 } 1344 else 1345 { 1346 HGCMSvcSetU32(&paParms[3], cbActual); 1347 } 1348 1349 /* If the data to return exceeds the buffer the guest supplies, tell it (and let it try again). */ 1350 if (cbActual >= dataBlock.cbData) 1351 rc = VINF_BUFFER_OVERFLOW; 1352 1353 if (rc == VINF_SUCCESS) 1354 { 1355 /* Only remove "read active" flag after successful read again. */ 1356 pClient->State.fFlags &= ~SHCLCLIENTSTATE_FLAGS_READ_ACTIVE; 1357 } 1358 } 1359 } 1360 } 1361 1362 LogFlowFuncLeaveRC(rc); 1363 return rc; 1364 } 1365 1366 int shClSvcGetDataWrite(PSHCLCLIENT pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 1195 1367 { 1196 1368 LogFlowFuncEnter(); … … 1199 1371 && ShClSvcGetMode() != VBOX_SHCL_MODE_BIDIRECTIONAL) 1200 1372 { 1201 return VERR_NOT_SUPPORTED; 1202 } 1373 return VERR_ACCESS_DENIED; 1374 } 1375 1376 /* Is the guest supposed to write any clipboard data from the host? */ 1377 if (!(pClient->State.fFlags & SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE)) 1378 return VERR_WRONG_ORDER; 1203 1379 1204 1380 int rc; … … 1210 1386 RT_ZERO(cmdCtx); 1211 1387 1212 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy */ 1213 { 1214 if (cParms < 2) 1215 { 1216 rc = VERR_INVALID_PARAMETER; 1217 } 1218 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* format */ 1219 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR) /* ptr */ 1388 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy, Guest Additions < 6.1. */ 1389 { 1390 if (cParms != 2) 1220 1391 { 1221 1392 rc = VERR_INVALID_PARAMETER; … … 1225 1396 rc = HGCMSvcGetU32(&paParms[0], &dataBlock.uFormat); 1226 1397 if (RT_SUCCESS(rc)) 1227 rc = HGCMSvcGetBuf(&paParms[1], &dataBlock.pvData, &dataBlock.cbData); 1398 { 1399 if (pClient->State.POD.uFormat == VBOX_SHCL_FMT_NONE) 1400 pClient->State.POD.uFormat = dataBlock.uFormat; 1401 1402 if ( dataBlock.uFormat == VBOX_SHCL_FMT_NONE 1403 || dataBlock.uFormat != pClient->State.POD.uFormat) 1404 { 1405 LogFunc(("Invalid format (client=%RU32 vs host=%RU32)\n", dataBlock.uFormat, pClient->State.POD.uFormat)); 1406 rc = VERR_INVALID_PARAMETER; 1407 } 1408 else 1409 rc = HGCMSvcGetBuf(&paParms[1], &dataBlock.pvData, &dataBlock.cbData); 1410 } 1228 1411 } 1229 1412 } 1230 1413 else 1231 1414 { 1232 if (cParms <VBOX_SHCL_CPARMS_WRITE_DATA)1415 if (cParms != VBOX_SHCL_CPARMS_WRITE_DATA) 1233 1416 { 1234 1417 rc = VERR_INVALID_PARAMETER; 1235 1418 } 1236 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_64BIT /* uContext */1237 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* uFormat */1238 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbData */1239 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR) /* pvData */1240 {1241 rc = VERR_INVALID_PARAMETER;1242 }1243 1419 else 1244 1420 { 1245 1421 rc = HGCMSvcGetU64(&paParms[0], &cmdCtx.uContextID); 1422 1423 /** @todo Handle paParms[1] flags. */ 1424 1246 1425 if (RT_SUCCESS(rc)) 1247 rc = HGCMSvcGetU32(&paParms[ 1], &dataBlock.uFormat);1426 rc = HGCMSvcGetU32(&paParms[2], &dataBlock.uFormat); 1248 1427 if (RT_SUCCESS(rc)) 1249 rc = HGCMSvcGetBuf(&paParms[3], &dataBlock.pvData, &dataBlock.cbData); 1250 1251 /** @todo Handle the rest. */ 1428 rc = HGCMSvcGetBuf(&paParms[4], &dataBlock.pvData, &dataBlock.cbData); 1252 1429 } 1253 1430 } … … 1268 1445 1269 1446 rc = ShClSvcImplWriteData(pClient, &cmdCtx, &dataBlock); 1447 if (RT_SUCCESS(rc)) 1448 { 1449 /* Remove "write active" flag after successful read again. */ 1450 pClient->State.fFlags &= ~SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE; 1451 } 1270 1452 } 1271 1453 … … 1450 1632 #endif 1451 1633 1634 LogFunc(("Client state: fFlags=0x%x, fGuestFeatures0=0x%x, fGuestFeatures1=0x%x\n", 1635 pClient->State.fFlags, pClient->State.fGuestFeatures0, pClient->State.fGuestFeatures1)); 1636 1452 1637 switch (u32Function) 1453 1638 { … … 1519 1704 uint32_t uFormats = 0; 1520 1705 1521 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy */1706 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy, Guest Additions < 6.1. */ 1522 1707 { 1523 1708 if (cParms != 1) … … 1587 1772 1588 1773 rc = ShClSvcImplFormatAnnounce(pClient, &cmdCtx, &formatData); 1589 }1590 }1591 }1592 1593 break;1594 }1595 1596 case VBOX_SHCL_GUEST_FN_DATA_READ:1597 {1598 if (cParms != VBOX_SHCL_CPARMS_READ_DATA)1599 {1600 rc = VERR_INVALID_PARAMETER;1601 }1602 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* format */1603 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* ptr */1604 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* size */1605 )1606 {1607 rc = VERR_INVALID_PARAMETER;1608 }1609 else1610 {1611 if ( ShClSvcGetMode() != VBOX_SHCL_MODE_HOST_TO_GUEST1612 && ShClSvcGetMode() != VBOX_SHCL_MODE_BIDIRECTIONAL)1613 {1614 rc = VERR_ACCESS_DENIED;1615 break;1616 }1617 1618 uint32_t uFormat;1619 rc = HGCMSvcGetU32(&paParms[0], &uFormat);1620 if (RT_SUCCESS(rc))1621 {1622 void *pv;1623 uint32_t cb;1624 rc = HGCMSvcGetBuf(&paParms[1], &pv, &cb);1625 if (RT_SUCCESS(rc))1626 {1627 uint32_t cbActual = 0;1628 1629 /* If there is a service extension active, try reading data from it first. */1630 if (g_ExtState.pfnExtension)1631 {1632 SHCLEXTPARMS parms;1633 RT_ZERO(parms);1634 1635 parms.uFormat = uFormat;1636 parms.u.pvData = pv;1637 parms.cbData = cb;1638 1639 g_ExtState.fReadingData = true;1640 1641 /* Read clipboard data from the extension. */1642 rc = g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_DATA_READ,1643 &parms, sizeof(parms));1644 1645 LogFlowFunc(("g_ExtState.fDelayedAnnouncement=%RTbool, g_ExtState.uDelayedFormats=0x%x\n",1646 g_ExtState.fDelayedAnnouncement, g_ExtState.uDelayedFormats));1647 1648 /* Did the extension send the clipboard formats yet?1649 * Otherwise, do this now. */1650 if (g_ExtState.fDelayedAnnouncement)1651 {1652 SHCLFORMATDATA formatData;1653 RT_ZERO(formatData);1654 1655 formatData.uFormats = g_ExtState.uDelayedFormats;1656 Assert(formatData.uFormats != VBOX_SHCL_FMT_NONE); /* There better is *any* format here now. */1657 1658 int rc2 = ShClSvcFormatsReport(pClient, &formatData);1659 AssertRC(rc2);1660 1661 g_ExtState.fDelayedAnnouncement = false;1662 g_ExtState.uDelayedFormats = 0;1663 }1664 1665 g_ExtState.fReadingData = false;1666 1667 if (RT_SUCCESS(rc))1668 {1669 cbActual = parms.cbData;1670 }1671 }1672 1673 /* Note: The host clipboard *always* has precedence over the service extension above,1674 * so data which has been read above might get overridden by the host clipboard eventually. */1675 1676 SHCLCLIENTCMDCTX cmdCtx;1677 RT_ZERO(cmdCtx);1678 1679 /* Release any other pending read, as we only1680 * support one pending read at one time. */1681 1774 if (RT_SUCCESS(rc)) 1682 1775 { 1683 SHCLDATABLOCK dataBlock; 1684 RT_ZERO(dataBlock); 1685 1686 dataBlock.pvData = pv; 1687 dataBlock.cbData = cb; 1688 dataBlock.uFormat = uFormat; 1689 1690 rc = ShClSvcImplReadData(pClient, &cmdCtx, &dataBlock, &cbActual); 1691 if (RT_SUCCESS(rc)) 1692 HGCMSvcSetU32(&paParms[2], cbActual); 1776 pClient->State.fFlags |= SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE; 1693 1777 } 1694 1778 } … … 1699 1783 } 1700 1784 1785 case VBOX_SHCL_GUEST_FN_DATA_READ: 1786 { 1787 rc = shClSvcGetDataRead(pClient, cParms, paParms); 1788 break; 1789 } 1790 1701 1791 case VBOX_SHCL_GUEST_FN_DATA_WRITE: 1702 1792 { 1703 rc = sh clSvcGetDataWrite(pClient, cParms, paParms);1793 rc = shClSvcGetDataWrite(pClient, cParms, paParms); 1704 1794 break; 1705 1795 } … … 1709 1799 LogRel2(("Shared Clipboard: Operation canceled by guest side\n")); 1710 1800 1711 /** @todo Do we need to do anything here? */ 1801 /* Reset client state and start over. */ 1802 shclSvcClientStateReset(&pClient->State); 1803 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 1804 shclSvcClientTransfersReset(pClient); 1805 #endif 1806 /** @todo Do we need to do anything else here? */ 1712 1807 break; 1713 1808 } … … 1801 1896 pClientState->fGuestFeatures1 = VBOX_SHCL_GF_NONE; 1802 1897 1803 pClientState->cbChunkSize = _64K; /** Make this configurable. */ 1898 pClientState->cbChunkSize = _64K; /** Make this configurable. */ 1899 pClientState->enmSource = SHCLSOURCE_INVALID; 1900 pClientState->fFlags = SHCLCLIENTSTATE_FLAGS_NONE; 1901 1902 pClientState->POD.enmDir = SHCLTRANSFERDIR_UNKNOWN; 1903 pClientState->POD.uFormat = VBOX_SHCL_FMT_NONE; 1904 pClientState->POD.cbToReadWriteTotal = 0; 1905 pClientState->POD.cbReadWritten = 0; 1804 1906 1805 1907 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 1806 1908 pClientState->Transfers.enmTransferDir = SHCLTRANSFERDIR_UNKNOWN; 1807 1909 #endif 1910 1911 1808 1912 } 1809 1913 … … 1899 2003 { 1900 2004 /** Note: Saving the session ID not necessary, as they're not persistent across state save/restore. */ 1901 SSMFIELD_ENTRY (SHCLCLIENTSTATE, fGuestFeatures0), 1902 SSMFIELD_ENTRY (SHCLCLIENTSTATE, fGuestFeatures1), 1903 SSMFIELD_ENTRY (SHCLCLIENTSTATE, cbChunkSize), 1904 SSMFIELD_ENTRY (SHCLCLIENTSTATE, enmSource), 2005 SSMFIELD_ENTRY(SHCLCLIENTSTATE, fGuestFeatures0), 2006 SSMFIELD_ENTRY(SHCLCLIENTSTATE, fGuestFeatures1), 2007 SSMFIELD_ENTRY(SHCLCLIENTSTATE, cbChunkSize), 2008 SSMFIELD_ENTRY(SHCLCLIENTSTATE, enmSource), 2009 SSMFIELD_ENTRY(SHCLCLIENTSTATE, fFlags), 2010 SSMFIELD_ENTRY_TERM() 2011 }; 2012 2013 /** 2014 * SSM descriptor table for the SHCLCLIENTPODSTATE structure. 2015 */ 2016 static SSMFIELD const s_aShClSSMClientPODState[] = 2017 { 2018 SSMFIELD_ENTRY(SHCLCLIENTPODSTATE, enmDir), 2019 SSMFIELD_ENTRY(SHCLCLIENTPODSTATE, uFormat), 2020 SSMFIELD_ENTRY(SHCLCLIENTPODSTATE, cbToReadWriteTotal), 2021 SSMFIELD_ENTRY(SHCLCLIENTPODSTATE, cbReadWritten), 2022 SSMFIELD_ENTRY(SHCLCLIENTPODSTATE, tsLastReadWrittenMs), 1905 2023 SSMFIELD_ENTRY_TERM() 1906 2024 }; … … 1954 2072 1955 2073 /* Write Shared Clipboard saved state version. */ 1956 SSMR3PutU32(pSSM, VBOX_SHCL_SSM_VER_ 1);2074 SSMR3PutU32(pSSM, VBOX_SHCL_SSM_VER_LATEST); 1957 2075 1958 2076 int rc = SSMR3PutStructEx(pSSM, &pClient->State, sizeof(pClient->State), 0 /*fFlags*/, &s_aShClSSMClientState[0], NULL); 2077 AssertRCReturn(rc, rc); 2078 2079 rc = SSMR3PutStructEx(pSSM, &pClient->State.POD, sizeof(pClient->State.POD), 0 /*fFlags*/, &s_aShClSSMClientPODState[0], NULL); 1959 2080 AssertRCReturn(rc, rc); 1960 2081 … … 2047 2168 return svcLoadStateV0(u32ClientID, pvClient, pSSM, uVersion); 2048 2169 } 2049 else if (lenOrVer == VBOX_SHCL_SSM_VER_1) 2050 { 2051 rc = SSMR3GetStructEx(pSSM, &pClient->State, sizeof(pClient->State), 0 /* fFlags */, 2052 &s_aShClSSMClientState[0], NULL); 2053 AssertRCReturn(rc, rc); 2170 else if (lenOrVer >= VBOX_SHCL_SSM_VER_1) 2171 { 2172 if (lenOrVer >= VBOX_SHCL_SSM_VER_2) 2173 { 2174 rc = SSMR3GetStructEx(pSSM, &pClient->State, sizeof(pClient->State), 0 /* fFlags */, 2175 &s_aShClSSMClientState[0], NULL); 2176 AssertRCReturn(rc, rc); 2177 2178 rc = SSMR3GetStructEx(pSSM, &pClient->State.POD, sizeof(pClient->State.POD), 0 /* fFlags */, 2179 &s_aShClSSMClientPODState[0], NULL); 2180 AssertRCReturn(rc, rc); 2181 } 2182 else /** @todo Remove this block after 6.1 RC; don't annoy team members with broken saved states. */ 2183 { 2184 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Begin marker */ 2185 AssertRC(rc); 2186 2187 rc = SSMR3GetU64(pSSM, &pClient->State.fGuestFeatures0); 2188 AssertRC(rc); 2189 2190 rc = SSMR3GetU64(pSSM, &pClient->State.fGuestFeatures1); 2191 AssertRC(rc); 2192 2193 rc = SSMR3GetU32(pSSM, &pClient->State.cbChunkSize); 2194 AssertRC(rc); 2195 2196 rc = SSMR3GetU32(pSSM, (uint32_t *)&pClient->State.enmSource); 2197 AssertRC(rc); 2198 2199 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* End marker */ 2200 AssertRC(rc); 2201 } 2054 2202 2055 2203 rc = SSMR3GetStructEx(pSSM, &pClient->State.Transfers, sizeof(pClient->State.Transfers), 0 /* fFlags */,
Note:
See TracChangeset
for help on using the changeset viewer.