VirtualBox

Changeset 50523 in vbox


Ignore:
Timestamp:
Feb 20, 2014 12:00:58 PM (11 years ago)
Author:
vboxsync
Message:

Addiitions/common/VBoxGuest, VBoxGuestLibR3: add mediation in the guest driver for guest capabilities, mouse status and event filtering.

Location:
trunk/src/VBox/Additions/common
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r50391 r50523  
    6666static DECLCALLBACK(int) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdrNonVolatile, void *pvUser, uint32_t u32User);
    6767#endif
    68 #ifdef DEBUG
    69 static void testSetMouseStatus(void);
    70 #endif
    71 static int VBoxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures);
    7268
    7369static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags);
     
    126122        *pu32OtherVal = fNotVal;
    127123    return fResult;
     124}
     125
     126
     127/**
     128 * Sets the interrupt filter mask during initialization and termination.
     129 *
     130 * This will ASSUME that we're the ones in carge over the mask, so
     131 * we'll simply clear all bits we don't set.
     132 *
     133 * @returns VBox status code (ignored).
     134 * @param   fMask       The new mask.
     135 */
     136static int vboxGuestSetFilterMask(uint32_t fMask)
     137{
     138    VMMDevCtlGuestFilterMask *pReq;
     139    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask);
     140    if (RT_SUCCESS(rc))
     141    {
     142        pReq->u32OrMask = fMask;
     143        pReq->u32NotMask = ~fMask;
     144        rc = VbglGRPerform(&pReq->header);
     145        if (RT_FAILURE(rc))
     146            LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc\n", rc));
     147        VbglGRFree(&pReq->header);
     148    }
     149    return rc;
     150}
     151
     152
     153/**
     154 * Sets the guest capabilities to the host.
     155 *
     156 * This will ASSUME that we're the ones in charge of the mask, so
     157 * we'll simply clear all bits we don't set.
     158 *
     159 * @returns VBox status code.
     160 * @param   fMask       The new mask.
     161 */
     162static int vboxGuestSetCapabilities(uint32_t fMask)
     163{
     164    VMMDevReqGuestCapabilities2 *pReq;
     165    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq),
     166                         VMMDevReq_SetGuestCapabilities);
     167    if (RT_SUCCESS(rc))
     168    {
     169        pReq->u32OrMask = fMask;
     170        pReq->u32NotMask = ~fMask;
     171        rc = VbglGRPerform(&pReq->header);
     172        if (RT_FAILURE(rc))
     173            LogRelFunc(("failed with rc=%Rrc\n", rc));
     174        VbglGRFree(&pReq->header);
     175    }
     176    return rc;
     177}
     178
     179
     180/**
     181 * Sets the mouse status to the host.
     182 *
     183 * This will ASSUME that we're the ones in charge of the mask, so
     184 * we'll simply clear all bits we don't set.
     185 *
     186 * @returns VBox status code.
     187 * @param   fMask       The new mask.
     188 */
     189static int vboxGuestSetMouseStatus(uint32_t fMask)
     190{
     191    VMMDevReqMouseStatus *pReq;
     192    int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq),
     193                         VMMDevReq_SetMouseStatus);
     194    if (RT_SUCCESS(rc))
     195    {
     196        pReq->mouseFeatures = fMask;
     197        pReq->pointerXPos   = 0;
     198        pReq->pointerYPos   = 0;
     199        rc = VbglGRPerform(&pReq->header);
     200        if (RT_FAILURE(rc))
     201            LogRelFunc(("failed with rc=%Rrc\n", rc));
     202        VbglGRFree(&pReq->header);
     203    }
     204    return rc;
     205}
     206
     207
     208/** Host flags to be updated by a given invokation of the
     209 * vboxGuestUpdateHostFlags() method. */
     210enum
     211{
     212    HostFlags_FilterMask = 1,
     213    HostFlags_Capabilities,
     214    HostFlags_MouseStatus,
     215    HostFlags_SizeHack = (unsigned)-1
     216};
     217
     218
     219/** Check which host flags in a given category are being asserted by some guest
     220 * session and assert exactly those on the host which are being asserted by one
     221 * or more sessions.  pCallingSession is purely for sanity checking and can be
     222 * NULL. */
     223static int vboxGuestUpdateHostFlags(PVBOXGUESTDEVEXT pDevExt,
     224                                    PVBOXGUESTSESSION pSession,
     225                                    unsigned enmFlags)
     226{
     227    int rc = VINF_SUCCESS;
     228    uint32_t fFilterMask = 0, fCapabilities = 0, fMouseStatus = 0;
     229    PVBOXGUESTSESSION pIterator;
     230    unsigned cSessions = 0;
     231
     232    RTSpinlockAcquire(pDevExt->SessionSpinlock);
     233    RTListForEach(&pDevExt->SessionList, pIterator, VBOXGUESTSESSION, ListNode)
     234    {
     235        fFilterMask   |= pIterator->fFilterMask;
     236        fCapabilities |= pIterator->fCapabilities;
     237        fMouseStatus  |= pIterator->fMouseStatus;
     238        ++cSessions;
     239    }
     240    if (!cSessions)
     241        if (fFilterMask | fCapabilities | fMouseStatus)
     242            rc = VERR_INTERNAL_ERROR;
     243    if (cSessions == 1 && pSession)
     244        if (   fFilterMask   != pSession->fFilterMask
     245            || fCapabilities != pSession->fCapabilities
     246            || fMouseStatus  != pSession->fMouseStatus)
     247            rc = VERR_INTERNAL_ERROR;
     248    if (cSessions > 1 && pSession)
     249        if (   ~fFilterMask   & pSession->fFilterMask
     250            || ~fCapabilities & pSession->fCapabilities
     251            || ~fMouseStatus  & pSession->fMouseStatus)
     252            rc = VERR_INTERNAL_ERROR;
     253    if (RT_SUCCESS(rc))
     254    {
     255        if (enmFlags & HostFlags_FilterMask)
     256            vboxGuestSetFilterMask(fFilterMask | pDevExt->fFixedEvents);
     257        if (enmFlags & HostFlags_Capabilities)
     258            vboxGuestSetCapabilities(fCapabilities);
     259        /* Since VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR is inverted in the session
     260         * capabilities we invert it again before sending it to the host. */
     261        fMouseStatus ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
     262        if (enmFlags & HostFlags_MouseStatus)
     263            vboxGuestSetMouseStatus(fMouseStatus);
     264    }
     265    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
     266    return rc;
    128267}
    129268
     
    332471
    333472/**
    334  * Sets the interrupt filter mask during initialization and termination.
    335  *
    336  * This will ASSUME that we're the ones in carge over the mask, so
    337  * we'll simply clear all bits we don't set.
    338  *
    339  * @returns VBox status code (ignored).
    340  * @param   pDevExt     The device extension.
    341  * @param   fMask       The new mask.
    342  */
    343 static int vboxGuestSetFilterMask(PVBOXGUESTDEVEXT pDevExt, uint32_t fMask)
    344 {
    345     VMMDevCtlGuestFilterMask *pReq;
    346     int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask);
    347     if (RT_SUCCESS(rc))
    348     {
    349         pReq->u32OrMask = fMask;
    350         pReq->u32NotMask = ~fMask;
    351         rc = VbglGRPerform(&pReq->header);
    352         if (RT_FAILURE(rc))
    353             LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc\n", rc));
    354         VbglGRFree(&pReq->header);
    355     }
    356     return rc;
    357 }
    358 
    359 
    360 /**
    361473 * Inflate the balloon by one chunk represented by an R0 memory object.
    362474 *
     
    799911    RTListInit(&pDevExt->WokenUpList);
    800912    RTListInit(&pDevExt->FreeList);
     913    RTListInit(&pDevExt->SessionList);
    801914#ifdef VBOX_WITH_VRDP_SESSION_HANDLING
    802915    pDevExt->fVRDPEnabled = false;
     
    812925    pDevExt->MemBalloon.paMemObj = NULL;
    813926    pDevExt->MemBalloon.pOwner = NULL;
    814     for (i = 0; i < RT_ELEMENTS(pDevExt->acMouseFeatureUsage); ++i)
    815         pDevExt->acMouseFeatureUsage[i] = 0;
    816     pDevExt->fMouseStatus = 0;
    817927    pDevExt->MouseNotifyCallback.pfnNotify = NULL;
    818928    pDevExt->MouseNotifyCallback.pvUser = NULL;
     
    883993            if (RT_SUCCESS(rc))
    884994            {
    885                 rc = vboxGuestSetFilterMask(pDevExt, fFixedEvents);
     995                rc = vboxGuestSetFilterMask(fFixedEvents);
    886996                if (RT_SUCCESS(rc))
    887997                {
     
    8901000                     * graphics driver will re-enable this when it is necessary.
    8911001                     */
    892                     rc = VBoxGuestSetGuestCapabilities(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS);
     1002                    rc = vboxGuestSetCapabilities(0);
    8931003                    if (RT_SUCCESS(rc))
    8941004                    {
    8951005                        vboxGuestInitFixateGuestMappings(pDevExt);
    8961006
    897 #ifdef DEBUG
    898                         testSetMouseStatus();  /* Other tests? */
    899 #endif
    900 
    9011007                        rc = VBoxGuestReportDriverStatus(true /* Driver is active */);
    9021008                        if (RT_FAILURE(rc))
     
    9071013                    }
    9081014
    909                     LogRel(("VBoxGuestInitDevExt: VBoxGuestSetGuestCapabilities failed, rc=%Rrc\n", rc));
     1015                    LogRel(("VBoxGuestInitDevExt: vboxGuestSetCapabilities failed, rc=%Rrc\n", rc));
    9101016                }
    9111017                else
     
    9741080     */
    9751081    vboxGuestTermUnfixGuestMappings(pDevExt);
    976     VBoxGuestSetGuestCapabilities(0, UINT32_MAX);       /* clears all capabilities */
    977     vboxGuestSetFilterMask(pDevExt, 0);                 /* filter all events */
     1082    vboxGuestSetCapabilities(0);                  /* clear all Capabilities */
     1083    vboxGuestSetFilterMask(0);                    /* filter all events */
     1084    vboxGuestSetMouseStatus(0);                   /* clear all mouse features */
    9781085    vboxGuestCloseMemBalloon(pDevExt, (PVBOXGUESTSESSION)NULL);
    9791086
     
    9941101    VBoxGuestDeleteWaitList(&pDevExt->WokenUpList);
    9951102    VBoxGuestDeleteWaitList(&pDevExt->FreeList);
     1103    /** @todo We do not assert that the session list is empty, because probably
     1104     * no one would notice. */
    9961105
    9971106    VbglTerminate();
     
    10321141    pSession->R0Process = RTR0ProcHandleSelf();
    10331142    pSession->pDevExt = pDevExt;
     1143    RTSpinlockAcquire(pDevExt->SessionSpinlock);
     1144    RTListAppend(&pDevExt->SessionList, &pSession->ListNode);
     1145    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
    10341146
    10351147    *ppSession = pSession;
     
    10621174    pSession->R0Process = NIL_RTR0PROCESS;
    10631175    pSession->pDevExt = pDevExt;
     1176    RTSpinlockAcquire(pDevExt->SessionSpinlock);
     1177    RTListAppend(&pDevExt->SessionList, &pSession->ListNode);
     1178    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
    10641179
    10651180    *ppSession = pSession;
     
    10831198         pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
    10841199
     1200    RTSpinlockAcquire(pDevExt->SessionSpinlock);
     1201    RTListNodeRemove(&pSession->ListNode);
     1202    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
    10851203    VBoxGuestCommonGuestCapsAcquire(pDevExt, pSession, 0, UINT32_MAX, VBOXGUESTCAPSACQUIRE_FLAGS_NONE);
    10861204
     
    11041222    pSession->R0Process = NIL_RTR0PROCESS;
    11051223    vboxGuestCloseMemBalloon(pDevExt, pSession);
    1106     /* Reset any mouse status flags which the session may have set. */
    1107     VBoxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession, 0);
     1224    /* Update the host flags (mouse status etc) not to reflect this session. */
     1225    vboxGuestUpdateHostFlags(pDevExt, NULL,
     1226         HostFlags_FilterMask | HostFlags_Capabilities | HostFlags_MouseStatus);
    11081227    RTMemFree(pSession);
    11091228}
     
    18261945
    18271946
    1828 static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, VBoxGuestFilterMaskInfo *pInfo)
    1829 {
    1830     VMMDevCtlGuestFilterMask *pReq;
    1831     int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask);
    1832     if (RT_FAILURE(rc))
    1833     {
    1834         Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
    1835              sizeof(*pReq), sizeof(*pReq), rc));
    1836         return rc;
    1837     }
    1838 
    1839     pReq->u32OrMask = pInfo->u32OrMask;
    1840     pReq->u32NotMask = pInfo->u32NotMask;
    1841     pReq->u32NotMask &= ~pDevExt->fFixedEvents; /* don't permit these to be cleared! */
    1842     rc = VbglGRPerform(&pReq->header);
    1843     if (RT_FAILURE(rc))
    1844         Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: VbglGRPerform failed, rc=%Rrc!\n", rc));
    1845 
    1846     VbglGRFree(&pReq->header);
     1947static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt,
     1948                                              PVBOXGUESTSESSION pSession,
     1949                                              VBoxGuestFilterMaskInfo *pInfo)
     1950{
     1951    int rc;
     1952
     1953    if ((pInfo->u32OrMask | pInfo->u32NotMask) & ~VMMDEV_EVENT_VALID_EVENT_MASK)
     1954        return VERR_INVALID_PARAMETER;
     1955    RTSpinlockAcquire(pDevExt->SessionSpinlock);
     1956    pSession->fFilterMask |= pInfo->u32OrMask;
     1957    pSession->fFilterMask &= ~pInfo->u32NotMask;
     1958    rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_FilterMask);
     1959    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
     1960    return rc;
     1961}
     1962
     1963
     1964static int VBoxGuestCommonIOCtl_SetCapabilities(PVBOXGUESTDEVEXT pDevExt,
     1965                                            PVBOXGUESTSESSION pSession,
     1966                                            VBoxGuestSetCapabilitiesInfo *pInfo)
     1967{
     1968    int rc;
     1969
     1970    if (  (pInfo->u32OrMask | pInfo->u32NotMask)
     1971        & ~VMMDEV_GUEST_CAPABILITIES_MASK)
     1972        return VERR_INVALID_PARAMETER;
     1973    RTSpinlockAcquire(pDevExt->SessionSpinlock);
     1974    pSession->fCapabilities |= pInfo->u32OrMask;
     1975    pSession->fCapabilities &= ~pInfo->u32NotMask;
     1976    rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_Capabilities);
     1977    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
     1978    return rc;
     1979}
     1980
     1981
     1982/**
     1983 * Sets the mouse status features for this session and updates them
     1984 * globally.
     1985 *
     1986 * @returns VBox status code.
     1987 *
     1988 * @param   pDevExt             The device extention.
     1989 * @param   pSession            The session.
     1990 * @param   fFeatures           New bitmap of enabled features.
     1991 */
     1992static int vboxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt,
     1993                                               PVBOXGUESTSESSION pSession,
     1994                                               uint32_t fFeatures)
     1995{
     1996    int rc;
     1997
     1998    if (fFeatures & ~VMMDEV_MOUSE_GUEST_MASK)
     1999        return VERR_INVALID_PARAMETER;
     2000    /* Since this is more of a negative feature we invert it to get the real
     2001     * feature (when the guest does not need the host cursor). */
     2002    fFeatures ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
     2003    RTSpinlockAcquire(pDevExt->SessionSpinlock);
     2004    pSession->fMouseStatus = fFeatures;
     2005    rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_MouseStatus);
     2006    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
    18472007    return rc;
    18482008}
     
    23392499}
    23402500#endif /* VBOX_WITH_VRDP_SESSION_HANDLING */
    2341 
    2342 #ifdef DEBUG
    2343 /** Unit test SetMouseStatus instead of really executing the request. */
    2344 static bool     g_test_fSetMouseStatus = false;
    2345 /** When unit testing SetMouseStatus, the fake RC for the GR to return. */
    2346 static int      g_test_SetMouseStatusGRRC;
    2347 /** When unit testing SetMouseStatus this will be set to the status passed to
    2348  * the GR. */
    2349 static uint32_t g_test_statusSetMouseStatus;
    2350 #endif
    2351 
    2352 static int vboxguestcommonSetMouseStatus(uint32_t fFeatures)
    2353 {
    2354     VMMDevReqMouseStatus *pReq;
    2355     int rc;
    2356 
    2357     LogRelFlowFunc(("fFeatures=%u\n", (int) fFeatures));
    2358     rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetMouseStatus);
    2359     if (RT_SUCCESS(rc))
    2360     {
    2361         pReq->mouseFeatures = fFeatures;
    2362         pReq->pointerXPos = 0;
    2363         pReq->pointerYPos = 0;
    2364 #ifdef DEBUG
    2365         if (g_test_fSetMouseStatus)
    2366         {
    2367             g_test_statusSetMouseStatus = pReq->mouseFeatures;
    2368             rc = g_test_SetMouseStatusGRRC;
    2369         }
    2370         else
    2371 #endif
    2372             rc = VbglGRPerform(&pReq->header);
    2373         VbglGRFree(&pReq->header);
    2374     }
    2375     LogRelFlowFunc(("rc=%Rrc\n", rc));
    2376     return rc;
    2377 }
    2378 
    2379 
    2380 /**
    2381  * Sets the mouse status features for this session and updates them
    2382  * globally.  We aim to ensure that if several threads call this in
    2383  * parallel the most recent status will always end up being set.
    2384  *
    2385  * @returns VBox status code.
    2386  *
    2387  * @param   pDevExt             The device extention.
    2388  * @param   pSession            The session.
    2389  * @param   fFeatures           New bitmap of enabled features.
    2390  */
    2391 static int VBoxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures)
    2392 {
    2393     uint32_t    fNewDevExtStatus = 0;
    2394     unsigned    i;
    2395     int         rc;
    2396     /* Exit early if nothing has changed - hack to work around the
    2397      * Windows Additions not using the common code. */
    2398     bool        fNoAction;
    2399 
    2400     RTSpinlockAcquire(pDevExt->SessionSpinlock);
    2401 
    2402     /* For all the bits which the guest is allowed to set, check whether the
    2403      * requested value is different to the current one and adjust the global
    2404      * usage counter and if appropriate the global state if so. */
    2405     for (i = 0; i < sizeof(fFeatures) * 8; i++)
    2406     {
    2407         if (RT_BIT_32(i) & VMMDEV_MOUSE_GUEST_MASK)
    2408         {
    2409             if (   (RT_BIT_32(i) & fFeatures)
    2410                 && !(RT_BIT_32(i) & pSession->fMouseStatus))
    2411                 pDevExt->acMouseFeatureUsage[i]++;
    2412             else if (   !(RT_BIT_32(i) & fFeatures)
    2413                      && (RT_BIT_32(i) & pSession->fMouseStatus))
    2414                 pDevExt->acMouseFeatureUsage[i]--;
    2415         }
    2416         if (pDevExt->acMouseFeatureUsage[i] > 0)
    2417             fNewDevExtStatus |= RT_BIT_32(i);
    2418     }
    2419 
    2420     pSession->fMouseStatus = fFeatures & VMMDEV_MOUSE_GUEST_MASK;
    2421     fNoAction = (pDevExt->fMouseStatus == fNewDevExtStatus);
    2422     pDevExt->fMouseStatus = fNewDevExtStatus;
    2423 
    2424     RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
    2425     if (fNoAction)
    2426         return VINF_SUCCESS;
    2427 
    2428     do
    2429     {
    2430         fNewDevExtStatus = pDevExt->fMouseStatus;
    2431         rc = vboxguestcommonSetMouseStatus(fNewDevExtStatus);
    2432     } while (   RT_SUCCESS(rc)
    2433              && fNewDevExtStatus != pDevExt->fMouseStatus);
    2434 
    2435     return rc;
    2436 }
    2437 
    2438 
    2439 #ifdef DEBUG
    2440 /** Unit test for the SET_MOUSE_STATUS IoCtl.  Since this is closely tied to
    2441  * the code in question it probably makes most sense to keep it next to the
    2442  * code. */
    2443 static void testSetMouseStatus(void)
    2444 {
    2445     uint32_t u32Data;
    2446     int rc;
    2447     RTSPINLOCK Spinlock;
    2448 
    2449     g_test_fSetMouseStatus = true;
    2450     rc = RTSpinlockCreate(&Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestTest");
    2451     AssertRCReturnVoid(rc);
    2452     {
    2453         VBOXGUESTDEVEXT  DevExt  = { 0 };
    2454         VBOXGUESTSESSION Session = { 0 };
    2455 
    2456         g_test_statusSetMouseStatus = ~0;
    2457         g_test_SetMouseStatusGRRC = VINF_SUCCESS;
    2458         DevExt.SessionSpinlock = Spinlock;
    2459         u32Data = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
    2460         rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
    2461                                   &Session, &u32Data, sizeof(u32Data), NULL);
    2462         AssertRCSuccess(rc);
    2463         AssertMsg(   g_test_statusSetMouseStatus
    2464                   == VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE,
    2465                   ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
    2466         DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR) - 1] = 1;
    2467         rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
    2468                                   &Session, &u32Data, sizeof(u32Data), NULL);
    2469         AssertRCSuccess(rc);
    2470         AssertMsg(   g_test_statusSetMouseStatus
    2471                   == (  VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
    2472                       | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR),
    2473                   ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
    2474         u32Data = VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE;  /* Can't change this */
    2475         rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
    2476                                   &Session, &u32Data, sizeof(u32Data), NULL);
    2477         AssertRCSuccess(rc);
    2478         AssertMsg(   g_test_statusSetMouseStatus
    2479                   == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,
    2480                   ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
    2481         u32Data = VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
    2482         rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
    2483                                   &Session, &u32Data, sizeof(u32Data), NULL);
    2484         AssertRCSuccess(rc);
    2485         AssertMsg(   g_test_statusSetMouseStatus
    2486                   == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,
    2487                   ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
    2488         u32Data = 0;
    2489         rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
    2490                                   &Session, &u32Data, sizeof(u32Data), NULL);
    2491         AssertRCSuccess(rc);
    2492         AssertMsg(   g_test_statusSetMouseStatus
    2493                   == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,
    2494                   ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
    2495         AssertMsg(DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR) - 1] == 1,
    2496                   ("Actual value: %d\n", DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR)]));
    2497         g_test_SetMouseStatusGRRC = VERR_UNRESOLVED_ERROR;
    2498         /* This should succeed as the host request should not be made
    2499          * since nothing has changed. */
    2500         rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
    2501                                   &Session, &u32Data, sizeof(u32Data), NULL);
    2502         AssertRCSuccess(rc);
    2503         /* This should fail with VERR_UNRESOLVED_ERROR as set above. */
    2504         u32Data = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
    2505         rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
    2506                                   &Session, &u32Data, sizeof(u32Data), NULL);
    2507         AssertMsg(rc == VERR_UNRESOLVED_ERROR, ("rc == %Rrc\n", rc));
    2508         /* Untested paths: out of memory; race setting status to host */
    2509    }
    2510     RTSpinlockDestroy(Spinlock);
    2511     g_test_fSetMouseStatus = false;
    2512 }
    2513 #endif
    25142501
    25152502
     
    28822869
    28832870            case VBOXGUEST_IOCTL_CTL_FILTER_MASK:
    2884                 CHECKRET_MIN_SIZE("CTL_FILTER_MASK", sizeof(VBoxGuestFilterMaskInfo));
    2885                 rc = VBoxGuestCommonIOCtl_CtlFilterMask(pDevExt, (VBoxGuestFilterMaskInfo *)pvData);
     2871                CHECKRET_MIN_SIZE("CTL_FILTER_MASK",
     2872                                  sizeof(VBoxGuestFilterMaskInfo));
     2873                rc = VBoxGuestCommonIOCtl_CtlFilterMask(pDevExt, pSession,
     2874                                             (VBoxGuestFilterMaskInfo *)pvData);
    28862875                break;
    28872876
     
    29302919            case VBOXGUEST_IOCTL_SET_MOUSE_STATUS:
    29312920                CHECKRET_SIZE("SET_MOUSE_STATUS", sizeof(uint32_t));
    2932                 rc = VBoxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession,
     2921                rc = vboxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession,
    29332922                                                         *(uint32_t *)pvData);
    29342923                break;
     
    29452934                rc = VBoxGuestCommonIOCTL_GuestCapsAcquire(pDevExt, pSession, (VBoxGuestCapsAquire*)pvData);
    29462935                *pcbDataReturned = sizeof(VBoxGuestCapsAquire);
     2936                break;
     2937
     2938            case VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES:
     2939                CHECKRET_MIN_SIZE("SET_GUEST_CAPABILITIES",
     2940                                  sizeof(VBoxGuestSetCapabilitiesInfo));
     2941                rc = VBoxGuestCommonIOCtl_SetCapabilities(pDevExt, pSession,
     2942                                        (VBoxGuestSetCapabilitiesInfo *)pvData);
    29472943                break;
    29482944
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h

    r50391 r50523  
    158158    /** Spinlock various items in the VBOXGUESTSESSION. */
    159159    RTSPINLOCK                  SessionSpinlock;
     160    /** List of guest sessions (VBOXGUESTSESSION).  We currently traverse this
     161     * but do not search it, so a list data type should be fine.  Use under the
     162     * #SessionSpinlock lock. */
     163    RTLISTANCHOR                SessionList;
    160164#ifdef VBOX_WITH_VRDP_SESSION_HANDLING
    161165    bool                        fVRDPEnabled;
     
    166170    /** Memory balloon information for RTR0MemObjAllocPhysNC(). */
    167171    VBOXGUESTMEMBALLOON         MemBalloon;
    168     /** For each mouse status feature the number of sessions which have
    169      * enabled it.  A feature is enabled globally if at least one session has
    170      * requested it. */
    171     /** @todo can we programmatically determine the size of the array and
    172      * still get the following alignment right? */
    173     uint32_t volatile           acMouseFeatureUsage[32];
    174     /** The mouse feature status matching the counts above.  These are updated
    175      * together inside the session spinlock. */
    176     uint32_t volatile           fMouseStatus;
    177172    /** Counter of number of active ISRs.  Currently used for safely removing
    178173     * the mouse handler callback. */
     
    204199typedef struct VBOXGUESTSESSION
    205200{
     201    /** The list node. */
     202    RTLISTNODE                  ListNode;
    206203#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
    207204    /** Pointer to the next session with the same hash. */
     
    230227     * Used to implement polling.  */
    231228    uint32_t volatile           u32MousePosChangedSeq;
     229    /** VMMDev events requested.  An event type requested in any guest session
     230     * will be added to the host filter.
     231     * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
     232    uint32_t                    fFilterMask;
     233    /** Capabilities supported.  A capability enabled in any guest session will
     234     * be enabled for the host.
     235     * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
     236    uint32_t                    fCapabilities;
    232237    /** Mouse features supported.  A feature enabled in any guest session will
    233      * be enabled for the host. */
    234     uint32_t volatile           fMouseStatus;
     238     * be enabled for the host.
     239     * @note We invert the VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR feature in this
     240     * bitmap.  The logic of this is that the real feature is when the host
     241     * cursor is not needed, and we tell the host it is not needed if any
     242     * session explicitly fails to assert it.  Storing it inverted simplifies
     243     * the checks.
     244     * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
     245    uint32_t                    fMouseStatus;
    235246#ifdef RT_OS_DARWIN
    236247    /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp

    r48938 r50523  
    6060VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot)
    6161{
    62     VMMDevReqGuestCapabilities2 Req;
    63 
    64     vmmdevInitRequest(&Req.header, VMMDevReq_SetGuestCapabilities);
    65     Req.u32OrMask = fOr;
    66     Req.u32NotMask = fNot;
    67     int rc = vbglR3GRPerform(&Req.header);
    68 #if defined(DEBUG)
    69     if (RT_SUCCESS(rc))
    70         LogRel(("Successfully changed guest capabilities: or mask 0x%x, not mask 0x%x.\n", fOr, fNot));
    71     else
    72         LogRel(("Failed to change guest capabilities: or mask 0x%x, not mask 0x%x.  rc=%Rrc.\n", fOr, fNot, rc));
    73 #endif
    74     return rc;
     62    VBoxGuestSetCapabilitiesInfo Info;
     63    Info.u32OrMask = fOr;
     64    Info.u32NotMask = fNot;
     65    return vbglR3DoIOCtl(VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES, &Info,
     66                         sizeof(Info));
    7567}
    7668
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