Changeset 95966 in vbox
- Timestamp:
- Aug 1, 2022 3:40:29 PM (2 years ago)
- 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 39 39 VBoxTray_SOURCES = \ 40 40 VBoxTray.cpp \ 41 VBoxCaps.cpp \ 42 VBoxConsole.cpp \ 43 VBoxDesktopTracking.cpp \ 41 44 VBoxDispIf.cpp \ 42 45 VBoxSeamless.cpp \ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.cpp
r95961 r95966 29 29 #include <iprt/win/windows.h> 30 30 31 #include <VBoxDisplay.h> /** @todo r=bird: Presumably the ../include/VBoxDisplay.h file rather than ./VBoxDisplay.h. WTF??? */32 31 #include <VBoxHook.h> /* from ../include/ */ 33 32 34 33 #include "VBoxTray.h" 34 #include "VBoxTrayInternal.h" 35 35 #include "VBoxHelpers.h" 36 36 #include "VBoxSeamless.h" 37 38 37 39 38 … … 70 69 *********************************************************************************************************************************/ 71 70 void VBoxLogString(HANDLE hDriver, char *pszStr); 72 71 static void vboxSeamlessSetSupported(BOOL fSupported); 73 72 74 73 … … 105 104 && pCtx->pfnVBoxHookRemoveWindowTracker) 106 105 { 107 VBoxSeamlessSetSupported(TRUE);106 vboxSeamlessSetSupported(TRUE); 108 107 109 108 *ppInstance = pCtx; … … 136 135 AssertPtr(pCtx); 137 136 138 VBoxSeamlessSetSupported(FALSE);137 vboxSeamlessSetSupported(FALSE); 139 138 140 139 /* Inform the host that we no longer support the seamless window mode. */ … … 206 205 207 206 VBoxDispIfSeamlessTerm(&gVBoxDispIfSeamless); 207 } 208 209 void vboxSeamlessSetSupported(BOOL fSupported) 210 { 211 VBoxConsoleCapSetSupported(VBOXCAPS_ENTRY_IDX_SEAMLESS, fSupported); 208 212 } 209 213 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.h
r93115 r95966 22 22 #endif 23 23 24 void VBoxSeamlessEnable( );25 void VBoxSeamlessDisable( );24 void VBoxSeamlessEnable(void); 25 void VBoxSeamlessDisable(void); 26 26 void VBoxSeamlessCheckWindows(bool fForce); 27 28 void VBoxSeamlessSetSupported(BOOL fSupported);29 27 30 28 #endif /* !GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxSeamless_h */ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
r95965 r95966 56 56 57 57 58 59 60 /*61 * Dt (desktop [state] tracking) functionality API62 *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 076 #define VBOXCAPS_ENTRY_IDX_GRAPHICS 177 #define VBOXCAPS_ENTRY_IDX_COUNT 278 79 typedef enum VBOXCAPS_ENTRY_FUNCSTATE80 {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 106 58 static void VBoxGrapicsSetSupported(BOOL fSupported); 107 59 … … 115 67 /* Global message handler prototypes. */ 116 68 static 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);120 69 121 70 … … 828 777 } 829 778 830 static void VBoxTrayCheckDt()831 {832 BOOL fOldAllowedState = VBoxConsoleIsAllowed();833 if (vboxDtHandleEvent())834 {835 if (!VBoxConsoleIsAllowed() != !fOldAllowedState)836 VBoxConsoleEnable(!fOldAllowedState);837 }838 }839 840 779 static int vboxTrayServiceMain(void) 841 780 { … … 1378 1317 } 1379 1318 1380 /*1381 * Dt (desktop [state] tracking) functionality API impl1382 *1383 * !!!NOTE: this API is NOT thread-safe!!!1384 * */1385 1386 typedef struct VBOXDT1387 {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 // else1414 // {1415 // DWORD dwErr = GetLastError();1416 // LogFlowFunc(("pfnGetThreadDesktop for Seamless failed, last error = %08X\n", dwErr));1417 // }1418 1419 gVBoxDt.pfnCloseDesktop(hInput);1420 }1421 else1422 {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 else1461 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 else1522 {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 else1531 {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 VBoxGuest1576 * otherwise Acquisition mechanism will treat us as different client and will not propagate necessary requests1577 * */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_ACSTATE1588 {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_ACQUIRED1595 } 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_ENTRY1604 {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 VBOXCAPS1614 {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 else1632 {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_ACQUIRED1759 && 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 else1784 {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 else1877 {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 else1894 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 else1907 {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 1919 1319 static void VBoxGrapicsSetSupported(BOOL fSupported) 1920 1320 { 1921 1321 VBoxConsoleCapSetSupported(VBOXCAPS_ENTRY_IDX_GRAPHICS, fSupported); 1922 1322 } 1323 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTrayInternal.h
r95965 r95966 21 21 # pragma once 22 22 #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 30 typedef 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 41 int VBoxAcquireGuestCaps(uint32_t fOr, uint32_t fNot, bool fCfg); 42 void VBoxCapsEntryFuncStateSet(uint32_t iCup, VBOXCAPS_ENTRY_FUNCSTATE enmFuncState); 43 int VBoxCapsInit(); 44 int VBoxCapsReleaseAll(); 45 void VBoxCapsTerm(); 46 BOOL VBoxCapsEntryIsAcquired(uint32_t iCap); 47 BOOL VBoxCapsEntryIsEnabled(uint32_t iCap); 48 BOOL VBoxCapsCheckTimer(WPARAM wParam); 49 int VBoxCapsEntryRelease(uint32_t iCap); 50 int VBoxCapsEntryAcquire(uint32_t iCap); 51 int VBoxCapsAcquireAllSupported(); 52 53 54 /* console-related caps API */ 55 BOOL VBoxConsoleIsAllowed(); 56 void VBoxConsoleEnable(BOOL fEnable); 57 void 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 * */ 65 int vboxDtInit(); 66 void vboxDtTerm(); 67 /* @returns true on "IsInputDesktop" state change */ 68 BOOL vboxDtHandleEvent(); 69 /* @returns true iff the application (VBoxTray) desktop is input */ 70 BOOL vboxDtIsInputDesktop(); 71 HANDLE vboxDtGetNotifyEvent(); 72 BOOL vboxDtCheckTimer(WPARAM wParam); 73 void VBoxTrayCheckDt(); 74 75 23 76 /* 24 77 * St (session [state] tracking) functionality API … … 34 87 BOOL vboxStCheckTimer(WPARAM wEvent); 35 88 89 36 90 DWORD VBoxDisplayGetCount(); 37 91 DWORD VBoxDisplayGetConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes);
Note:
See TracChangeset
for help on using the changeset viewer.