VirtualBox

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

Last change on this file since 47935 was 46182, checked in by vboxsync, 12 years ago

VBoxHook.cpp: Fixed warning in WriteLog. Some other cleanups in this and related code.

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

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