VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDesktopTracking.cpp@ 95966

最後變更 在這個檔案從95966是 95966,由 vboxsync 提交於 3 年 前

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.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.4 KB
 
1/* $Id: VBoxDesktopTracking.cpp 95966 2022-08-01 15:40:29Z vboxsync $ */
2/** @file
3 * VBoxDesktopTracking.cpp - Desktop tracking.
4 */
5
6/*
7 * Copyright (C) 2013-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19#include <iprt/errcore.h>
20#include <iprt/ldr.h>
21#include <iprt/log.h>
22#include <iprt/string.h>
23#include <iprt/system.h>
24#include <iprt/win/windows.h>
25
26#include <VBoxHook.h>
27
28#include "VBoxTray.h"
29#include "VBoxTrayInternal.h"
30
31/* Default desktop state tracking */
32#include <Wtsapi32.h>
33
34
35/** @todo r=andy Lacks documentation / Doxygen headers. What does this, and why? */
36
37/*
38 * Dt (desktop [state] tracking) functionality API impl
39 *
40 * !!!NOTE: this API is NOT thread-safe!!!
41 * */
42
43typedef struct VBOXDT
44{
45 HANDLE hNotifyEvent;
46 BOOL fIsInputDesktop;
47 UINT_PTR idTimer;
48 RTLDRMOD hLdrModHook;
49 BOOL (* pfnVBoxHookInstallActiveDesktopTracker)(HMODULE hDll);
50 BOOL (* pfnVBoxHookRemoveActiveDesktopTracker)();
51 HDESK (WINAPI * pfnGetThreadDesktop)(DWORD dwThreadId);
52 HDESK (WINAPI * pfnOpenInputDesktop)(DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess);
53 BOOL (WINAPI * pfnCloseDesktop)(HDESK hDesktop);
54} VBOXDT;
55
56static VBOXDT gVBoxDt;
57
58BOOL vboxDtCalculateIsInputDesktop()
59{
60 BOOL fIsInputDt = FALSE;
61 HDESK hInput = gVBoxDt.pfnOpenInputDesktop(0, FALSE, DESKTOP_CREATEWINDOW);
62 if (hInput)
63 {
64// DWORD dwThreadId = GetCurrentThreadId();
65// HDESK hThreadDt = gVBoxDt.pfnGetThreadDesktop(dwThreadId);
66// if (hThreadDt)
67// {
68 fIsInputDt = TRUE;
69// }
70// else
71// {
72// DWORD dwErr = GetLastError();
73// LogFlowFunc(("pfnGetThreadDesktop for Seamless failed, last error = %08X\n", dwErr));
74// }
75
76 gVBoxDt.pfnCloseDesktop(hInput);
77 }
78 else
79 {
80// DWORD dwErr = GetLastError();
81// LogFlowFunc(("pfnOpenInputDesktop for Seamless failed, last error = %08X\n", dwErr));
82 }
83 return fIsInputDt;
84}
85
86void VBoxTrayCheckDt()
87{
88 BOOL fOldAllowedState = VBoxConsoleIsAllowed();
89 if (vboxDtHandleEvent())
90 {
91 if (!VBoxConsoleIsAllowed() != !fOldAllowedState)
92 VBoxConsoleEnable(!fOldAllowedState);
93 }
94}
95
96BOOL vboxDtCheckTimer(WPARAM wParam)
97{
98 if (wParam != gVBoxDt.idTimer)
99 return FALSE;
100
101 VBoxTrayCheckDt();
102
103 return TRUE;
104}
105
106int vboxDtInit()
107{
108 RT_ZERO(gVBoxDt);
109
110 int rc;
111 gVBoxDt.hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, VBOXHOOK_GLOBAL_DT_EVENT_NAME);
112 if (gVBoxDt.hNotifyEvent != NULL)
113 {
114 /* Load the hook dll and resolve the necessary entry points. */
115 rc = RTLdrLoadAppPriv(VBOXHOOK_DLL_NAME, &gVBoxDt.hLdrModHook);
116 if (RT_SUCCESS(rc))
117 {
118 rc = RTLdrGetSymbol(gVBoxDt.hLdrModHook, "VBoxHookInstallActiveDesktopTracker",
119 (void **)&gVBoxDt.pfnVBoxHookInstallActiveDesktopTracker);
120 if (RT_SUCCESS(rc))
121 {
122 rc = RTLdrGetSymbol(gVBoxDt.hLdrModHook, "VBoxHookRemoveActiveDesktopTracker",
123 (void **)&gVBoxDt.pfnVBoxHookRemoveActiveDesktopTracker);
124 if (RT_FAILURE(rc))
125 LogFlowFunc(("VBoxHookRemoveActiveDesktopTracker not found\n"));
126 }
127 else
128 LogFlowFunc(("VBoxHookInstallActiveDesktopTracker not found\n"));
129 if (RT_SUCCESS(rc))
130 {
131 /* Try get the system APIs we need. */
132 *(void **)&gVBoxDt.pfnGetThreadDesktop = RTLdrGetSystemSymbol("user32.dll", "GetThreadDesktop");
133 if (!gVBoxDt.pfnGetThreadDesktop)
134 {
135 LogFlowFunc(("GetThreadDesktop not found\n"));
136 rc = VERR_NOT_SUPPORTED;
137 }
138
139 *(void **)&gVBoxDt.pfnOpenInputDesktop = RTLdrGetSystemSymbol("user32.dll", "OpenInputDesktop");
140 if (!gVBoxDt.pfnOpenInputDesktop)
141 {
142 LogFlowFunc(("OpenInputDesktop not found\n"));
143 rc = VERR_NOT_SUPPORTED;
144 }
145
146 *(void **)&gVBoxDt.pfnCloseDesktop = RTLdrGetSystemSymbol("user32.dll", "CloseDesktop");
147 if (!gVBoxDt.pfnCloseDesktop)
148 {
149 LogFlowFunc(("CloseDesktop not found\n"));
150 rc = VERR_NOT_SUPPORTED;
151 }
152
153 if (RT_SUCCESS(rc))
154 {
155 BOOL fRc = FALSE;
156 /* For Vista and up we need to change the integrity of the security descriptor, too. */
157 uint64_t const uNtVersion = RTSystemGetNtVersion();
158 if (uNtVersion >= RTSYSTEM_MAKE_NT_VERSION(6, 0, 0))
159 {
160 HMODULE hModHook = (HMODULE)RTLdrGetNativeHandle(gVBoxDt.hLdrModHook);
161 Assert((uintptr_t)hModHook != ~(uintptr_t)0);
162 fRc = gVBoxDt.pfnVBoxHookInstallActiveDesktopTracker(hModHook);
163 if (!fRc)
164 LogFlowFunc(("pfnVBoxHookInstallActiveDesktopTracker failed, last error = %08X\n", GetLastError()));
165 }
166
167 if (!fRc)
168 {
169 gVBoxDt.idTimer = SetTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_DT_TIMER, 500, (TIMERPROC)NULL);
170 if (!gVBoxDt.idTimer)
171 {
172 DWORD dwErr = GetLastError();
173 LogFlowFunc(("SetTimer error %08X\n", dwErr));
174 rc = RTErrConvertFromWin32(dwErr);
175 }
176 }
177
178 if (RT_SUCCESS(rc))
179 {
180 gVBoxDt.fIsInputDesktop = vboxDtCalculateIsInputDesktop();
181 return VINF_SUCCESS;
182 }
183 }
184 }
185
186 RTLdrClose(gVBoxDt.hLdrModHook);
187 }
188 else
189 {
190 DWORD dwErr = GetLastError();
191 LogFlowFunc(("CreateEvent for Seamless failed, last error = %08X\n", dwErr));
192 rc = RTErrConvertFromWin32(dwErr);
193 }
194
195 CloseHandle(gVBoxDt.hNotifyEvent);
196 }
197 else
198 {
199 DWORD dwErr = GetLastError();
200 LogFlowFunc(("CreateEvent for Seamless failed, last error = %08X\n", dwErr));
201 rc = RTErrConvertFromWin32(dwErr);
202 }
203
204
205 RT_ZERO(gVBoxDt);
206 gVBoxDt.fIsInputDesktop = TRUE;
207
208 return rc;
209}
210
211void vboxDtTerm()
212{
213 if (!gVBoxDt.hLdrModHook)
214 return;
215
216 gVBoxDt.pfnVBoxHookRemoveActiveDesktopTracker();
217
218 RTLdrClose(gVBoxDt.hLdrModHook);
219 CloseHandle(gVBoxDt.hNotifyEvent);
220
221 RT_ZERO(gVBoxDt);
222}
223
224/* @returns true on "IsInputDesktop" state change */
225BOOL vboxDtHandleEvent()
226{
227 BOOL fIsInputDesktop = gVBoxDt.fIsInputDesktop;
228 gVBoxDt.fIsInputDesktop = vboxDtCalculateIsInputDesktop();
229 return !fIsInputDesktop != !gVBoxDt.fIsInputDesktop;
230}
231
232HANDLE vboxDtGetNotifyEvent()
233{
234 return gVBoxDt.hNotifyEvent;
235}
236
237/* @returns true iff the application (VBoxTray) desktop is input */
238BOOL vboxDtIsInputDesktop()
239{
240 return gVBoxDt.fIsInputDesktop;
241}
242
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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