summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp')
-rw-r--r--src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp205
1 files changed, 130 insertions, 75 deletions
diff --git a/src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp b/src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp
index 553aae32..291a9d7c 100644
--- a/src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp
+++ b/src/VBox/Additions/WINNT/VBoxHook/VBoxHook.cpp
@@ -1,8 +1,10 @@
+/* $Id: VBoxHook.cpp $ */
/** @file
- *
* VBoxHook -- Global windows hook dll
- *
- * Copyright (C) 2006-2007 Oracle Corporation
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -12,29 +14,32 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
+
#include <Windows.h>
#include <VBoxHook.h>
#include <VBox/VBoxGuestLib.h>
#include <stdio.h>
#pragma data_seg("SHARED")
-static HWINEVENTHOOK hEventHook[2] = {0};
+static HWINEVENTHOOK hWinEventHook[2] = {0};
+static HWINEVENTHOOK hDesktopEventHook = NULL;
#pragma data_seg()
#pragma comment(linker, "/section:SHARED,RWS")
-static HANDLE hNotifyEvent = 0;
+static HANDLE hWinNotifyEvent = 0;
+static HANDLE hDesktopNotifyEvent = 0;
#ifdef DEBUG
-void WriteLog(char *String, ...);
-#define dprintf(a) do { WriteLog a; } while (0)
+static void WriteLog(const char *pszFormat, ...);
+# define dprintf(a) do { WriteLog a; } while (0)
#else
-#define dprintf(a) do {} while (0)
-#endif /* DEBUG */
+# define dprintf(a) do {} while (0)
+#endif /* !DEBUG */
-void CALLBACK VBoxHandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
- LONG idObject, LONG idChild,
- DWORD dwEventThread, DWORD dwmsEventTime)
+static void CALLBACK VBoxHandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
+ LONG idObject, LONG idChild,
+ DWORD dwEventThread, DWORD dwmsEventTime)
{
DWORD dwStyle;
if ( idObject != OBJID_WINDOW
@@ -75,97 +80,147 @@ void CALLBACK VBoxHandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
break;
}
#endif
- if (!hNotifyEvent)
+ if (!hWinNotifyEvent)
{
- hNotifyEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, VBOXHOOK_GLOBAL_EVENT_NAME);
- dprintf(("OpenEvent returned %x (last err=%x)\n", hNotifyEvent, GetLastError()));
+ hWinNotifyEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, VBOXHOOK_GLOBAL_WT_EVENT_NAME);
+ dprintf(("OpenEvent returned %x (last err=%x)\n", hWinNotifyEvent, GetLastError()));
}
- BOOL ret = SetEvent(hNotifyEvent);
- dprintf(("SetEvent %x returned %d (last error %x)\n", hNotifyEvent, ret, GetLastError()));
+ BOOL ret = SetEvent(hWinNotifyEvent);
+ dprintf(("SetEvent %x returned %d (last error %x)\n", hWinNotifyEvent, ret, GetLastError()));
break;
}
}
+static void CALLBACK VBoxHandleDesktopEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
+ LONG idObject, LONG idChild,
+ DWORD dwEventThread, DWORD dwmsEventTime)
+{
+ if (!hDesktopNotifyEvent)
+ {
+ hDesktopNotifyEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, VBOXHOOK_GLOBAL_DT_EVENT_NAME);
+ dprintf(("OpenEvent returned %x (last err=%x)\n", hDesktopNotifyEvent, GetLastError()));
+ }
+ BOOL ret = SetEvent(hDesktopNotifyEvent);
+ dprintf(("SetEvent %x returned %d (last error %x)\n", hDesktopNotifyEvent, ret, GetLastError()));
+}
-/* Install the global message hook */
-BOOL VBoxInstallHook(HMODULE hDll)
+BOOL VBoxHookInstallActiveDesktopTracker(HMODULE hDll)
{
- if (hEventHook[0] || hEventHook[1])
+ if (hDesktopEventHook)
return TRUE;
CoInitialize(NULL);
- hEventHook[0] = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE,
- hDll,
- VBoxHandleWinEvent,
- 0, 0,
- WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);
-
- hEventHook[1] = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_HIDE,
- hDll,
- VBoxHandleWinEvent,
- 0, 0,
- WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);
- return !!hEventHook[0];
+ hDesktopEventHook = SetWinEventHook(EVENT_SYSTEM_DESKTOPSWITCH, EVENT_SYSTEM_DESKTOPSWITCH,
+ hDll,
+ VBoxHandleDesktopEvent,
+ 0, 0,
+ 0);
+
+ return !!hDesktopEventHook;
+
}
-/* Remove the global message hook */
-BOOL VBoxRemoveHook()
+BOOL VBoxHookRemoveActiveDesktopTracker()
{
- if (hEventHook[0] && hEventHook[1])
+ if (hDesktopEventHook)
{
- UnhookWinEvent(hEventHook[0]);
- UnhookWinEvent(hEventHook[1]);
+ UnhookWinEvent(hDesktopEventHook);
CoUninitialize();
}
- hEventHook[0] = hEventHook[1] = 0;
- return true;
+ hDesktopEventHook = 0;
+ return TRUE;
}
+/** Install the global message hook */
+BOOL VBoxHookInstallWindowTracker(HMODULE hDll)
+{
+ if (hWinEventHook[0] || hWinEventHook[1])
+ return TRUE;
-#ifdef DEBUG
-#include <VBox/VBoxGuest.h>
-#include <VBox/VMMDev.h>
-
-static char LogBuffer[1024];
-static HANDLE gVBoxDriver = INVALID_HANDLE_VALUE;
+ CoInitialize(NULL);
+ hWinEventHook[0] = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE,
+ hDll,
+ VBoxHandleWinEvent,
+ 0, 0,
+ WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);
+
+ hWinEventHook[1] = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_HIDE,
+ hDll,
+ VBoxHandleWinEvent,
+ 0, 0,
+ WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);
+ return !!hWinEventHook[0];
+}
-VBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq)
+/** Remove the global message hook */
+BOOL VBoxHookRemoveWindowTracker()
{
- DWORD cbReturned;
- DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_VMMREQUEST(pReq->size), pReq, pReq->size,
- pReq, pReq->size, &cbReturned, NULL);
- return VINF_SUCCESS;
+ if (hWinEventHook[0] && hWinEventHook[1])
+ {
+ UnhookWinEvent(hWinEventHook[0]);
+ UnhookWinEvent(hWinEventHook[1]);
+ CoUninitialize();
+ }
+ hWinEventHook[0] = hWinEventHook[1] = 0;
+ return TRUE;
}
-void WriteLog(char *pszStr, ...)
+
+#ifdef DEBUG
+# include <VBox/VBoxGuest.h>
+# include <VBox/VMMDev.h>
+
+/**
+ * dprintf worker using VBoxGuest.sys and VMMDevReq_LogString.
+ */
+static void WriteLog(const char *pszFormat, ...)
{
- VMMDevReqLogString *pReq = (VMMDevReqLogString *)LogBuffer;
- int rc;
-
- /* open VBox guest driver */
- if (gVBoxDriver == INVALID_HANDLE_VALUE)
- gVBoxDriver = CreateFile(VBOXGUEST_DEVICE_NAME,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
- NULL);
-
- if (gVBoxDriver == INVALID_HANDLE_VALUE)
- return;
+ /*
+ * Open VBox guest driver once.
+ */
+ static HANDLE s_hVBoxGuest = INVALID_HANDLE_VALUE;
+ HANDLE hVBoxGuest = s_hVBoxGuest;
+ if (hVBoxGuest == INVALID_HANDLE_VALUE)
+ {
+ hVBoxGuest = CreateFile(VBOXGUEST_DEVICE_NAME,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+ NULL);
+ if (hVBoxGuest == INVALID_HANDLE_VALUE)
+ return;
+ s_hVBoxGuest = hVBoxGuest;
+ }
- va_list va;
+ /*
+ * We're apparently afraid of using stack here, so we use a static buffer
+ * instead and pray we won't be here at the same time on two threads...
+ */
+ static union
+ {
+ VMMDevReqLogString Req;
+ uint8_t abBuf[1024];
+ } s_uBuf;
- va_start(va, pszStr);
+ vmmdevInitRequest(&s_uBuf.Req.header, VMMDevReq_LogString);
+
+ va_list va;
+ va_start(va, pszFormat);
+ size_t cch = vsprintf(s_uBuf.Req.szString, pszFormat, va);
+ va_end(va);
- vmmdevInitRequest(&pReq->header, VMMDevReq_LogString);
- vsprintf(pReq->szString, pszStr, va);
- pReq->header.size += strlen(pReq->szString);
- rc = VbglR3GRPerform(&pReq->header);
+ s_uBuf.Req.header.size += (uint32_t)cch;
+ if (s_uBuf.Req.header.size > sizeof(s_uBuf))
+ __debugbreak();
- va_end (va);
- return;
+ DWORD cbReturned;
+ DeviceIoControl(hVBoxGuest, VBOXGUEST_IOCTL_VMMREQUEST(s_uBuf.Req.size),
+ &s_uBuf.Req, s_uBuf.Req.header.size,
+ &s_uBuf.Req, s_uBuf.Req.header.size,
+ &cbReturned, NULL);
}
-#endif
+#endif /* DEBUG */
+