VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp@ 95890

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

Add/Nt/VBoxHook: Made it build in VBOX_WITH_NOCRT_STATIC mode. bugref:10261

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.6 KB
 
1/* $Id: VBoxHook.cpp 95871 2022-07-27 02:38:21Z vboxsync $ */
2/** @file
3 * VBoxHook -- Global windows hook dll
4 */
5
6/*
7 * Copyright (C) 2006-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/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <iprt/win/windows.h>
23
24#include <VBoxHook.h>
25#include <VBox/VBoxGuestLib.h>
26#ifdef DEBUG
27# include <VBox/VBoxGuest.h>
28# include <VBox/VMMDev.h>
29# include <iprt/string.h>
30#endif
31
32
33/*********************************************************************************************************************************
34* Global Variables *
35*********************************************************************************************************************************/
36#pragma data_seg("SHARED")
37static HWINEVENTHOOK g_ahWinEventHook[2] = { NULL, NULL };
38static HWINEVENTHOOK g_hDesktopEventHook = NULL;
39#pragma data_seg()
40#pragma comment(linker, "/section:SHARED,RWS")
41
42static HANDLE g_hWinNotifyEvent = NULL;
43static HANDLE g_hDesktopNotifyEvent = NULL;
44
45
46/*********************************************************************************************************************************
47* Internal Functions *
48*********************************************************************************************************************************/
49#ifdef DEBUG
50static void WriteLog(const char *pszFormat, ...);
51# define dprintf(a) do { WriteLog a; } while (0)
52#else
53# define dprintf(a) do {} while (0)
54#endif /* !DEBUG */
55
56
57static void CALLBACK VBoxHandleWinEvent(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd,
58 LONG idObject, LONG idChild,
59 DWORD dwEventThread, DWORD dwmsEventTime) RT_NOTHROW_DEF
60{
61 RT_NOREF(hWinEventHook, idChild, dwEventThread, dwmsEventTime);
62 DWORD dwStyle;
63 if ( idObject != OBJID_WINDOW
64 || !hwnd)
65 return;
66
67 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
68 if (dwStyle & WS_CHILD)
69 return;
70
71 switch(event)
72 {
73 case EVENT_OBJECT_LOCATIONCHANGE:
74 if (!(dwStyle & WS_VISIBLE))
75 return;
76
77 case EVENT_OBJECT_CREATE:
78 case EVENT_OBJECT_DESTROY:
79 case EVENT_OBJECT_HIDE:
80 case EVENT_OBJECT_SHOW:
81#ifdef DEBUG
82 switch(event)
83 {
84 case EVENT_OBJECT_LOCATIONCHANGE:
85 dprintf(("VBoxHandleWinEvent EVENT_OBJECT_LOCATIONCHANGE for window %x\n", hwnd));
86 break;
87 case EVENT_OBJECT_CREATE:
88 dprintf(("VBoxHandleWinEvent EVENT_OBJECT_CREATE for window %x\n", hwnd));
89 break;
90 case EVENT_OBJECT_HIDE:
91 dprintf(("VBoxHandleWinEvent EVENT_OBJECT_HIDE for window %x\n", hwnd));
92 break;
93 case EVENT_OBJECT_SHOW:
94 dprintf(("VBoxHandleWinEvent EVENT_OBJECT_SHOW for window %x\n", hwnd));
95 break;
96 case EVENT_OBJECT_DESTROY:
97 dprintf(("VBoxHandleWinEvent EVENT_OBJECT_DESTROY for window %x\n", hwnd));
98 break;
99 }
100#endif
101 if (!g_hWinNotifyEvent)
102 {
103 g_hWinNotifyEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, VBOXHOOK_GLOBAL_WT_EVENT_NAME);
104 dprintf(("OpenEvent returned %x (last err=%x)\n", g_hWinNotifyEvent, GetLastError()));
105 }
106 BOOL fRc = SetEvent(g_hWinNotifyEvent);
107 dprintf(("SetEvent %x returned %d (last error %x)\n", g_hWinNotifyEvent, fRc, GetLastError())); NOREF(fRc);
108 break;
109 }
110}
111
112static void CALLBACK VBoxHandleDesktopEvent(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd,
113 LONG idObject, LONG idChild,
114 DWORD dwEventThread, DWORD dwmsEventTime) RT_NOTHROW_DEF
115{
116 RT_NOREF(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime);
117 if (!g_hDesktopNotifyEvent)
118 {
119 g_hDesktopNotifyEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, VBOXHOOK_GLOBAL_DT_EVENT_NAME);
120 dprintf(("OpenEvent returned %x (last err=%x)\n", g_hDesktopNotifyEvent, GetLastError()));
121 }
122 BOOL fRc = SetEvent(g_hDesktopNotifyEvent);
123 dprintf(("SetEvent %x returned %d (last error %x)\n", g_hDesktopNotifyEvent, fRc, GetLastError())); NOREF(fRc);
124}
125
126BOOL VBoxHookInstallActiveDesktopTracker(HMODULE hDll)
127{
128 if (g_hDesktopEventHook)
129 return TRUE;
130
131 CoInitialize(NULL);
132 g_hDesktopEventHook = SetWinEventHook(EVENT_SYSTEM_DESKTOPSWITCH, EVENT_SYSTEM_DESKTOPSWITCH,
133 hDll,
134 VBoxHandleDesktopEvent,
135 0, 0,
136 0);
137
138 return !!g_hDesktopEventHook;
139
140}
141
142BOOL VBoxHookRemoveActiveDesktopTracker()
143{
144 if (g_hDesktopEventHook)
145 {
146 UnhookWinEvent(g_hDesktopEventHook);
147 CoUninitialize();
148 }
149 g_hDesktopEventHook = 0;
150 return TRUE;
151}
152
153/** Install the global message hook */
154BOOL VBoxHookInstallWindowTracker(HMODULE hDll)
155{
156 if (g_ahWinEventHook[0] || g_ahWinEventHook[1])
157 return TRUE;
158
159 CoInitialize(NULL);
160 g_ahWinEventHook[0] = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE,
161 hDll,
162 VBoxHandleWinEvent,
163 0, 0,
164 WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);
165
166 g_ahWinEventHook[1] = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_HIDE,
167 hDll,
168 VBoxHandleWinEvent,
169 0, 0,
170 WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);
171 return !!g_ahWinEventHook[0];
172}
173
174/** Remove the global message hook */
175BOOL VBoxHookRemoveWindowTracker()
176{
177 if (g_ahWinEventHook[0] && g_ahWinEventHook[1])
178 {
179 UnhookWinEvent(g_ahWinEventHook[0]);
180 UnhookWinEvent(g_ahWinEventHook[1]);
181 CoUninitialize();
182 }
183 g_ahWinEventHook[0] = g_ahWinEventHook[1] = 0;
184 return TRUE;
185}
186
187
188#ifdef DEBUG
189/**
190 * dprintf worker using VBoxGuest.sys and VMMDevReq_LogString.
191 */
192static void WriteLog(const char *pszFormat, ...)
193{
194 /*
195 * Open VBox guest driver once.
196 */
197 static HANDLE s_hVBoxGuest = INVALID_HANDLE_VALUE;
198 HANDLE hVBoxGuest = s_hVBoxGuest;
199 if (hVBoxGuest == INVALID_HANDLE_VALUE)
200 {
201 hVBoxGuest = CreateFile(VBOXGUEST_DEVICE_NAME,
202 GENERIC_READ | GENERIC_WRITE,
203 FILE_SHARE_READ | FILE_SHARE_WRITE,
204 NULL,
205 OPEN_EXISTING,
206 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
207 NULL);
208 if (hVBoxGuest == INVALID_HANDLE_VALUE)
209 return;
210 s_hVBoxGuest = hVBoxGuest;
211 }
212
213 /*
214 * We're apparently afraid of using stack here, so we use a static buffer
215 * instead and pray we won't be here at the same time on two threads...
216 */
217 static union
218 {
219 VMMDevReqLogString Req;
220 uint8_t abBuf[1024];
221 } s_uBuf;
222
223 vmmdevInitRequest(&s_uBuf.Req.header, VMMDevReq_LogString);
224
225 va_list va;
226 va_start(va, pszFormat);
227 size_t cch = RTStrPrintf(s_uBuf.Req.szString, sizeof(s_uBuf.Req.szString), pszFormat, va);
228 va_end(va);
229
230 s_uBuf.Req.header.size += (uint32_t)cch;
231 if (s_uBuf.Req.header.size > sizeof(s_uBuf))
232 __debugbreak();
233
234 DWORD cbReturned;
235 DeviceIoControl(hVBoxGuest, VBGL_IOCTL_VMMDEV_REQUEST(s_uBuf.Req.size),
236 &s_uBuf.Req, s_uBuf.Req.header.size,
237 &s_uBuf.Req, s_uBuf.Req.header.size,
238 &cbReturned, NULL);
239}
240#endif /* DEBUG */
241
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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