VirtualBox

Changeset 85712 in vbox


Ignore:
Timestamp:
Aug 12, 2020 12:24:30 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
139856
Message:

DnD: Added wire protocol support for querying and reporting guest / host features in host service and VbglR3. Untested.

Location:
trunk
Files:
4 edited

Legend:

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

    r84984 r85712  
    4444 *           The guest itself uses VBOXDNDCONNECTMSG to report its supported protocol version to the DnD service.
    4545 *
    46  *     Protocol v3 (VBox 5.0.10 and up, current):
     46 *     Protocol v3 (VBox 5.0.10 and up, deprecated):
    4747 *         + Added VBOXDNDDISCONNECTMSG for being able to track client disconnects on host side (Main).
    4848 *         + Added context IDs for every HGCM message. Not used yet and must be 0.
     
    5656 *         - Removed unused HOST_DND_GH_RECV_DIR, HOST_DND_GH_RECV_FILE_DATA and HOST_DND_GH_RECV_FILE_HDR commands.
    5757 *
    58  * Protocol TODO:
    59  *
    60  *     - Split up messages which use VBOXDNDHGACTIONMSG into own functions and remove parameters which
    61  *       are not actually needed / used by a function. Why does HOST_DND_HG_EVT_MOVE need all the format stuff, for example?
     58 *     VBox 6.1.x and up, current:
     59 *         + Added GUEST_DND_QUERY_FEATURES + GUEST_DND_REPORT_FEATURES.
     60 *         - Protocol versioning support in VBOXDNDCONNECTMSG is now marked as being deprecated.
     61 *
     62 ** @todo:
     63 * - Split up messages which use VBOXDNDHGACTIONMSG into own functions and remove parameters which
     64 *   are not actually needed / used by a function. Why does HOST_DND_HG_EVT_MOVE need all the format stuff, for example?
    6265 */
    6366
     
    170173    GUEST_DND_DISCONNECT               = 11,
    171174
     175    /** Report guest side feature flags and retrieve the host ones.
     176     *
     177     * Two 64-bit parameters are passed in from the guest with the guest features
     178     * (VBOX_DND_GF_XXX), the host replies by replacing the parameter values with
     179     * the host ones (VBOX_DND_HF_XXX).
     180     *
     181     * @retval  VINF_SUCCESS on success.
     182     * @retval  VERR_INVALID_CLIENT_ID
     183     * @retval  VERR_WRONG_PARAMETER_COUNT
     184     * @retval  VERR_WRONG_PARAMETER_TYPE
     185     * @since   6.1.x
     186     */
     187    GUEST_DND_REPORT_FEATURES          = 12,
     188
     189    /** Query the host ones feature masks.
     190     *
     191     * That way the guest (client) can get hold of the features from the host.
     192     * Again, it is prudent to set the 127 bit and observe it being cleared on
     193     * success, as older hosts might return success without doing anything.
     194     *
     195     * @retval  VINF_SUCCESS on success.
     196     * @retval  VERR_INVALID_CLIENT_ID
     197     * @retval  VERR_WRONG_PARAMETER_COUNT
     198     * @retval  VERR_WRONG_PARAMETER_TYPE
     199     * @since   6.1.x
     200     */
     201    GUEST_DND_QUERY_FEATURES           = 13,
     202
    172203    /**
    173204     * The guest waits for a new message the host wants to process
     
    223254};
    224255
     256/** @name VBOX_DND_GF_XXX - Guest features.
     257 * @sa GUEST_DND_REPORT_FEATURES
     258 * @{ */
     259/** No flags set. */
     260#define VBOX_DND_GF_NONE                          0
     261/** Bit that must be set in the 2nd parameter, will be cleared if the host reponds
     262 * correctly (old hosts might not). */
     263#define VBOX_DND_GF_1_MUST_BE_ONE                 RT_BIT_64(63)
     264/** @} */
     265
     266/** @name VBOX_DND_HF_XXX - Host features.
     267 * @sa DND_GUEST_REPORT_FEATURES
     268 * @{ */
     269/** No flags set. */
     270#define VBOX_DND_HF_NONE                          0
     271/** @} */
     272
    225273/**
    226274 * DnD operation progress states.
     
    642690        struct
    643691        {
    644             /** Protocol version to use. */
     692            /** Protocol version to use.
     693             *  Deprecated since VBox 6.1.x. Do not use / rely on it anymore. */
    645694            HGCMFunctionParameter uProtocol;     /* OUT uint32_t */
    646695            /** Connection flags. Optional. */
     
    651700            /** Context ID. Unused at the moment. */
    652701            HGCMFunctionParameter uContext;     /* OUT uint32_t */
    653             /** Protocol version to use. */
     702            /** Protocol version to use.
     703             *  Deprecated since VBox 6.1.x. Do not use / rely on it anymore. */
    654704            HGCMFunctionParameter uProtocol;     /* OUT uint32_t */
    655705            /** Connection flags. Optional. */
     
    900950    /** Callback data header. */
    901951    VBOXDNDCBHEADERDATA         hdr;
     952    /** Protocol version to use.
     953     *  Deprecated since VBox 6.1.x. Do not use / rely on it anymore. */
    902954    uint32_t                    uProtocol;
    903955    uint32_t                    uFlags;
  • trunk/include/VBox/VBoxGuestLib.h

    r85371 r85712  
    11541154    /** The VM's current session ID. */
    11551155    uint64_t uSessionID;
    1156     /** Protocol version to use. */
    1157     uint32_t uProtocol;
     1156    /** Protocol version to use.
     1157     *  Deprecated; do not used / rely on it anymore. */
     1158    uint32_t uProtocolDeprecated;
     1159    /** Host feature flags (VBOX_DND_HF_XXX).
     1160     * This is set by VbglR3DnDConnect(). */
     1161    uint64_t fHostFeatures;
     1162    /** The guest feature flags reported to the host (VBOX_DND_GF_XXX).
     1163     * This is set by VbglR3DnDConnect().  */
     1164    uint64_t fGuestFeatures;
    11581165    /** Number of parameters retrieved for the current command. */
    11591166    uint32_t uNumParms;
     
    12981305VBGLR3DECL(int)     VbglR3DnDDisconnect(PVBGLR3GUESTDNDCMDCTX pCtx);
    12991306
     1307VBGLR3DECL(int)     VbglR3DnDReportFeatures(uint32_t idClient, uint64_t fGuestFeatures, uint64_t *pfHostFeatures);
     1308
    13001309VBGLR3DECL(int)     VbglR3DnDEventGetNext(PVBGLR3GUESTDNDCMDCTX pCtx, PVBGLR3DNDEVENT *ppEvent);
    13011310VBGLR3DECL(void)    VbglR3DnDEventFree(PVBGLR3DNDEVENT pEvent);
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDragAndDrop.cpp

    r85587 r85712  
    685685    AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
    686686
    687     Assert(pCtx->uProtocol >= 3); /* Only for protocol v3 and up. */
     687    Assert(pCtx->uProtocolDeprecated >= 3); /* Only for protocol v3 and up. */
    688688
    689689    HGCMMsgHGSendDataHdr Msg;
     
    10121012    Assert(pCtx->uClientID);
    10131013
    1014     /* Set the default protocol version we would like to use. */
    1015     pCtx->uProtocol = 3;
     1014    /* Set the default protocol version we would like to use.
     1015     * Deprecated since VBox 6.1.x, but let this set to 3 to (hopefully) not break things. */
     1016    pCtx->uProtocolDeprecated = 3;
     1017
     1018    pCtx->fHostFeatures  = VBOX_DND_HF_NONE;
     1019    pCtx->fGuestFeatures = VBOX_DND_GF_NONE;
    10161020
    10171021    /*
     
    10301034    HGCMMsgConnect Msg;
    10311035    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_CONNECT, 3);
    1032     /** @todo Context ID not used yet. */
    1033     Msg.u.v3.uContext.SetUInt32(0);
    1034     Msg.u.v3.uProtocol.SetUInt32(pCtx->uProtocol);
    1035     Msg.u.v3.uFlags.SetUInt32(0); /* Unused at the moment. */
     1036    Msg.u.v3.uContext.SetUInt32(0);                /** @todo Context ID not used yet. */
     1037    Msg.u.v3.uProtocol.SetUInt32(pCtx->uProtocolDeprecated); /* Deprecated since VBox 6.1.x. */
     1038    Msg.u.v3.uFlags.SetUInt32(0);                  /* Unused at the moment. */
    10361039
    10371040    rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     
    10391042    {
    10401043        /* Set the protocol version we're going to use as told by the host. */
    1041         rc = Msg.u.v3.uProtocol.GetUInt32(&pCtx->uProtocol); AssertRC(rc);
     1044        rc = Msg.u.v3.uProtocol.GetUInt32(&pCtx->uProtocolDeprecated); AssertRC(rc);
     1045
     1046        /*
     1047         * Next is reporting our features.  If this fails, assume older host.
     1048         */
     1049        rc2 = VbglR3DnDReportFeatures(pCtx->uClientID, pCtx->fGuestFeatures, &pCtx->fHostFeatures);
     1050        if (RT_SUCCESS(rc2))
     1051        {
     1052            LogRel2(("DnD: Guest features: %#RX64 - Host features: %#RX64\n",
     1053                     pCtx->fGuestFeatures, pCtx->fHostFeatures));
     1054        }
     1055        else /* Failing here is not fatal; might be running with an older host. */
     1056        {
     1057            AssertLogRelMsg(rc2 == VERR_NOT_SUPPORTED || rc2 == VERR_NOT_IMPLEMENTED,
     1058                            ("Reporting features failed: %Rrc\n", rc2));
     1059        }
    10421060
    10431061        pCtx->cbMaxChunkSize = DND_DEFAULT_CHUNK_SIZE; /** @todo Use a scratch buffer on the heap? */
    10441062    }
    10451063    else
    1046         pCtx->uProtocol = 0; /*  We're using protocol v0 (initial draft) as a fallback. */
    1047 
    1048     /** @todo Implement protocol feature flags. */
    1049 
    1050     LogFlowFunc(("uClient=%RU32, uProtocol=%RU32, rc=%Rrc\n", pCtx->uClientID, pCtx->uProtocol, rc));
     1064        pCtx->uProtocolDeprecated = 0; /*  We're using protocol v0 (initial draft) as a fallback. */
     1065
     1066    LogFlowFunc(("uClient=%RU32, uProtocol=%RU32, rc=%Rrc\n", pCtx->uClientID, pCtx->uProtocolDeprecated, rc));
    10511067    return rc;
    10521068}
     
    10661082        pCtx->uClientID = 0;
    10671083    return rc;
     1084}
     1085
     1086/**
     1087 * Reports features to the host and retrieve host feature set.
     1088 *
     1089 * @returns VBox status code.
     1090 * @param   idClient        The client ID returned by VbglR3DnDConnect().
     1091 * @param   fGuestFeatures  Features to report, VBOX_DND_GF_XXX.
     1092 * @param   pfHostFeatures  Where to store the features VBOX_DND_HF_XXX.
     1093 */
     1094VBGLR3DECL(int) VbglR3DnDReportFeatures(uint32_t idClient, uint64_t fGuestFeatures, uint64_t *pfHostFeatures)
     1095{
     1096    int rc;
     1097    do
     1098    {
     1099        struct
     1100        {
     1101            VBGLIOCHGCMCALL         Hdr;
     1102            HGCMFunctionParameter   f64Features0;
     1103            HGCMFunctionParameter   f64Features1;
     1104        } Msg;
     1105        VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_DND_REPORT_FEATURES, 2);
     1106        VbglHGCMParmUInt64Set(&Msg.f64Features0, fGuestFeatures);
     1107        VbglHGCMParmUInt64Set(&Msg.f64Features1, VBOX_DND_GF_1_MUST_BE_ONE);
     1108
     1109        rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
     1110        if (RT_SUCCESS(rc))
     1111        {
     1112            Assert(Msg.f64Features0.type == VMMDevHGCMParmType_64bit);
     1113            Assert(Msg.f64Features1.type == VMMDevHGCMParmType_64bit);
     1114            if (Msg.f64Features1.u.value64 & VBOX_DND_GF_1_MUST_BE_ONE)
     1115                rc = VERR_NOT_SUPPORTED;
     1116            else if (pfHostFeatures)
     1117                *pfHostFeatures = Msg.f64Features0.u.value64;
     1118            break;
     1119        }
     1120    } while (rc == VERR_INTERRUPTED);
     1121    return rc;
     1122
    10681123}
    10691124
  • trunk/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.cpp

    r85681 r85712  
    5050{
    5151public:
     52
    5253    DragAndDropClient(uint32_t idClient)
    5354        : HGCM::Client(idClient)
     55        , fGuestFeatures0(VBOX_DND_GF_NONE)
     56        , fGuestFeatures1(VBOX_DND_GF_NONE)
    5457    {
    5558        RT_ZERO(m_SvcCtx);
     
    6265
    6366public:
     67
    6468    void disconnect(void) RT_NOEXCEPT;
     69
     70public:
     71
     72    /** Guest feature flags, VBOX_DND_GF_0_XXX. */
     73    uint64_t                fGuestFeatures0;
     74    /** Guest feature flags, VBOX_DND_GF_1_XXX. */
     75    uint64_t                fGuestFeatures1;
    6576};
    6677
     
    8899    int  clientConnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT RT_OVERRIDE;
    89100    int  clientDisconnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT RT_OVERRIDE;
     101    int  clientQueryFeatures(DragAndDropClient *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT;
     102    int  clientReportFeatures(DragAndDropClient *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT;
    90103    void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t idClient, void *pvClient, uint32_t u32Function,
    91104                   uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT RT_OVERRIDE;
     
    112125    /** Current drag and drop mode, VBOX_DRAG_AND_DROP_MODE_XXX. */
    113126    uint32_t                           m_u32Mode;
     127    /** Host feature mask (VBOX_DND_HF_0_XXX) for DND_GUEST_REPORT_FEATURES
     128     * and DND_GUEST_QUERY_FEATURES. */
     129    uint64_t                           m_fHostFeatures0;
    114130};
    115131
     
    166182    modeSet(VBOX_DRAG_AND_DROP_MODE_OFF);
    167183
     184    /* Set host features. */
     185    m_fHostFeatures0 = VBOX_DND_HF_NONE;
     186
    168187    int rc = VINF_SUCCESS;
    169188
     
    274293}
    275294
     295/**
     296 * Implements GUEST_DND_REPORT_FEATURES.
     297 *
     298 * @returns VBox status code.
     299 * @retval  VINF_HGCM_ASYNC_EXECUTE on success (we complete the message here).
     300 * @retval  VERR_ACCESS_DENIED if not master
     301 * @retval  VERR_INVALID_PARAMETER if bit 63 in the 2nd parameter isn't set.
     302 * @retval  VERR_WRONG_PARAMETER_COUNT
     303 *
     304 * @param   pClient     The client state.
     305 * @param   hCall       The client's call handle.
     306 * @param   cParms      Number of parameters.
     307 * @param   paParms     Array of parameters.
     308 */
     309int DragAndDropService::clientReportFeatures(DragAndDropClient *pClient,
     310                                             VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT
     311{
     312    /*
     313     * Validate the request.
     314     */
     315    ASSERT_GUEST_RETURN(cParms == 2, VERR_WRONG_PARAMETER_COUNT);
     316    ASSERT_GUEST_RETURN(paParms[0].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_WRONG_PARAMETER_TYPE);
     317    uint64_t const fFeatures0 = paParms[0].u.uint64;
     318    ASSERT_GUEST_RETURN(paParms[1].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_WRONG_PARAMETER_TYPE);
     319    uint64_t const fFeatures1 = paParms[1].u.uint64;
     320    ASSERT_GUEST_RETURN(fFeatures1 & VBOX_DND_GF_1_MUST_BE_ONE, VERR_INVALID_PARAMETER);
     321
     322    /*
     323     * Do the work.
     324     */
     325    paParms[0].u.uint64 = m_fHostFeatures0;
     326    paParms[1].u.uint64 = 0;
     327
     328    int rc = pClient->Complete(hCall, VINF_SUCCESS);
     329    if (RT_SUCCESS(rc))
     330    {
     331        pClient->fGuestFeatures0 = fFeatures0;
     332        pClient->fGuestFeatures1 = fFeatures1;
     333        Log(("[Client %RU32] features: %#RX64 %#RX64\n", pClient->GetClientID(), fFeatures0, fFeatures1));
     334    }
     335    else
     336        LogFunc(("pfnCallComplete -> %Rrc\n", rc));
     337
     338    return VINF_HGCM_ASYNC_EXECUTE;
     339}
     340
     341/**
     342 * Implements GUEST_DND_QUERY_FEATURES.
     343 *
     344 * @returns VBox status code.
     345 * @retval  VINF_HGCM_ASYNC_EXECUTE on success (we complete the message here).
     346 * @retval  VERR_WRONG_PARAMETER_COUNT
     347 *
     348 * @param   pClient     The client state.
     349 * @param   hCall       The client's call handle.
     350 * @param   cParms      Number of parameters.
     351 * @param   paParms     Array of parameters.
     352 */
     353int DragAndDropService::clientQueryFeatures(DragAndDropClient *pClient,
     354                                            VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT
     355{
     356    /*
     357     * Validate the request.
     358     */
     359    ASSERT_GUEST_RETURN(cParms == 2, VERR_WRONG_PARAMETER_COUNT);
     360    ASSERT_GUEST_RETURN(paParms[0].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_WRONG_PARAMETER_TYPE);
     361    ASSERT_GUEST_RETURN(paParms[1].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_WRONG_PARAMETER_TYPE);
     362    ASSERT_GUEST(paParms[1].u.uint64 & RT_BIT_64(63));
     363
     364    /*
     365     * Do the work.
     366     */
     367    paParms[0].u.uint64 = m_fHostFeatures0;
     368    paParms[1].u.uint64 = 0;
     369
     370    int rc = pClient->Complete(hCall, VINF_SUCCESS);
     371    if (RT_FAILURE(rc))
     372        LogFunc(("pfnCallComplete -> %Rrc\n", rc));
     373
     374    return VINF_HGCM_ASYNC_EXECUTE;
     375}
     376
    276377int DragAndDropService::modeSet(uint32_t u32Mode) RT_NOEXCEPT
    277378{
     
    327428        /* New since protocol v2. */
    328429        case GUEST_DND_CONNECT:
     430            RT_FALL_THROUGH();
     431        /* New since VBox 6.1.x. */
     432        case GUEST_DND_REPORT_FEATURES:
     433            RT_FALL_THROUGH();
     434        /* New since VBox 6.1.x. */
     435        case GUEST_DND_QUERY_FEATURES:
    329436        {
    330437            /*
    331              * Never block the initial connect call, as the clients do this when
     438             * Never block these calls, as the clients issues those when
    332439             * initializing and might get stuck if drag and drop is set to "disabled" at
    333440             * that time.
     
    524631                break;
    525632            }
     633            case GUEST_DND_REPORT_FEATURES:
     634            {
     635                LogFlowFunc(("GUEST_DND_REPORT_FEATURES\n"));
     636                rc = clientReportFeatures(pClient, callHandle, cParms, paParms);
     637                break;
     638            }
     639            case GUEST_DND_QUERY_FEATURES:
     640            {
     641                LogFlowFunc(("GUEST_DND_QUERY_FEATURES"));
     642                rc = clientQueryFeatures(pClient, callHandle, cParms, paParms);
     643                break;
     644            }
    526645            case GUEST_DND_HG_ACK_OP:
    527646            {
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette