Changeset 82506 in vbox
- Timestamp:
- Dec 9, 2019 3:18:31 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/HostServices/VBoxClipboardSvc.h
r82500 r82506 286 286 /** Reads data in specified format from the host. 287 287 * 288 * This function takes three parameters, a 32-bit format bit , a buffer289 * and 32-bit number of bytes read (output).288 * This function takes three parameters, a 32-bit format bit 289 * (VBOX_SHCL_FMT_XXX), a buffer and 32-bit number of bytes read (output). 290 290 * 291 291 * There was a period during 6.1 development where it would take five parameters … … 305 305 */ 306 306 #define VBOX_SHCL_GUEST_FN_DATA_READ 3 307 /** Writes data in requested format to the host. */ 307 /** Writes requested data to the host. 308 * 309 * This function takes either 2 or 3 parameters. The last two parameters are a 310 * 32-bit format bit (VBOX_SHCL_FMT_XXX) and a data buffer holding the related 311 * data. The three parameter variant have a context ID first, which shall be a 312 * copy of the ID in the data request message. 313 * 314 * There was a period during 6.1 development where there would be a 5 parameter 315 * version of this, inserting an unused flags parameter between the context ID 316 * and the format bit, as well as a 32-bit data buffer size repate between the 317 * format bit and the data buffer. This format is still accepted, though 318 * deprecated. 319 * 320 * @retval VINF_SUCCESS on success. 321 * @retval VERR_INVALID_CLIENT_ID 322 * @retval VERR_WRONG_PARAMETER_COUNT 323 * @retval VERR_WRONG_PARAMETER_TYPE 324 * @retval VERR_INVALID_CONTEXT if the context ID didn't match up. 325 */ 308 326 #define VBOX_SHCL_GUEST_FN_DATA_WRITE 4 309 327 … … 704 722 typedef struct VBoxShClParmDataRead 705 723 { 706 /** uint32_t, in: Requested format. */724 /** uint32_t, in: Requested format (VBOX_SHCL_FMT_XXX). */ 707 725 HGCMFunctionParameter f32Format; 708 /** ptr, out: The data buffer to put the data in on success. */726 /** ptr, out: The data buffer to put the data in on success. */ 709 727 HGCMFunctionParameter pData; 710 /** uint32_t, out: Size of returned data, if larger than the buffer, then no728 /** uint32_t, out: Size of returned data, if larger than the buffer, then no 711 729 * data was actually transferred and the guest must repeat the call. */ 712 730 HGCMFunctionParameter cb32Needed; 713 731 } VBoxShClParmDataRead; 732 714 733 #define VBOX_SHCL_CPARMS_DATA_READ 3 /**< The parameter count for VBOX_SHCL_GUEST_FN_DATA_READ. */ 715 734 #define VBOX_SHCL_CPARMS_DATA_READ_61B 5 /**< The 6.1 dev cycle variant, see VBOX_SHCL_GUEST_FN_DATA_READ. */ 716 735 /** @} */ 717 736 718 /** 719 * Writes clipboard data. 720 */ 721 typedef struct _VBoxShClWriteDataMsg 722 { 723 VBGLIOCHGCMCALL hdr; 724 725 union 726 { 727 struct 728 { 729 /** Returned format as requested in the VBOX_SHCL_HOST_MSG_READ_DATA message. */ 730 HGCMFunctionParameter format; /* IN uint32_t */ 731 /** Data. */ 732 HGCMFunctionParameter ptr; /* IN linear pointer. */ 733 } v0; 734 struct 735 { 736 /** uint64_t, out: Context ID. */ 737 HGCMFunctionParameter uContext; 738 /** uint32_t, out: Write flags; currently unused and must be set to 0. */ 739 HGCMFunctionParameter fFlags; 740 /** uint32_t, out: Requested format to read data in. */ 741 HGCMFunctionParameter uFormat; 742 /** uint32_t, out: Size of data (in bytes). */ 743 HGCMFunctionParameter cbData; 744 /** ptr, out: Actual data. */ 745 HGCMFunctionParameter pvData; 746 } v1; 747 } u; 748 } VBoxShClWriteDataMsg; 749 750 #define VBOX_SHCL_CPARMS_WRITE_DATA 5 737 /** @name 738 * @{ */ 739 740 /** VBOX_SHCL_GUEST_FN_DATA_WRITE parameters. */ 741 typedef struct VBoxShClParmDataWrite 742 { 743 /** uint64_t, in: Context ID from VBOX_SHCL_HOST_MSG_READ_DATA. */ 744 HGCMFunctionParameter id64Context; 745 /** uint32_t, in: The data format (VBOX_SHCL_FMT_XXX). */ 746 HGCMFunctionParameter f32Format; 747 /** ptr, in: The data. */ 748 HGCMFunctionParameter pData; 749 } VBoxShClParmDataWrite; 750 751 /** Old VBOX_SHCL_GUEST_FN_DATA_WRITE parameters. */ 752 typedef struct VBoxShClParmDataWriteOld 753 { 754 /** uint32_t, in: The data format (VBOX_SHCL_FMT_XXX). */ 755 HGCMFunctionParameter f32Format; 756 /** ptr, in: The data. */ 757 HGCMFunctionParameter pData; 758 } VBoxShClParmDataWriteOld; 759 760 #define VBOX_SHCL_CPARMS_DATA_WRITE 3 /**< The variant used when VBOX_SHCL_GF_0_CONTEXT_ID is reported. */ 761 #define VBOX_SHCL_CPARMS_DATA_WRITE_OLD 2 /**< The variant used when VBOX_SHCL_GF_0_CONTEXT_ID isn't reported. */ 762 #define VBOX_SHCL_CPARMS_DATA_WRITE_61B 5 /**< The 6.1 dev cycle variant, see VBOX_SHCL_GUEST_FN_DATA_WRITE. */ 763 /** @} */ 751 764 752 765 /** -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp
r82500 r82506 2395 2395 LogFlowFuncEnter(); 2396 2396 2397 VBoxShClWriteDataMsg Msg; 2398 RT_ZERO(Msg); 2399 2400 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, 2401 VBOX_SHCL_GUEST_FN_DATA_WRITE, 2); 2402 2403 VbglHGCMParmUInt32Set(&Msg.u.v0.format, fFormat); 2404 VbglHGCMParmPtrSet(&Msg.u.v0.ptr, pv, cb); 2405 2406 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg.hdr) + sizeof(Msg.u.v0)); 2397 struct 2398 { 2399 VBGLIOCHGCMCALL Hdr; 2400 VBoxShClParmDataWriteOld Parms; 2401 } Msg; 2402 2403 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, VBOX_SHCL_GUEST_FN_DATA_WRITE, VBOX_SHCL_CPARMS_DATA_WRITE_OLD); 2404 VbglHGCMParmUInt32Set(&Msg.Parms.f32Format, fFormat); 2405 VbglHGCMParmPtrSet(&Msg.Parms.pData, pv, cb); 2406 2407 int rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg)); 2407 2408 2408 2409 LogFlowFuncLeaveRC(rc); … … 2435 2436 else 2436 2437 { 2437 VBoxShClWriteDataMsg Msg; 2438 RT_ZERO(Msg); 2439 2440 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, 2441 VBOX_SHCL_GUEST_FN_DATA_WRITE, VBOX_SHCL_CPARMS_WRITE_DATA); 2438 struct 2439 { 2440 VBGLIOCHGCMCALL Hdr; 2441 VBoxShClParmDataWrite Parms; 2442 } Msg; 2443 2444 VBGL_HGCM_HDR_INIT(&Msg.Hdr, pCtx->uClientID, VBOX_SHCL_GUEST_FN_DATA_WRITE, VBOX_SHCL_CPARMS_DATA_WRITE); 2445 Msg.Parms.id64Context.SetUInt64(pCtx->uContextID); 2446 Msg.Parms.f32Format.SetUInt32(pData->uFormat); 2447 Msg.Parms.pData.SetPtr(pData->pvData, pData->cbData); 2442 2448 2443 2449 LogFlowFunc(("CID=%RU32\n", pCtx->uContextID)); 2444 2450 2445 Msg.u.v1.uContext.SetUInt64(pCtx->uContextID); 2446 Msg.u.v1.uFormat.SetUInt32(pData->uFormat); 2447 Msg.u.v1.fFlags.SetUInt32(0); 2448 Msg.u.v1.cbData.SetUInt32(pData->cbData); 2449 Msg.u.v1.pvData.SetPtr(pData->pvData, pData->cbData); 2450 2451 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 2451 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg)); 2452 2452 } 2453 2453 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
r82489 r82506 146 146 RTCList<SHCLCLIENTMSG *> queueMsg; 147 147 /** The client's own event source. 148 * Needed for events which are not bound to a specific transfer. */ 148 * Needed for events which are not bound to a specific transfer. 149 * @todo r=bird: s/Events/EventSrc/ !! */ 149 150 SHCLEVENTSOURCE Events; 150 151 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r82501 r82506 1459 1459 LogFlowFuncEnter(); 1460 1460 1461 if ( ShClSvcGetMode() != VBOX_SHCL_MODE_GUEST_TO_HOST 1462 && ShClSvcGetMode() != VBOX_SHCL_MODE_BIDIRECTIONAL) 1463 { 1461 /* 1462 * Check if the service mode allows this operation and whether the guest is 1463 * supposed to be reading from the host. 1464 */ 1465 uint32_t uMode = ShClSvcGetMode(); 1466 if ( uMode == VBOX_SHCL_MODE_BIDIRECTIONAL 1467 || uMode == VBOX_SHCL_MODE_GUEST_TO_HOST) 1468 { /* likely */ } 1469 else 1464 1470 return VERR_ACCESS_DENIED; 1465 } 1466 1467 /* Is the guest supposed to write any clipboard data from the host? */ 1468 if (!(pClient->State.fFlags & SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE)) 1469 return VERR_WRONG_ORDER; 1470 1471 int rc; 1472 1473 SHCLDATABLOCK dataBlock; 1474 RT_ZERO(dataBlock); 1475 1471 1472 /** @todo r=bird: This whole active flag stuff is broken, so disabling for now. */ 1473 //if (pClient->State.fFlags & SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE) 1474 //{ /* likely */ } 1475 //else 1476 // return VERR_WRONG_ORDER; 1477 1478 /* 1479 * Digest parameters. 1480 * 1481 * There are 3 different format here, formatunately no parameters have been 1482 * switch around so it's plain sailing compared to the DATA_READ message. 1483 */ 1484 ASSERT_GUEST_RETURN(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID 1485 ? cParms == VBOX_SHCL_CPARMS_DATA_WRITE || cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B 1486 : cParms == VBOX_SHCL_CPARMS_DATA_WRITE_OLD, 1487 VERR_WRONG_PARAMETER_COUNT); 1488 1489 uintptr_t iParm = 0; 1476 1490 SHCLCLIENTCMDCTX cmdCtx; 1477 1491 RT_ZERO(cmdCtx); 1478 1479 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) /* Legacy, Guest Additions < 6.1. */ 1480 { 1481 if (cParms != 2) 1482 { 1483 rc = VERR_INVALID_PARAMETER; 1484 } 1485 else 1486 { 1487 rc = HGCMSvcGetU32(&paParms[0], &dataBlock.uFormat); 1488 if (RT_SUCCESS(rc)) 1489 { 1490 if (pClient->State.POD.uFormat == VBOX_SHCL_FMT_NONE) 1491 pClient->State.POD.uFormat = dataBlock.uFormat; 1492 1493 if ( dataBlock.uFormat == VBOX_SHCL_FMT_NONE 1494 || dataBlock.uFormat != pClient->State.POD.uFormat) 1495 { 1496 LogFunc(("Invalid format (client=%RU32 vs host=%RU32)\n", dataBlock.uFormat, pClient->State.POD.uFormat)); 1497 rc = VERR_INVALID_PARAMETER; 1498 } 1499 else 1500 rc = HGCMSvcGetBuf(&paParms[1], &dataBlock.pvData, &dataBlock.cbData); 1501 } 1502 } 1492 if (cParms > VBOX_SHCL_CPARMS_DATA_WRITE_OLD) 1493 { 1494 ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_WRONG_PARAMETER_TYPE); 1495 cmdCtx.uContextID = paParms[iParm].u.uint64; 1496 uint64_t const idCtxExpected = VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, pClient->Events.uID, 1497 VBOX_SHCL_CONTEXTID_GET_EVENT(cmdCtx.uContextID)); 1498 ASSERT_GUEST_MSG_RETURN(cmdCtx.uContextID == idCtxExpected, 1499 ("Wrong context ID: %#RX64, expected %#RX64\n", cmdCtx.uContextID, idCtxExpected), 1500 VERR_INVALID_CONTEXT); 1501 iParm++; 1503 1502 } 1504 1503 else 1505 1504 { 1506 if (cParms != VBOX_SHCL_CPARMS_WRITE_DATA) 1507 { 1508 rc = VERR_INVALID_PARAMETER; 1509 } 1510 else 1511 { 1512 rc = HGCMSvcGetU64(&paParms[0], &cmdCtx.uContextID); 1513 1514 /** @todo Handle paParms[1] flags. */ 1515 1516 if (RT_SUCCESS(rc)) 1517 rc = HGCMSvcGetU32(&paParms[2], &dataBlock.uFormat); 1518 if (RT_SUCCESS(rc)) 1519 rc = HGCMSvcGetBuf(&paParms[4], &dataBlock.pvData, &dataBlock.cbData); 1520 } 1521 } 1522 1505 /** @todo supply CID from client state? Setting it in ShClSvcDataReadRequest? */ 1506 } 1507 if (cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B) 1508 { 1509 ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE); 1510 ASSERT_GUEST_RETURN(paParms[iParm].u.uint32 == 0, VERR_INVALID_FLAGS); 1511 iParm++; 1512 } 1513 SHCLDATABLOCK dataBlock; 1514 ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE); /* Format bit. */ 1515 dataBlock.uFormat = paParms[iParm].u.uint32; 1516 iParm++; 1517 if (cParms == VBOX_SHCL_CPARMS_DATA_WRITE_61B) 1518 { 1519 ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE); /* "cbData" - duplicates buffer size. */ 1520 iParm++; 1521 } 1522 ASSERT_GUEST_RETURN(paParms[iParm].type == VBOX_HGCM_SVC_PARM_PTR, VERR_WRONG_PARAMETER_TYPE); /* Data buffer */ 1523 dataBlock.pvData = paParms[iParm].u.pointer.addr; 1524 dataBlock.cbData = paParms[iParm].u.pointer.size; 1525 iParm++; 1526 Assert(iParm == cParms); 1527 1528 /* 1529 * For some reason we need to do this (makes absolutely no sense to bird). 1530 */ 1531 /** @todo r=bird: I really don't get why you need the State.POD.uFormat 1532 * member. I'm sure there is a reason. Incomplete code? */ 1533 if (!(pClient->State.fGuestFeatures0 & VBOX_SHCL_GF_0_CONTEXT_ID)) 1534 { 1535 if (pClient->State.POD.uFormat == VBOX_SHCL_FMT_NONE) 1536 pClient->State.POD.uFormat = dataBlock.uFormat; 1537 /** @todo r=bird: this must be buggy to, I've disabled it without testing 1538 * though. */ 1539 //ASSERT_GUEST_MSG_RETURN(pClient->State.POD.uFormat == dataBlock.uFormat, 1540 // ("Requested %#x, POD.uFormat=%#x\n", dataBlock.uFormat, pClient->State.POD.uFormat), 1541 // VERR_BAD_EXE_FORMAT /*VERR_INTERNAL_ERROR*/); 1542 } 1543 1544 /* 1545 * Write the data to the active host side clipboard. 1546 */ 1547 int rc; 1548 if (g_ExtState.pfnExtension) 1549 { 1550 SHCLEXTPARMS parms; 1551 RT_ZERO(parms); 1552 parms.uFormat = dataBlock.uFormat; 1553 parms.u.pvData = dataBlock.pvData; 1554 parms.cbData = dataBlock.cbData; 1555 1556 g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_DATA_WRITE, &parms, sizeof(parms)); 1557 rc = VINF_SUCCESS; 1558 } 1559 else 1560 rc = ShClSvcImplWriteData(pClient, &cmdCtx, &dataBlock); 1523 1561 if (RT_SUCCESS(rc)) 1524 1562 { 1525 if (g_ExtState.pfnExtension) 1526 { 1527 SHCLEXTPARMS parms; 1528 RT_ZERO(parms); 1529 1530 parms.uFormat = dataBlock.uFormat; 1531 parms.u.pvData = dataBlock.pvData; 1532 parms.cbData = dataBlock.cbData; 1533 1534 g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_DATA_WRITE, &parms, sizeof(parms)); 1535 } 1536 1537 rc = ShClSvcImplWriteData(pClient, &cmdCtx, &dataBlock); 1538 if (RT_SUCCESS(rc)) 1539 { 1540 /* Remove "write active" flag after successful read again. */ 1541 pClient->State.fFlags &= ~SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE; 1542 } 1563 /* Remove "write active" flag after successful read again. */ 1564 /** @todo r=bird: This doesn't make any effing sense. What if the host 1565 * wants to have the guest write it another format??? */ 1566 pClient->State.fFlags &= ~SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE; 1543 1567 } 1544 1568 … … 1848 1872 &parms, sizeof(parms)); 1849 1873 } 1850 1851 SHCLCLIENTCMDCTX cmdCtx; 1852 RT_ZERO(cmdCtx); 1853 1854 SHCLFORMATDATA formatData; 1855 RT_ZERO(formatData); 1856 1857 formatData.Formats = uFormats; 1858 Assert(formatData.Formats != VBOX_SHCL_FMT_NONE); /* Sanity. */ 1859 1860 rc = ShClSvcImplFormatAnnounce(pClient, &cmdCtx, &formatData); 1874 else 1875 { 1876 1877 SHCLCLIENTCMDCTX cmdCtx; 1878 RT_ZERO(cmdCtx); 1879 1880 SHCLFORMATDATA formatData; 1881 RT_ZERO(formatData); 1882 1883 formatData.Formats = uFormats; 1884 Assert(formatData.Formats != VBOX_SHCL_FMT_NONE); /* Sanity. */ 1885 1886 rc = ShClSvcImplFormatAnnounce(pClient, &cmdCtx, &formatData); 1887 } 1888 1889 /** @todo r=bird: I'm not sure if the guest should be automatically allowed 1890 * to write the host clipboard now. It would make more sense to disallow 1891 * host clipboard reads until the host reports formats. 1892 * 1893 * The writes should only really be allowed upon request from the host, 1894 * shouldn't they? (Though, I'm not sure, maybe there are situations 1895 * where the guest side will just want to push the content over 1896 * immediately while it's still available, I don't quite recall now... 1897 */ 1861 1898 if (RT_SUCCESS(rc)) 1862 {1863 1899 pClient->State.fFlags |= SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE; 1864 }1865 1900 } 1866 1901 } … … 1875 1910 1876 1911 case VBOX_SHCL_GUEST_FN_DATA_WRITE: 1877 {1878 1912 rc = shClSvcGetDataWrite(pClient, cParms, paParms); 1879 1913 break; 1880 }1881 1914 1882 1915 case VBOX_SHCL_GUEST_FN_CANCEL:
Note:
See TracChangeset
for help on using the changeset viewer.