VirtualBox

Changeset 82506 in vbox


Ignore:
Timestamp:
Dec 9, 2019 3:18:31 AM (5 years ago)
Author:
vboxsync
Message:

SharedClipboardSvc,Vbgl: Reviewed and adjusted the handling of the VBOX_SHCL_GUEST_FN_DATA_WRITE message, paddling back two thirds of the parameter changes from the 6.1 dev cycle and fixing a couple of bugs introduced (buggy code commented out and marked with @todos). Fixing the broadcast approach of VBOX_SHCL_GUEST_FN_FORMATS_REPORT as the host doesn't want to know about clipboard stuff when VRDE clients are using the clipboard. Also documented the message. bugref:9437

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/HostServices/VBoxClipboardSvc.h

    r82500 r82506  
    286286/** Reads data in specified format from the host.
    287287 *
    288  * This function takes three parameters, a 32-bit format bit, a buffer
    289  * 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).
    290290 *
    291291 * There was a period during 6.1 development where it would take five parameters
     
    305305 */
    306306#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 */
    308326#define VBOX_SHCL_GUEST_FN_DATA_WRITE             4
    309327
     
    704722typedef struct VBoxShClParmDataRead
    705723{
    706     /** uint32_t, in: Requested format. */
     724    /** uint32_t, in:   Requested format (VBOX_SHCL_FMT_XXX). */
    707725    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. */
    709727    HGCMFunctionParameter pData;
    710     /** uint32_t, out: Size of returned data, if larger than the buffer, then no
     728    /** uint32_t, out:  Size of returned data, if larger than the buffer, then no
    711729     * data was actually transferred and the guest must repeat the call.  */
    712730    HGCMFunctionParameter cb32Needed;
    713731} VBoxShClParmDataRead;
     732
    714733#define VBOX_SHCL_CPARMS_DATA_READ      3   /**< The parameter count for VBOX_SHCL_GUEST_FN_DATA_READ. */
    715734#define VBOX_SHCL_CPARMS_DATA_READ_61B  5   /**< The 6.1 dev cycle variant, see VBOX_SHCL_GUEST_FN_DATA_READ.  */
    716735/** @}  */
    717736
    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. */
     741typedef 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. */
     752typedef 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/** @} */
    751764
    752765/**
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r82500 r82506  
    23952395    LogFlowFuncEnter();
    23962396
    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));
    24072408
    24082409    LogFlowFuncLeaveRC(rc);
     
    24352436    else
    24362437    {
    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);
    24422448
    24432449        LogFlowFunc(("CID=%RU32\n", pCtx->uContextID));
    24442450
    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));
    24522452    }
    24532453
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h

    r82489 r82506  
    146146    RTCList<SHCLCLIENTMSG *> queueMsg;
    147147    /** 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/ !!  */
    149150    SHCLEVENTSOURCE          Events;
    150151#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r82501 r82506  
    14591459    LogFlowFuncEnter();
    14601460
    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
    14641470        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;
    14761490    SHCLCLIENTCMDCTX cmdCtx;
    14771491    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++;
    15031502    }
    15041503    else
    15051504    {
    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);
    15231561    if (RT_SUCCESS(rc))
    15241562    {
    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;
    15431567    }
    15441568
     
    18481872                                                    &parms, sizeof(parms));
    18491873                        }
    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                         */
    18611898                        if (RT_SUCCESS(rc))
    1862                         {
    18631899                            pClient->State.fFlags |= SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE;
    1864                         }
    18651900                    }
    18661901                }
     
    18751910
    18761911        case VBOX_SHCL_GUEST_FN_DATA_WRITE:
    1877         {
    18781912            rc = shClSvcGetDataWrite(pClient, cParms, paParms);
    18791913            break;
    1880         }
    18811914
    18821915        case VBOX_SHCL_GUEST_FN_CANCEL:
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