VirtualBox

Changeset 95966 in vbox


Ignore:
Timestamp:
Aug 1, 2022 3:40:29 PM (2 years ago)
Author:
vboxsync
Message:

Additions/VBoxTray: More cleanup: Moved the capabilities and console API into own modules, also the desktop tracking stuff. All lacks documentation, hard to find out what this all does, and why.

Location:
trunk/src/VBox/Additions/WINNT/VBoxTray
Files:
3 added
5 edited

Legend:

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

    r95965 r95966  
    3939VBoxTray_SOURCES  = \
    4040        VBoxTray.cpp \
     41        VBoxCaps.cpp \
     42        VBoxConsole.cpp \
     43        VBoxDesktopTracking.cpp \
    4144        VBoxDispIf.cpp \
    4245        VBoxSeamless.cpp \
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.cpp

    r95961 r95966  
    2929#include <iprt/win/windows.h>
    3030
    31 #include <VBoxDisplay.h> /** @todo r=bird: Presumably the ../include/VBoxDisplay.h file rather than ./VBoxDisplay.h. WTF???  */
    3231#include <VBoxHook.h> /* from ../include/ */
    3332
    3433#include "VBoxTray.h"
     34#include "VBoxTrayInternal.h"
    3535#include "VBoxHelpers.h"
    3636#include "VBoxSeamless.h"
    37 
    3837
    3938
     
    7069*********************************************************************************************************************************/
    7170void VBoxLogString(HANDLE hDriver, char *pszStr);
    72 
     71static void vboxSeamlessSetSupported(BOOL fSupported);
    7372
    7473
     
    105104                && pCtx->pfnVBoxHookRemoveWindowTracker)
    106105            {
    107                 VBoxSeamlessSetSupported(TRUE);
     106                vboxSeamlessSetSupported(TRUE);
    108107
    109108                *ppInstance = pCtx;
     
    136135    AssertPtr(pCtx);
    137136
    138     VBoxSeamlessSetSupported(FALSE);
     137    vboxSeamlessSetSupported(FALSE);
    139138
    140139    /* Inform the host that we no longer support the seamless window mode. */
     
    206205
    207206    VBoxDispIfSeamlessTerm(&gVBoxDispIfSeamless);
     207}
     208
     209void vboxSeamlessSetSupported(BOOL fSupported)
     210{
     211    VBoxConsoleCapSetSupported(VBOXCAPS_ENTRY_IDX_SEAMLESS, fSupported);
    208212}
    209213
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.h

    r93115 r95966  
    2222#endif
    2323
    24 void VBoxSeamlessEnable();
    25 void VBoxSeamlessDisable();
     24void VBoxSeamlessEnable(void);
     25void VBoxSeamlessDisable(void);
    2626void VBoxSeamlessCheckWindows(bool fForce);
    27 
    28 void VBoxSeamlessSetSupported(BOOL fSupported);
    2927
    3028#endif /* !GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxSeamless_h */
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp

    r95965 r95966  
    5656
    5757
    58 
    59 
    60 /*
    61  * Dt (desktop [state] tracking) functionality API
    62  *
    63  * !!!NOTE: this API is NOT thread-safe!!!
    64  * */
    65 static int vboxDtInit();
    66 static void vboxDtTerm();
    67 /* @returns true on "IsInputDesktop" state change */
    68 static BOOL vboxDtHandleEvent();
    69 /* @returns true iff the application (VBoxTray) desktop is input */
    70 static BOOL vboxDtIsInputDesktop();
    71 static HANDLE vboxDtGetNotifyEvent();
    72 static BOOL vboxDtCheckTimer(WPARAM wParam);
    73 
    74 /* caps API */
    75 #define VBOXCAPS_ENTRY_IDX_SEAMLESS  0
    76 #define VBOXCAPS_ENTRY_IDX_GRAPHICS  1
    77 #define VBOXCAPS_ENTRY_IDX_COUNT     2
    78 
    79 typedef enum VBOXCAPS_ENTRY_FUNCSTATE
    80 {
    81     /* the cap is unsupported */
    82     VBOXCAPS_ENTRY_FUNCSTATE_UNSUPPORTED = 0,
    83     /* the cap is supported */
    84     VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED,
    85     /* the cap functionality is started, it can be disabled however if its AcState is not ACQUIRED */
    86     VBOXCAPS_ENTRY_FUNCSTATE_STARTED,
    87 } VBOXCAPS_ENTRY_FUNCSTATE;
    88 
    89 
    90 static void VBoxCapsEntryFuncStateSet(uint32_t iCup, VBOXCAPS_ENTRY_FUNCSTATE enmFuncState);
    91 static int VBoxCapsInit();
    92 static int VBoxCapsReleaseAll();
    93 static void VBoxCapsTerm();
    94 static BOOL VBoxCapsEntryIsAcquired(uint32_t iCap);
    95 static BOOL VBoxCapsEntryIsEnabled(uint32_t iCap);
    96 static BOOL VBoxCapsCheckTimer(WPARAM wParam);
    97 static int VBoxCapsEntryRelease(uint32_t iCap);
    98 static int VBoxCapsEntryAcquire(uint32_t iCap);
    99 static int VBoxCapsAcquireAllSupported();
    100 
    101 /* console-related caps API */
    102 static BOOL VBoxConsoleIsAllowed();
    103 static void VBoxConsoleEnable(BOOL fEnable);
    104 static void VBoxConsoleCapSetSupported(uint32_t iCap, BOOL fSupported);
    105 
    10658static void VBoxGrapicsSetSupported(BOOL fSupported);
    10759
     
    11567/* Global message handler prototypes. */
    11668static int vboxTrayGlMsgTaskbarCreated(WPARAM lParam, LPARAM wParam);
    117 /*static int vboxTrayGlMsgShowBalloonMsg(WPARAM lParam, LPARAM wParam);*/
    118 
    119 static int VBoxAcquireGuestCaps(uint32_t fOr, uint32_t fNot, bool fCfg);
    12069
    12170
     
    828777}
    829778
    830 static void VBoxTrayCheckDt()
    831 {
    832     BOOL fOldAllowedState = VBoxConsoleIsAllowed();
    833     if (vboxDtHandleEvent())
    834     {
    835         if (!VBoxConsoleIsAllowed() != !fOldAllowedState)
    836             VBoxConsoleEnable(!fOldAllowedState);
    837     }
    838 }
    839 
    840779static int vboxTrayServiceMain(void)
    841780{
     
    13781317}
    13791318
    1380 /*
    1381  * Dt (desktop [state] tracking) functionality API impl
    1382  *
    1383  * !!!NOTE: this API is NOT thread-safe!!!
    1384  * */
    1385 
    1386 typedef struct VBOXDT
    1387 {
    1388     HANDLE hNotifyEvent;
    1389     BOOL fIsInputDesktop;
    1390     UINT_PTR idTimer;
    1391     RTLDRMOD hLdrModHook;
    1392     BOOL (* pfnVBoxHookInstallActiveDesktopTracker)(HMODULE hDll);
    1393     BOOL (* pfnVBoxHookRemoveActiveDesktopTracker)();
    1394     HDESK (WINAPI * pfnGetThreadDesktop)(DWORD dwThreadId);
    1395     HDESK (WINAPI * pfnOpenInputDesktop)(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess);
    1396     BOOL (WINAPI * pfnCloseDesktop)(HDESK hDesktop);
    1397 } VBOXDT;
    1398 
    1399 static VBOXDT gVBoxDt;
    1400 
    1401 static BOOL vboxDtCalculateIsInputDesktop()
    1402 {
    1403     BOOL fIsInputDt = FALSE;
    1404     HDESK hInput = gVBoxDt.pfnOpenInputDesktop(0, FALSE, DESKTOP_CREATEWINDOW);
    1405     if (hInput)
    1406     {
    1407 //        DWORD dwThreadId = GetCurrentThreadId();
    1408 //        HDESK hThreadDt = gVBoxDt.pfnGetThreadDesktop(dwThreadId);
    1409 //        if (hThreadDt)
    1410 //        {
    1411             fIsInputDt = TRUE;
    1412 //        }
    1413 //        else
    1414 //        {
    1415 //            DWORD dwErr = GetLastError();
    1416 //            LogFlowFunc(("pfnGetThreadDesktop for Seamless failed, last error = %08X\n", dwErr));
    1417 //        }
    1418 
    1419         gVBoxDt.pfnCloseDesktop(hInput);
    1420     }
    1421     else
    1422     {
    1423 //        DWORD dwErr = GetLastError();
    1424 //        LogFlowFunc(("pfnOpenInputDesktop for Seamless failed, last error = %08X\n", dwErr));
    1425     }
    1426     return fIsInputDt;
    1427 }
    1428 
    1429 static BOOL vboxDtCheckTimer(WPARAM wParam)
    1430 {
    1431     if (wParam != gVBoxDt.idTimer)
    1432         return FALSE;
    1433 
    1434     VBoxTrayCheckDt();
    1435 
    1436     return TRUE;
    1437 }
    1438 
    1439 static int vboxDtInit()
    1440 {
    1441     RT_ZERO(gVBoxDt);
    1442 
    1443     int rc;
    1444     gVBoxDt.hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, VBOXHOOK_GLOBAL_DT_EVENT_NAME);
    1445     if (gVBoxDt.hNotifyEvent != NULL)
    1446     {
    1447         /* Load the hook dll and resolve the necessary entry points. */
    1448         rc = RTLdrLoadAppPriv(VBOXHOOK_DLL_NAME, &gVBoxDt.hLdrModHook);
    1449         if (RT_SUCCESS(rc))
    1450         {
    1451             rc = RTLdrGetSymbol(gVBoxDt.hLdrModHook, "VBoxHookInstallActiveDesktopTracker",
    1452                                 (void **)&gVBoxDt.pfnVBoxHookInstallActiveDesktopTracker);
    1453             if (RT_SUCCESS(rc))
    1454             {
    1455                 rc = RTLdrGetSymbol(gVBoxDt.hLdrModHook, "VBoxHookRemoveActiveDesktopTracker",
    1456                                     (void **)&gVBoxDt.pfnVBoxHookRemoveActiveDesktopTracker);
    1457                 if (RT_FAILURE(rc))
    1458                     LogFlowFunc(("VBoxHookRemoveActiveDesktopTracker not found\n"));
    1459             }
    1460             else
    1461                 LogFlowFunc(("VBoxHookInstallActiveDesktopTracker not found\n"));
    1462             if (RT_SUCCESS(rc))
    1463             {
    1464                 /* Try get the system APIs we need. */
    1465                 *(void **)&gVBoxDt.pfnGetThreadDesktop = RTLdrGetSystemSymbol("user32.dll", "GetThreadDesktop");
    1466                 if (!gVBoxDt.pfnGetThreadDesktop)
    1467                 {
    1468                     LogFlowFunc(("GetThreadDesktop not found\n"));
    1469                     rc = VERR_NOT_SUPPORTED;
    1470                 }
    1471 
    1472                 *(void **)&gVBoxDt.pfnOpenInputDesktop = RTLdrGetSystemSymbol("user32.dll", "OpenInputDesktop");
    1473                 if (!gVBoxDt.pfnOpenInputDesktop)
    1474                 {
    1475                     LogFlowFunc(("OpenInputDesktop not found\n"));
    1476                     rc = VERR_NOT_SUPPORTED;
    1477                 }
    1478 
    1479                 *(void **)&gVBoxDt.pfnCloseDesktop = RTLdrGetSystemSymbol("user32.dll", "CloseDesktop");
    1480                 if (!gVBoxDt.pfnCloseDesktop)
    1481                 {
    1482                     LogFlowFunc(("CloseDesktop not found\n"));
    1483                     rc = VERR_NOT_SUPPORTED;
    1484                 }
    1485 
    1486                 if (RT_SUCCESS(rc))
    1487                 {
    1488                     BOOL fRc = FALSE;
    1489                     /* For Vista and up we need to change the integrity of the security descriptor, too. */
    1490                     uint64_t const uNtVersion = RTSystemGetNtVersion();
    1491                     if (uNtVersion >= RTSYSTEM_MAKE_NT_VERSION(6, 0, 0))
    1492                     {
    1493                         HMODULE hModHook = (HMODULE)RTLdrGetNativeHandle(gVBoxDt.hLdrModHook);
    1494                         Assert((uintptr_t)hModHook != ~(uintptr_t)0);
    1495                         fRc = gVBoxDt.pfnVBoxHookInstallActiveDesktopTracker(hModHook);
    1496                         if (!fRc)
    1497                             LogFlowFunc(("pfnVBoxHookInstallActiveDesktopTracker failed, last error = %08X\n", GetLastError()));
    1498                     }
    1499 
    1500                     if (!fRc)
    1501                     {
    1502                         gVBoxDt.idTimer = SetTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_DT_TIMER, 500, (TIMERPROC)NULL);
    1503                         if (!gVBoxDt.idTimer)
    1504                         {
    1505                             DWORD dwErr = GetLastError();
    1506                             LogFlowFunc(("SetTimer error %08X\n", dwErr));
    1507                             rc = RTErrConvertFromWin32(dwErr);
    1508                         }
    1509                     }
    1510 
    1511                     if (RT_SUCCESS(rc))
    1512                     {
    1513                         gVBoxDt.fIsInputDesktop = vboxDtCalculateIsInputDesktop();
    1514                         return VINF_SUCCESS;
    1515                     }
    1516                 }
    1517             }
    1518 
    1519             RTLdrClose(gVBoxDt.hLdrModHook);
    1520         }
    1521         else
    1522         {
    1523             DWORD dwErr = GetLastError();
    1524             LogFlowFunc(("CreateEvent for Seamless failed, last error = %08X\n", dwErr));
    1525             rc = RTErrConvertFromWin32(dwErr);
    1526         }
    1527 
    1528         CloseHandle(gVBoxDt.hNotifyEvent);
    1529     }
    1530     else
    1531     {
    1532         DWORD dwErr = GetLastError();
    1533         LogFlowFunc(("CreateEvent for Seamless failed, last error = %08X\n", dwErr));
    1534         rc = RTErrConvertFromWin32(dwErr);
    1535     }
    1536 
    1537 
    1538     RT_ZERO(gVBoxDt);
    1539     gVBoxDt.fIsInputDesktop = TRUE;
    1540 
    1541     return rc;
    1542 }
    1543 
    1544 static void vboxDtTerm()
    1545 {
    1546     if (!gVBoxDt.hLdrModHook)
    1547         return;
    1548 
    1549     gVBoxDt.pfnVBoxHookRemoveActiveDesktopTracker();
    1550 
    1551     RTLdrClose(gVBoxDt.hLdrModHook);
    1552     CloseHandle(gVBoxDt.hNotifyEvent);
    1553 
    1554     RT_ZERO(gVBoxDt);
    1555 }
    1556 /* @returns true on "IsInputDesktop" state change */
    1557 static BOOL vboxDtHandleEvent()
    1558 {
    1559     BOOL fIsInputDesktop = gVBoxDt.fIsInputDesktop;
    1560     gVBoxDt.fIsInputDesktop = vboxDtCalculateIsInputDesktop();
    1561     return !fIsInputDesktop != !gVBoxDt.fIsInputDesktop;
    1562 }
    1563 
    1564 static HANDLE vboxDtGetNotifyEvent()
    1565 {
    1566     return gVBoxDt.hNotifyEvent;
    1567 }
    1568 
    1569 /* @returns true iff the application (VBoxTray) desktop is input */
    1570 static BOOL vboxDtIsInputDesktop()
    1571 {
    1572     return gVBoxDt.fIsInputDesktop;
    1573 }
    1574 
    1575 /* we need to perform Acquire/Release using the file handled we use for rewuesting events from VBoxGuest
    1576  * otherwise Acquisition mechanism will treat us as different client and will not propagate necessary requests
    1577  * */
    1578 static int VBoxAcquireGuestCaps(uint32_t fOr, uint32_t fNot, bool fCfg)
    1579 {
    1580     Log(("VBoxAcquireGuestCaps or(0x%x), not(0x%x), cfx(%d)\n", fOr, fNot, fCfg));
    1581     int rc = VbglR3AcquireGuestCaps(fOr, fNot, fCfg);
    1582     if (RT_FAILURE(rc))
    1583         LogFlowFunc(("VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE failed: %Rrc\n", rc));
    1584     return rc;
    1585 }
    1586 
    1587 typedef enum VBOXCAPS_ENTRY_ACSTATE
    1588 {
    1589     /* the given cap is released */
    1590     VBOXCAPS_ENTRY_ACSTATE_RELEASED = 0,
    1591     /* the given cap acquisition is in progress */
    1592     VBOXCAPS_ENTRY_ACSTATE_ACQUIRING,
    1593     /* the given cap is acquired */
    1594     VBOXCAPS_ENTRY_ACSTATE_ACQUIRED
    1595 } VBOXCAPS_ENTRY_ACSTATE;
    1596 
    1597 
    1598 struct VBOXCAPS_ENTRY;
    1599 struct VBOXCAPS;
    1600 
    1601 typedef DECLCALLBACKPTR(void, PFNVBOXCAPS_ENTRY_ON_ENABLE,(struct VBOXCAPS *pConsole, struct VBOXCAPS_ENTRY *pCap, BOOL fEnabled));
    1602 
    1603 typedef struct VBOXCAPS_ENTRY
    1604 {
    1605     uint32_t fCap;
    1606     uint32_t iCap;
    1607     VBOXCAPS_ENTRY_FUNCSTATE enmFuncState;
    1608     VBOXCAPS_ENTRY_ACSTATE enmAcState;
    1609     PFNVBOXCAPS_ENTRY_ON_ENABLE pfnOnEnable;
    1610 } VBOXCAPS_ENTRY;
    1611 
    1612 
    1613 typedef struct VBOXCAPS
    1614 {
    1615     UINT_PTR idTimer;
    1616     VBOXCAPS_ENTRY aCaps[VBOXCAPS_ENTRY_IDX_COUNT];
    1617 } VBOXCAPS;
    1618 
    1619 static VBOXCAPS gVBoxCaps;
    1620 
    1621 static DECLCALLBACK(void) vboxCapsOnEnableSeamless(struct VBOXCAPS *pConsole, struct VBOXCAPS_ENTRY *pCap, BOOL fEnabled)
    1622 {
    1623     RT_NOREF(pConsole, pCap);
    1624     if (fEnabled)
    1625     {
    1626         Log(("vboxCapsOnEnableSeamless: ENABLED\n"));
    1627         Assert(pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED);
    1628         Assert(pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED);
    1629         VBoxSeamlessEnable();
    1630     }
    1631     else
    1632     {
    1633         Log(("vboxCapsOnEnableSeamless: DISABLED\n"));
    1634         Assert(pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRED || pCap->enmFuncState != VBOXCAPS_ENTRY_FUNCSTATE_STARTED);
    1635         VBoxSeamlessDisable();
    1636     }
    1637 }
    1638 
    1639 static void vboxCapsEntryAcStateSet(VBOXCAPS_ENTRY *pCap, VBOXCAPS_ENTRY_ACSTATE enmAcState)
    1640 {
    1641     VBOXCAPS *pConsole = &gVBoxCaps;
    1642 
    1643     Log(("vboxCapsEntryAcStateSet: new state enmAcState(%d); pCap: fCap(%d), iCap(%d), enmFuncState(%d), enmAcState(%d)\n",
    1644             enmAcState, pCap->fCap, pCap->iCap, pCap->enmFuncState, pCap->enmAcState));
    1645 
    1646     if (pCap->enmAcState == enmAcState)
    1647         return;
    1648 
    1649     VBOXCAPS_ENTRY_ACSTATE enmOldAcState = pCap->enmAcState;
    1650     pCap->enmAcState = enmAcState;
    1651 
    1652     if (enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED)
    1653     {
    1654         if (pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED)
    1655         {
    1656             if (pCap->pfnOnEnable)
    1657                 pCap->pfnOnEnable(pConsole, pCap, TRUE);
    1658         }
    1659     }
    1660     else if (enmOldAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED && pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED)
    1661     {
    1662         if (pCap->pfnOnEnable)
    1663             pCap->pfnOnEnable(pConsole, pCap, FALSE);
    1664     }
    1665 }
    1666 
    1667 static void vboxCapsEntryFuncStateSet(VBOXCAPS_ENTRY *pCap, VBOXCAPS_ENTRY_FUNCSTATE enmFuncState)
    1668 {
    1669     VBOXCAPS *pConsole = &gVBoxCaps;
    1670 
    1671     Log(("vboxCapsEntryFuncStateSet: new state enmAcState(%d); pCap: fCap(%d), iCap(%d), enmFuncState(%d), enmAcState(%d)\n",
    1672             enmFuncState, pCap->fCap, pCap->iCap, pCap->enmFuncState, pCap->enmAcState));
    1673 
    1674     if (pCap->enmFuncState == enmFuncState)
    1675         return;
    1676 
    1677     VBOXCAPS_ENTRY_FUNCSTATE enmOldFuncState = pCap->enmFuncState;
    1678 
    1679     pCap->enmFuncState = enmFuncState;
    1680 
    1681     if (enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED)
    1682     {
    1683         Assert(enmOldFuncState == VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED);
    1684         if (pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED)
    1685         {
    1686             if (pCap->pfnOnEnable)
    1687                 pCap->pfnOnEnable(pConsole, pCap, TRUE);
    1688         }
    1689     }
    1690     else if (pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED && enmOldFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED)
    1691     {
    1692         if (pCap->pfnOnEnable)
    1693             pCap->pfnOnEnable(pConsole, pCap, FALSE);
    1694     }
    1695 }
    1696 
    1697 static void VBoxCapsEntryFuncStateSet(uint32_t iCup, VBOXCAPS_ENTRY_FUNCSTATE enmFuncState)
    1698 {
    1699     VBOXCAPS *pConsole = &gVBoxCaps;
    1700     VBOXCAPS_ENTRY *pCap = &pConsole->aCaps[iCup];
    1701     vboxCapsEntryFuncStateSet(pCap, enmFuncState);
    1702 }
    1703 
    1704 static int VBoxCapsInit()
    1705 {
    1706     VBOXCAPS *pConsole = &gVBoxCaps;
    1707     memset(pConsole, 0, sizeof (*pConsole));
    1708     pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].fCap = VMMDEV_GUEST_SUPPORTS_SEAMLESS;
    1709     pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].iCap = VBOXCAPS_ENTRY_IDX_SEAMLESS;
    1710     pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].pfnOnEnable = vboxCapsOnEnableSeamless;
    1711     pConsole->aCaps[VBOXCAPS_ENTRY_IDX_GRAPHICS].fCap = VMMDEV_GUEST_SUPPORTS_GRAPHICS;
    1712     pConsole->aCaps[VBOXCAPS_ENTRY_IDX_GRAPHICS].iCap = VBOXCAPS_ENTRY_IDX_GRAPHICS;
    1713     return VINF_SUCCESS;
    1714 }
    1715 
    1716 static int VBoxCapsReleaseAll()
    1717 {
    1718     VBOXCAPS *pConsole = &gVBoxCaps;
    1719     Log(("VBoxCapsReleaseAll\n"));
    1720     int rc = VBoxAcquireGuestCaps(0, VMMDEV_GUEST_SUPPORTS_SEAMLESS | VMMDEV_GUEST_SUPPORTS_GRAPHICS, false);
    1721     if (!RT_SUCCESS(rc))
    1722     {
    1723         LogFlowFunc(("vboxCapsEntryReleaseAll VBoxAcquireGuestCaps failed rc %d\n", rc));
    1724         return rc;
    1725     }
    1726 
    1727     if (pConsole->idTimer)
    1728     {
    1729         Log(("killing console timer\n"));
    1730         KillTimer(g_hwndToolWindow, pConsole->idTimer);
    1731         pConsole->idTimer = 0;
    1732     }
    1733 
    1734     for (int i = 0; i < RT_ELEMENTS(pConsole->aCaps); ++i)
    1735     {
    1736         vboxCapsEntryAcStateSet(&pConsole->aCaps[i], VBOXCAPS_ENTRY_ACSTATE_RELEASED);
    1737     }
    1738 
    1739     return rc;
    1740 }
    1741 
    1742 static void VBoxCapsTerm()
    1743 {
    1744     VBOXCAPS *pConsole = &gVBoxCaps;
    1745     VBoxCapsReleaseAll();
    1746     memset(pConsole, 0, sizeof (*pConsole));
    1747 }
    1748 
    1749 static BOOL VBoxCapsEntryIsAcquired(uint32_t iCap)
    1750 {
    1751     VBOXCAPS *pConsole = &gVBoxCaps;
    1752     return pConsole->aCaps[iCap].enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED;
    1753 }
    1754 
    1755 static BOOL VBoxCapsEntryIsEnabled(uint32_t iCap)
    1756 {
    1757     VBOXCAPS *pConsole = &gVBoxCaps;
    1758     return pConsole->aCaps[iCap].enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED
    1759             && pConsole->aCaps[iCap].enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED;
    1760 }
    1761 
    1762 static BOOL VBoxCapsCheckTimer(WPARAM wParam)
    1763 {
    1764     VBOXCAPS *pConsole = &gVBoxCaps;
    1765     if (wParam != pConsole->idTimer)
    1766         return FALSE;
    1767 
    1768     uint32_t u32AcquiredCaps = 0;
    1769     BOOL fNeedNewTimer = FALSE;
    1770 
    1771     for (int i = 0; i < RT_ELEMENTS(pConsole->aCaps); ++i)
    1772     {
    1773         VBOXCAPS_ENTRY *pCap = &pConsole->aCaps[i];
    1774         if (pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRING)
    1775             continue;
    1776 
    1777         int rc = VBoxAcquireGuestCaps(pCap->fCap, 0, false);
    1778         if (RT_SUCCESS(rc))
    1779         {
    1780             vboxCapsEntryAcStateSet(&pConsole->aCaps[i], VBOXCAPS_ENTRY_ACSTATE_ACQUIRED);
    1781             u32AcquiredCaps |= pCap->fCap;
    1782         }
    1783         else
    1784         {
    1785             Assert(rc == VERR_RESOURCE_BUSY);
    1786             fNeedNewTimer = TRUE;
    1787         }
    1788     }
    1789 
    1790     if (!fNeedNewTimer)
    1791     {
    1792         KillTimer(g_hwndToolWindow, pConsole->idTimer);
    1793         /* cleanup timer data */
    1794         pConsole->idTimer = 0;
    1795     }
    1796 
    1797     return TRUE;
    1798 }
    1799 
    1800 static int VBoxCapsEntryRelease(uint32_t iCap)
    1801 {
    1802     VBOXCAPS *pConsole = &gVBoxCaps;
    1803     VBOXCAPS_ENTRY *pCap = &pConsole->aCaps[iCap];
    1804     if (pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_RELEASED)
    1805     {
    1806         LogFlowFunc(("invalid cap[%d] state[%d] on release\n", iCap, pCap->enmAcState));
    1807         return VERR_INVALID_STATE;
    1808     }
    1809 
    1810     if (pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED)
    1811     {
    1812         int rc = VBoxAcquireGuestCaps(0, pCap->fCap, false);
    1813         AssertRC(rc);
    1814     }
    1815 
    1816     vboxCapsEntryAcStateSet(pCap, VBOXCAPS_ENTRY_ACSTATE_RELEASED);
    1817 
    1818     return VINF_SUCCESS;
    1819 }
    1820 
    1821 static int VBoxCapsEntryAcquire(uint32_t iCap)
    1822 {
    1823     VBOXCAPS *pConsole = &gVBoxCaps;
    1824     Assert(VBoxConsoleIsAllowed());
    1825     VBOXCAPS_ENTRY *pCap = &pConsole->aCaps[iCap];
    1826     Log(("VBoxCapsEntryAcquire %d\n", iCap));
    1827     if (pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_RELEASED)
    1828     {
    1829         LogFlowFunc(("invalid cap[%d] state[%d] on acquire\n", iCap, pCap->enmAcState));
    1830         return VERR_INVALID_STATE;
    1831     }
    1832 
    1833     vboxCapsEntryAcStateSet(pCap, VBOXCAPS_ENTRY_ACSTATE_ACQUIRING);
    1834     int rc = VBoxAcquireGuestCaps(pCap->fCap, 0, false);
    1835     if (RT_SUCCESS(rc))
    1836     {
    1837         vboxCapsEntryAcStateSet(pCap, VBOXCAPS_ENTRY_ACSTATE_ACQUIRED);
    1838         return VINF_SUCCESS;
    1839     }
    1840 
    1841     if (rc != VERR_RESOURCE_BUSY)
    1842     {
    1843         LogFlowFunc(("vboxCapsEntryReleaseAll VBoxAcquireGuestCaps failed rc %d\n", rc));
    1844         return rc;
    1845     }
    1846 
    1847     LogFlowFunc(("iCap %d is busy!\n", iCap));
    1848 
    1849     /* the cap was busy, most likely it is still used by other VBoxTray instance running in another session,
    1850      * queue the retry timer */
    1851     if (!pConsole->idTimer)
    1852     {
    1853         pConsole->idTimer = SetTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_CAPS_TIMER, 100, (TIMERPROC)NULL);
    1854         if (!pConsole->idTimer)
    1855         {
    1856             DWORD dwErr = GetLastError();
    1857             LogFlowFunc(("SetTimer error %08X\n", dwErr));
    1858             return RTErrConvertFromWin32(dwErr);
    1859         }
    1860     }
    1861 
    1862     return rc;
    1863 }
    1864 
    1865 static int VBoxCapsAcquireAllSupported()
    1866 {
    1867     VBOXCAPS *pConsole = &gVBoxCaps;
    1868     Log(("VBoxCapsAcquireAllSupported\n"));
    1869     for (int i = 0; i < RT_ELEMENTS(pConsole->aCaps); ++i)
    1870     {
    1871         if (pConsole->aCaps[i].enmFuncState >= VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED)
    1872         {
    1873             Log(("VBoxCapsAcquireAllSupported acquiring cap %d, state %d\n", i, pConsole->aCaps[i].enmFuncState));
    1874             VBoxCapsEntryAcquire(i);
    1875         }
    1876         else
    1877         {
    1878             LogFlowFunc(("VBoxCapsAcquireAllSupported: WARN: cap %d not supported, state %d\n", i, pConsole->aCaps[i].enmFuncState));
    1879         }
    1880     }
    1881     return VINF_SUCCESS;
    1882 }
    1883 
    1884 static BOOL VBoxConsoleIsAllowed()
    1885 {
    1886     return vboxDtIsInputDesktop() && vboxStIsActiveConsole();
    1887 }
    1888 
    1889 static void VBoxConsoleEnable(BOOL fEnable)
    1890 {
    1891     if (fEnable)
    1892         VBoxCapsAcquireAllSupported();
    1893     else
    1894         VBoxCapsReleaseAll();
    1895 }
    1896 
    1897 static void VBoxConsoleCapSetSupported(uint32_t iCap, BOOL fSupported)
    1898 {
    1899     if (fSupported)
    1900     {
    1901         VBoxCapsEntryFuncStateSet(iCap, VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED);
    1902 
    1903         if (VBoxConsoleIsAllowed())
    1904             VBoxCapsEntryAcquire(iCap);
    1905     }
    1906     else
    1907     {
    1908         VBoxCapsEntryFuncStateSet(iCap, VBOXCAPS_ENTRY_FUNCSTATE_UNSUPPORTED);
    1909 
    1910         VBoxCapsEntryRelease(iCap);
    1911     }
    1912 }
    1913 
    1914 void VBoxSeamlessSetSupported(BOOL fSupported)
    1915 {
    1916     VBoxConsoleCapSetSupported(VBOXCAPS_ENTRY_IDX_SEAMLESS, fSupported);
    1917 }
    1918 
    19191319static void VBoxGrapicsSetSupported(BOOL fSupported)
    19201320{
    19211321    VBoxConsoleCapSetSupported(VBOXCAPS_ENTRY_IDX_GRAPHICS, fSupported);
    19221322}
     1323
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTrayInternal.h

    r95965 r95966  
    2121# pragma once
    2222#endif
     23
     24
     25/* caps API */
     26#define VBOXCAPS_ENTRY_IDX_SEAMLESS  0
     27#define VBOXCAPS_ENTRY_IDX_GRAPHICS  1
     28#define VBOXCAPS_ENTRY_IDX_COUNT     2
     29
     30typedef enum VBOXCAPS_ENTRY_FUNCSTATE
     31{
     32    /* the cap is unsupported */
     33    VBOXCAPS_ENTRY_FUNCSTATE_UNSUPPORTED = 0,
     34    /* the cap is supported */
     35    VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED,
     36    /* the cap functionality is started, it can be disabled however if its AcState is not ACQUIRED */
     37    VBOXCAPS_ENTRY_FUNCSTATE_STARTED,
     38} VBOXCAPS_ENTRY_FUNCSTATE;
     39
     40
     41int VBoxAcquireGuestCaps(uint32_t fOr, uint32_t fNot, bool fCfg);
     42void VBoxCapsEntryFuncStateSet(uint32_t iCup, VBOXCAPS_ENTRY_FUNCSTATE enmFuncState);
     43int VBoxCapsInit();
     44int VBoxCapsReleaseAll();
     45void VBoxCapsTerm();
     46BOOL VBoxCapsEntryIsAcquired(uint32_t iCap);
     47BOOL VBoxCapsEntryIsEnabled(uint32_t iCap);
     48BOOL VBoxCapsCheckTimer(WPARAM wParam);
     49int VBoxCapsEntryRelease(uint32_t iCap);
     50int VBoxCapsEntryAcquire(uint32_t iCap);
     51int VBoxCapsAcquireAllSupported();
     52
     53
     54/* console-related caps API */
     55BOOL VBoxConsoleIsAllowed();
     56void VBoxConsoleEnable(BOOL fEnable);
     57void VBoxConsoleCapSetSupported(uint32_t iCap, BOOL fSupported);
     58
     59
     60/*
     61 * Dt (desktop [state] tracking) functionality API
     62 *
     63 * !!!NOTE: this API is NOT thread-safe!!!
     64 * */
     65int vboxDtInit();
     66void vboxDtTerm();
     67/* @returns true on "IsInputDesktop" state change */
     68BOOL vboxDtHandleEvent();
     69/* @returns true iff the application (VBoxTray) desktop is input */
     70BOOL vboxDtIsInputDesktop();
     71HANDLE vboxDtGetNotifyEvent();
     72BOOL vboxDtCheckTimer(WPARAM wParam);
     73void VBoxTrayCheckDt();
     74
     75
    2376/*
    2477 * St (session [state] tracking) functionality API
     
    3487BOOL vboxStCheckTimer(WPARAM wEvent);
    3588
     89
    3690DWORD VBoxDisplayGetCount();
    3791DWORD VBoxDisplayGetConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes);
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