VBoxHook.cpp revision e3cc59c2dca7d5a7f54ee27b9fbb68fe42d158ed
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VBoxHook -- Global windows hook dll
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (C) 2006-2007 innotek GmbH
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * General Public License as published by the Free Software Foundation,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * If you received this file as part of a commercial VirtualBox
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * distribution, then only the terms of your commercial VirtualBox
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * license agreement apply instead of the previous paragraph.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define _WIN32_WINNT 0x0500
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <windows.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBoxHook.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBoxDisplay.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <stdio.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#pragma data_seg("SHARED")
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic HWINEVENTHOOK hEventHook[2] = {0};
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#pragma data_seg()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#pragma comment(linker, "/section:SHARED,RWS")
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsyncstatic void VBoxRecheckVisibleWindows();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid WriteLog(char *String, ...);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define dprintf(a) do { WriteLog a; } while (0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#define dprintf(a) do {} while (0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* DEBUG */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync HDC hdc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRGN hrgn;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RECT rect;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync} VBOX_ENUM_PARAM, *PVBOX_ENUM_PARAM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsyncvoid CALLBACK VBoxHandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LONG idObject, LONG idChild,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DWORD dwEventThread, DWORD dwmsEventTime)
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync{
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync DWORD dwStyle;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( idObject != OBJID_WINDOW
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || !hwnd)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return;
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dwStyle = GetWindowLong(hwnd, GWL_STYLE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (dwStyle & WS_CHILD)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch(event)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case EVENT_OBJECT_LOCATIONCHANGE:
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync if (!(dwStyle & WS_VISIBLE))
2daaccf68be3773aee600c5c3e48bcf5401418a6vboxsync return;
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync case EVENT_OBJECT_CREATE:
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync case EVENT_OBJECT_DESTROY:
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync case EVENT_OBJECT_HIDE:
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync case EVENT_OBJECT_SHOW:
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync#ifdef DEBUG
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync switch(event)
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync {
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync case EVENT_OBJECT_LOCATIONCHANGE:
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync dprintf(("VBoxHandleWinEvent EVENT_OBJECT_LOCATIONCHANGE for window %x\n", hwnd));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case EVENT_OBJECT_CREATE:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("VBoxHandleWinEvent EVENT_OBJECT_CREATE for window %x\n", hwnd));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case EVENT_OBJECT_HIDE:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("VBoxHandleWinEvent EVENT_OBJECT_HIDE for window %x\n", hwnd));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case EVENT_OBJECT_SHOW:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("VBoxHandleWinEvent EVENT_OBJECT_SHOW for window %x\n", hwnd));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case EVENT_OBJECT_DESTROY:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("VBoxHandleWinEvent EVENT_OBJECT_DESTROY for window %x\n", hwnd));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxRecheckVisibleWindows();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncBOOL CALLBACK VBoxEnumFunc(HWND hwnd, LPARAM lParam)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync{
22e281e75ed636601178296c6daebda8f1d17c59vboxsync PVBOX_ENUM_PARAM lpParam = (PVBOX_ENUM_PARAM)lParam;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync DWORD dwStyle, dwExStyle;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync RECT rect, rectVisible;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync dwStyle = GetWindowLong(hwnd, GWL_STYLE);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync dwExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync if ( !(dwStyle & WS_VISIBLE)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync || (dwStyle & WS_CHILD))
22e281e75ed636601178296c6daebda8f1d17c59vboxsync return TRUE;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync dprintf(("VBoxEnumFunc %x\n", hwnd));
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /* Only visible windows that are present on the desktop are interesting here */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync if ( GetWindowRect(hwnd, &rect)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync && IntersectRect(&rectVisible, &lpParam->rect, &rect))
22e281e75ed636601178296c6daebda8f1d17c59vboxsync {
22e281e75ed636601178296c6daebda8f1d17c59vboxsync char szWindowText[256];
22e281e75ed636601178296c6daebda8f1d17c59vboxsync szWindowText[0] = 0;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync GetWindowText(hwnd, szWindowText, sizeof(szWindowText));
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /* Filter out Windows XP shadow windows */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /** @todo still shows inside the guest */
7b80828e5760a8814fe6cd494d2715a4544fbddcvboxsync if ( szWindowText[0] == 0
22e281e75ed636601178296c6daebda8f1d17c59vboxsync && dwStyle == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync && dwExStyle == (WS_EX_LAYERED|WS_EX_TOOLWINDOW|WS_EX_TRANSPARENT|WS_EX_TOPMOST))
22e281e75ed636601178296c6daebda8f1d17c59vboxsync {
22e281e75ed636601178296c6daebda8f1d17c59vboxsync dprintf(("Filter out shadow window style=%x exstyle=%x\n", dwStyle, dwExStyle));
22e281e75ed636601178296c6daebda8f1d17c59vboxsync return TRUE;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync }
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /** @todo will this suffice? The Program Manager window covers the whole screen */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync if (strcmp(szWindowText, "Program Manager"))
22e281e75ed636601178296c6daebda8f1d17c59vboxsync {
22e281e75ed636601178296c6daebda8f1d17c59vboxsync dprintf(("Enum hwnd=%x rect (%d,%d) (%d,%d)\n", hwnd, rect.left, rect.top, rect.right, rect.bottom));
22e281e75ed636601178296c6daebda8f1d17c59vboxsync dprintf(("title=%s style=%x\n", szWindowText, dwStyle));
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync HRGN hrgn = CreateRectRgn(0,0,0,0);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync int ret = GetWindowRgn(hwnd, hrgn);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
d1cbbd799d8912978f5146960b6780f387bb414bvboxsync if (ret == ERROR)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync {
22e281e75ed636601178296c6daebda8f1d17c59vboxsync dprintf(("GetWindowRgn failed with rc=%d\n", GetLastError()));
c17f5c90f2cb60b38ecabebce128724c6ff2d036vboxsync SetRectRgn(hrgn, rectVisible.left, rectVisible.top, rectVisible.right, rectVisible.bottom);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* this region is relative to the window origin instead of the desktop origin */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync OffsetRgn(hrgn, rectVisible.left, rectVisible.top);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (lpParam->hrgn)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* create a union of the current visible region and the visible rectangle of this window. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CombineRgn(lpParam->hrgn, lpParam->hrgn, hrgn, RGN_OR);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DeleteObject(hrgn);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync lpParam->hrgn = hrgn;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("Enum hwnd=%x rect (%d,%d) (%d,%d) (ignored)\n", hwnd, rect.left, rect.top, rect.right, rect.bottom));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("title=%s style=%x\n", szWindowText, dwStyle));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return TRUE; /* continue enumeration */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid VBoxRecheckVisibleWindows()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBOX_ENUM_PARAM param;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync param.hdc = GetDC(HWND_DESKTOP);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync param.hrgn = 0;
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync GetWindowRect(GetDesktopWindow(), &param.rect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("VBoxRecheckVisibleWindows desktop=%x rect (%d,%d) (%d,%d)\n", GetDesktopWindow(), param.rect.left, param.rect.top, param.rect.right, param.rect.bottom));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync EnumWindows(VBoxEnumFunc, (LPARAM)&param);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (param.hrgn)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DWORD cbSize;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbSize = GetRegionData(param.hrgn, 0, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (cbSize)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LPRGNDATA lpRgnData = (LPRGNDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (lpRgnData)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbSize = GetRegionData(param.hrgn, cbSize, lpRgnData);
3ecf9412133496b2aeb090cfd33a286404ec59fbvboxsync if (cbSize)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RECT *lpRect = (RECT *)&lpRgnData->Buffer[0];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("New visible region: \n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (DWORD i=0;i<lpRgnData->rdh.nCount;i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync dprintf(("visible rect (%d,%d)(%d,%d)\n", lpRect[i].left, lpRect[i].top, lpRect[i].right, lpRect[i].bottom));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
750d4d0506a38b2e80c997075d40aad474e675fbvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* send to display driver */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ExtEscape(param.hdc, VBOXESC_SETVISIBLEREGION, cbSize, (LPCSTR)lpRgnData, 0, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HeapFree(GetProcessHeap(), 0, lpRgnData);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DeleteObject(param.hrgn);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ReleaseDC(HWND_DESKTOP, param.hdc);
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync}
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync/* Install the global message hook */
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsyncBOOL VBoxInstallHook(HMODULE hDll)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync{
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync if (hEventHook[0] || hEventHook[1])
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync return TRUE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync /* Check current visible region state */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxRecheckVisibleWindows();
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync CoInitialize(NULL);
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync hEventHook[0] = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync hDll,
72ef2b9fc5ffc01d0dabd5052d6e8baa3a952773vboxsync VBoxHandleWinEvent,
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync 0, 0,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync hEventHook[1] = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_HIDE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync hDll,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxHandleWinEvent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync 0, 0,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return !!hEventHook[0];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* Remove the global message hook */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncBOOL VBoxRemoveHook()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (hEventHook[0] && hEventHook[1])
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync UnhookWinEvent(hEventHook[0]);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UnhookWinEvent(hEventHook[1]);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CoUninitialize();
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync hEventHook[0] = hEventHook[1] = 0;
909f4391cc20b4a3a9a2d3f8718084b669663ab2vboxsync return true;
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync}
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync#ifdef DEBUG
3ecd8008b81f02a04220705ae0033142af363280vboxsync#include <VBox/VBoxGuest.h>
3ecd8008b81f02a04220705ae0033142af363280vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic char LogBuffer[1024];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic HANDLE gVBoxDriver = INVALID_HANDLE_VALUE;
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVBGLR3DECL(int) VbglR3GRPerform(VMMDevRequestHeader *pReq)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DWORD cbReturned;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_VMMREQUEST, pReq, pReq->size,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pReq, pReq->size, &cbReturned, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync}
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid WriteLog(char *pszStr, ...)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
3ecd8008b81f02a04220705ae0033142af363280vboxsync VMMDevReqLogString *pReq = (VMMDevReqLogString *)LogBuffer;
3ecd8008b81f02a04220705ae0033142af363280vboxsync int rc;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* open VBox guest driver */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (gVBoxDriver == INVALID_HANDLE_VALUE)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync gVBoxDriver = CreateFile(VBOXGUEST_DEVICE_NAME,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync GENERIC_READ | GENERIC_WRITE,
22e281e75ed636601178296c6daebda8f1d17c59vboxsync FILE_SHARE_READ | FILE_SHARE_WRITE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NULL,
247b55faa8d054157f2481e68caca36f4dc9542cvboxsync OPEN_EXISTING,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync if (gVBoxDriver == INVALID_HANDLE_VALUE)
57399ab65e2825c324fb9dcb4642d4ae2c232509vboxsync return;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync va_list va;
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync va_start(va, pszStr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync vmmdevInitRequest(&pReq->header, VMMDevReq_LogString);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vsprintf(pReq->szString, pszStr, va);
6ae4b1c72625a8e5c369effea7f018b578d733c4vboxsync pReq->header.size += strlen(pReq->szString);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VbglR3GRPerform(&pReq->header);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync va_end (va);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync#endif
22e281e75ed636601178296c6daebda8f1d17c59vboxsync