VirtualBox

Changeset 45778 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Apr 26, 2013 1:44:22 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
85345
Message:

VBoxGuest/VBoxTray: bugfixes & proper handling for multiuser Seamles & Autoresize

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp

    r45763 r45778  
    10061006static VBOXST gVBoxSt;
    10071007
     1008static int vboxStCheckState()
     1009{
     1010    int rc = VINF_SUCCESS;
     1011    WTS_CONNECTSTATE_CLASS *penmConnectState = NULL;
     1012    USHORT *pProtocolType = NULL;
     1013    DWORD cbBuf = 0;
     1014    Assert(0);
     1015    if (gVBoxSt.pfnWTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSConnectState, (LPTSTR *)&penmConnectState, &cbBuf))
     1016    {
     1017        if (gVBoxSt.pfnWTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientProtocolType, (LPTSTR *)&pProtocolType, &cbBuf))
     1018        {
     1019            gVBoxSt.fIsConsole = (*pProtocolType == 0);
     1020            gVBoxSt.enmConnectState = *penmConnectState;
     1021        }
     1022        else
     1023        {
     1024            DWORD dwErr = GetLastError();
     1025            WARN(("VBoxTray: WTSQuerySessionInformationA WTSClientProtocolType failed, error = %08X\n", dwErr));
     1026            rc = RTErrConvertFromWin32(dwErr);
     1027        }
     1028    }
     1029    else
     1030    {
     1031        DWORD dwErr = GetLastError();
     1032        WARN(("VBoxTray: WTSQuerySessionInformationA WTSConnectState failed, error = %08X\n", dwErr));
     1033        rc = RTErrConvertFromWin32(dwErr);
     1034    }
     1035    return rc;
     1036}
     1037
    10081038static int vboxStInit(HWND hWnd)
    10091039{
     
    10341064        }
    10351065
     1066        Assert(0);
     1067
     1068
    10361069        if (rc == VINF_SUCCESS)
    10371070        {
     
    10391072            if (gVBoxSt.pfnWTSRegisterSessionNotification(gVBoxSt.hWTSAPIWnd, NOTIFY_FOR_THIS_SESSION))
    10401073            {
    1041                 WTS_CONNECTSTATE_CLASS *penmConnectState = NULL;
    1042                 USHORT *pProtocolType = NULL;
    1043                 DWORD cbBuf = 0;
    1044                 if (gVBoxSt.pfnWTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSConnectState, (LPTSTR *)&penmConnectState, &cbBuf))
    1045                 {
    1046                     if (gVBoxSt.pfnWTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientProtocolType, (LPTSTR *)&pProtocolType, &cbBuf))
    1047                     {
    1048                         gVBoxSt.fIsConsole = (*pProtocolType == 0);
    1049                         gVBoxSt.enmConnectState = *penmConnectState;
    1050                     }
    1051                     else
    1052                     {
    1053                         DWORD dwErr = GetLastError();
    1054                         WARN(("VBoxTray: WTSQuerySessionInformationA WTSClientProtocolType failed, error = %08X\n", dwErr));
    1055                         rc = RTErrConvertFromWin32(dwErr);
    1056                     }
    1057                 }
    1058                 else
    1059                 {
    1060                     DWORD dwErr = GetLastError();
    1061                     WARN(("VBoxTray: WTSQuerySessionInformationA WTSConnectState failed, error = %08X\n", dwErr));
    1062                     rc = RTErrConvertFromWin32(dwErr);
    1063                 }
     1074                vboxStCheckState();
    10641075                return VINF_SUCCESS;
    10651076            }
     
    11301141    WARN(("VBoxTray: WTS Event: %s\n", vboxStDbgGetString(wEvent)));
    11311142    BOOL fOldIsActiveConsole = vboxStIsActiveConsole();
    1132     switch (wEvent)
    1133     {
    1134         case WTS_CONSOLE_CONNECT:
    1135             gVBoxSt.enmConnectState = WTSConnected;
    1136             gVBoxSt.fIsConsole = TRUE;
    1137             break;
    1138         case WTS_CONSOLE_DISCONNECT:
    1139             gVBoxSt.enmConnectState = WTSDisconnected;
    1140             break;
    1141         case WTS_REMOTE_CONNECT:
    1142             gVBoxSt.enmConnectState = WTSConnected;
    1143             gVBoxSt.fIsConsole = FALSE;
    1144             break;
    1145         case WTS_REMOTE_DISCONNECT:
    1146             gVBoxSt.enmConnectState = WTSDisconnected;
    1147             break;
    1148         case WTS_SESSION_LOGON:
    1149             Assert(gVBoxSt.enmConnectState == WTSConnected);
    1150             gVBoxSt.enmConnectState = WTSActive;
    1151             break;
    1152         case WTS_SESSION_LOGOFF:
    1153             Assert(gVBoxSt.enmConnectState == WTSActive);
    1154             gVBoxSt.enmConnectState = WTSConnected;
    1155             break;
    1156         case WTS_SESSION_LOCK:
    1157             Assert(gVBoxSt.enmConnectState == WTSActive);
    1158             gVBoxSt.enmConnectState = WTSConnected;
    1159             break;
    1160         case WTS_SESSION_UNLOCK:
    1161             Assert(gVBoxSt.enmConnectState == WTSConnected);
    1162             gVBoxSt.enmConnectState = WTSActive;
    1163             break;
    1164         case WTS_SESSION_REMOTE_CONTROL:
    1165             /* todo */
    1166             WARN(("WTS_SESSION_REMOTE_CONTROL handling not implemented!"));
    1167             break;
    1168         default:
    1169             WARN(("unexpected session change notification %d", (DWORD)wEvent));
    1170             break;
    1171     }
     1143
     1144    vboxStCheckState();
    11721145
    11731146    return !vboxStIsActiveConsole() != !fOldIsActiveConsole;
     
    14051378    uint32_t fCap;
    14061379    uint32_t iCap;
    1407     /* the functionality is supported by the guest */
    1408     BOOL fIsSupported;
    1409     /* */
    1410     BOOL fIsOn;
    14111380    VBOXCAPS_ENTRY_FUNCSTATE enmFuncState;
    14121381    VBOXCAPS_ENTRY_ACSTATE enmAcState;
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r45760 r45778  
    7373static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask);
    7474
     75#define VBOXGUEST_ACQUIRE_STYLE_CAPS (VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
     76
    7577DECLINLINE(uint32_t) VBoxGuestCommonGetHandledEventsLocked(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
    7678{
    77     if(!pDevExt->u32GuestCapsAcquireMode)
     79    if(pDevExt->enmGuestCapsAcquireMode != VBOXGUUESTCAPS_MODE_ACQUIRE)
    7880        return VMMDEV_EVENT_VALID_EVENT_MASK;
    7981
    8082    uint32_t u32AquiredGuestCaps = pSession->u32AquiredGuestCaps;
    81     /* only VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST is filtered,
    82      * for now we allow VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST to come through
    83      * to make it still be propagated to r3 client and let clients deal with seamless validity on their own for simplicity */
    84     uint32_t u32CleanupEvents = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
     83    uint32_t u32CleanupEvents = VBOXGUEST_ACQUIRE_STYLE_CAPS;
    8584    if (u32AquiredGuestCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS)
    8685        u32CleanupEvents &= ~VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
     
    9796        ASMAtomicAndU32(&pDevExt->f32PendingEvents, ~fMatches);
    9897    return fMatches;
     98}
     99
     100DECLINLINE(bool) VBoxGuestCommonGuestCapsModeSet(PVBOXGUESTDEVEXT pDevExt, VBOXGUUESTCAPS_MODE enmMode)
     101{
     102    VBOXGUUESTCAPS_MODE enmOldMode;
     103    if (ASMAtomicCmpXchgExU32((volatile uint32_t*)&pDevExt->enmGuestCapsAcquireMode, enmMode, VBOXGUUESTCAPS_MODE_UNDEFINED, (uint32_t*)&enmOldMode))
     104        return true;
     105    return enmOldMode == enmMode;
    99106}
    100107
     
    796803    }
    797804
    798     pDevExt->u32GuestCapsAcquireMode = 0;
     805    pDevExt->enmGuestCapsAcquireMode = VBOXGUUESTCAPS_MODE_UNDEFINED;
    799806    pDevExt->u32GuestCaps = 0;
    800807
     
    15091516 * @param   pReqHdr             The request.
    15101517 */
    1511 static int VBoxGuestCheckIfVMMReqAllowed(PVBOXGUESTSESSION pSession, VMMDevRequestType enmType,
     1518static int VBoxGuestCheckIfVMMReqAllowed(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VMMDevRequestType enmType,
    15121519                                         VMMDevRequestHeader const *pReqHdr)
    15131520{
     
    15751582
    15761583        /*
     1584         * Anyone. But not for CapsAcquire mode
     1585         */
     1586        case VMMDevReq_SetGuestCapabilities:
     1587#if 0
     1588            /* @todo: currently windows clients use both Set and Acquire for different caps
     1589             * this should not lead to any problem, however, better switch to consistent behavior */
     1590            if (!VBoxGuestCommonGuestCapsModeSet(pDevExt, VBOXGUUESTCAPS_MODE_SET))
     1591            {
     1592                Assert(0);
     1593                LogRel(("calling caps set for invalid caps mode %d\n", pDevExt->enmGuestCapsAcquireMode));
     1594                enmRequired = kLevel_NoOne;
     1595                break;
     1596            }
     1597#endif
     1598            /* do not break, make it fall through to the below enmRequired setting */
     1599        /*
    15771600         * Anyone.
    15781601         */
     
    15911614        case VMMDevReq_GetHeightReduction:
    15921615        case VMMDevReq_GetDisplayChangeRequest2:
    1593         case VMMDevReq_SetGuestCapabilities:
    15941616        case VMMDevReq_VideoModeSupported2:
    15951617        case VMMDevReq_VideoAccelEnable:
     
    16881710    }
    16891711
    1690     rc = VBoxGuestCheckIfVMMReqAllowed(pSession, enmType, pReqHdr);
     1712    rc = VBoxGuestCheckIfVMMReqAllowed(pDevExt, pSession, enmType, pReqHdr);
    16911713    if (RT_FAILURE(rc))
    16921714    {
     
    24592481}
    24602482
     2483static void VBoxGuestCommonCheckEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fGenFakeEvents)
     2484{
     2485    RTSpinlockAcquire(pDevExt->EventSpinlock);
     2486    uint32_t fEvents = fGenFakeEvents | pDevExt->f32PendingEvents;
     2487    PVBOXGUESTWAIT  pWait;
     2488    PVBOXGUESTWAIT  pSafe;
     2489
     2490    RTListForEachSafe(&pDevExt->WaitList, pWait, pSafe, VBOXGUESTWAIT, ListNode)
     2491    {
     2492        uint32_t fHandledEvents = VBoxGuestCommonGetHandledEventsLocked(pDevExt, pWait->pSession);
     2493        if (    (pWait->fReqEvents & fEvents & fHandledEvents)
     2494                    &&  !pWait->fResEvents)
     2495        {
     2496            pWait->fResEvents = pWait->fReqEvents & fEvents & fHandledEvents;
     2497            Assert(!(fGenFakeEvents & pWait->fResEvents) || pSession == pWait->pSession);
     2498            fEvents &= ~pWait->fResEvents;
     2499            RTListNodeRemove(&pWait->ListNode);
     2500#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
     2501            RTListAppend(&pDevExt->WakeUpList, &pWait->ListNode);
     2502#else
     2503            RTListAppend(&pDevExt->WokenUpList, &pWait->ListNode);
     2504            rc |= RTSemEventMultiSignal(pWait->Event);
     2505#endif
     2506            if (!fEvents)
     2507                break;
     2508        }
     2509    }
     2510    ASMAtomicWriteU32(&pDevExt->f32PendingEvents, fEvents);
     2511
     2512    RTSpinlockRelease(pDevExt->EventSpinlock);
     2513
     2514#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
     2515    VBoxGuestWaitDoWakeUps(pDevExt);
     2516#endif
     2517}
     2518
    24612519static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask)
    24622520{
     2521    if (!VBoxGuestCommonGuestCapsModeSet(pDevExt, VBOXGUUESTCAPS_MODE_ACQUIRE))
     2522    {
     2523        Assert(0);
     2524        LogRel(("calling caps acquire for invalid caps mode %d\n", pDevExt->enmGuestCapsAcquireMode));
     2525        return VERR_INVALID_STATE;
     2526    }
    24632527    if (!VBoxGuestCommonGuestCapsValidateValues(fOrMask))
    24642528        return VERR_INVALID_PARAMETER;
     
    24752539    RTSpinlockAcquire(pDevExt->EventSpinlock);
    24762540
    2477     pDevExt->u32GuestCapsAcquireMode = 1;
    24782541    fCurrentOwnedCaps      = pSession->u32AquiredGuestCaps;
    24792542    fSessionNotCaps        = fCurrentOwnedCaps & fNotMask;
     
    25132576
    25142577    int rc = VBoxGuestSetGuestCapabilities(fSessionOrCaps, fSessionNotCaps);
    2515     if (RT_SUCCESS(rc))
    2516     {
    2517         /* success! return */
    2518         return VINF_SUCCESS;
    2519     }
    2520 
    2521     /* Failure branch
    2522      * this is generally bad since e.g. failure to release the caps may result in other sessions not being able to use it
    2523      * so we are not trying to restore the caps back to their values before the VBoxGuestCommonGuestCapsAcquire call,
    2524      * but just pretend everithing is OK.
    2525      * @todo: better failure handling mechanism? */
     2578    if (!RT_SUCCESS(rc))
     2579    {
     2580        /* Failure branch
     2581         * this is generally bad since e.g. failure to release the caps may result in other sessions not being able to use it
     2582         * so we are not trying to restore the caps back to their values before the VBoxGuestCommonGuestCapsAcquire call,
     2583         * but just pretend everithing is OK.
     2584         * @todo: better failure handling mechanism? */
     2585    }
     2586
     2587    /* success! */
     2588    uint32_t fGenFakeEvents = 0;
     2589
     2590    if (fSessionOrCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS)
     2591    {
     2592        /* generate the seamless change event so that the r3 app could synch with the seamless state
     2593         * although this introduces a false alarming of r3 client, it still solve the problem of
     2594         * client state inconsistency in multiuser environment */
     2595        fGenFakeEvents |= VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
     2596    }
     2597
     2598    /* since the acquire filter mask has changed, we need to process events in any way to ensure they go from pending events field
     2599     * to the proper (un-filtered) entries */
     2600    VBoxGuestCommonCheckEvents(pDevExt, pSession, fGenFakeEvents);
     2601
    25262602    return VINF_SUCCESS;
    25272603}
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h

    r45760 r45778  
    108108typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON;
    109109
     110typedef enum VBOXGUUESTCAPS_MODE
     111{
     112    VBOXGUUESTCAPS_MODE_UNDEFINED = 0,
     113    /* uncomment when/if guests have consistent Acquire/Set behavior,
     114     * i.e. only either of those should be used, while at leats on win they are used interchangeably */
     115    /*VBOXGUUESTCAPS_MODE_SET,*/
     116    VBOXGUUESTCAPS_MODE_ACQUIRE,
     117    VBOXGUUESTCAPS_MODE_Make32bit = 0x7fffffff,
     118} VBOXGUUESTCAPS_MODE;
    110119
    111120/**
     
    183192    /* true if the driver is in caps acquire mode,
    184193     * i.e. no seamless of resize events are reported unless the driver has acquired the corresponding guest caps */
    185     uint32_t                    u32GuestCapsAcquireMode;
     194    volatile VBOXGUUESTCAPS_MODE enmGuestCapsAcquireMode;
    186195    /* currently acquired (and reported) guest caps */
    187196    uint32_t                    u32GuestCaps;
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