VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxService/VBoxSeamless.cpp@ 3803

Last change on this file since 3803 was 3803, checked in by vboxsync, 17 years ago

break from loop after success

File size: 9.1 KB
Line 
1/** @file
2 *
3 * VBoxSeamless - Seamless windows
4 *
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 *
22 */
23
24#include "VBoxService.h"
25#include <VBoxHook.h>
26#include <VBox/VBoxDev.h>
27#include <iprt/assert.h>
28#include "helpers.h"
29
30typedef struct _VBOXSEAMLESSCONTEXT
31{
32 const VBOXSERVICEENV *pEnv;
33
34 HMODULE hModule;
35
36 BOOL (* pfnVBoxInstallHook)(HMODULE hDll);
37 BOOL (* pfnVBoxRemoveHook)();
38
39} VBOXSEAMLESSCONTEXT;
40
41static VBOXSEAMLESSCONTEXT gCtx = {0};
42
43void VBoxLogString(HANDLE hDriver, char *pszStr);
44
45int VBoxSeamlessInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
46{
47 dprintf(("VBoxSeamlessInit\n"));
48
49 *pfStartThread = false;
50 gCtx.pEnv = pEnv;
51
52 /* Will fail if SetWinEventHook is not present (version < NT4 SP6 apparently) */
53 gCtx.hModule = LoadLibrary(VBOXHOOK_DLL_NAME);
54 if (gCtx.hModule)
55 {
56 *(uintptr_t *)&gCtx.pfnVBoxInstallHook = (uintptr_t)GetProcAddress(gCtx.hModule, "VBoxInstallHook");
57 *(uintptr_t *)&gCtx.pfnVBoxRemoveHook = (uintptr_t)GetProcAddress(gCtx.hModule, "VBoxRemoveHook");
58
59 /* inform the host that we support the seamless window mode */
60 VMMDevReqGuestCapabilities vmmreqGuestCaps = {0};
61 vmmdevInitRequest((VMMDevRequestHeader*)&vmmreqGuestCaps, VMMDevReq_ReportGuestCapabilities);
62 vmmreqGuestCaps.caps = VMMDEV_GUEST_SUPPORTS_SEAMLESS;
63
64 DWORD cbReturned;
65 if (!DeviceIoControl(pEnv->hDriver, IOCTL_VBOXGUEST_VMMREQUEST, &vmmreqGuestCaps, sizeof(vmmreqGuestCaps),
66 &vmmreqGuestCaps, sizeof(vmmreqGuestCaps), &cbReturned, NULL))
67 {
68 dprintf(("VMMDevReq_ReportGuestCapabilities: error doing IOCTL, last error: %d\n", GetLastError()));
69 return VERR_INVALID_PARAMETER;
70 }
71
72 *pfStartThread = true;
73 *ppInstance = &gCtx;
74 return VINF_SUCCESS;
75 }
76 else
77 {
78 dprintf(("VBoxSeamlessInit LoadLibrary failed with %d\n", GetLastError()));
79 return VERR_INVALID_PARAMETER;
80 }
81
82 return VINF_SUCCESS;
83}
84
85
86void VBoxSeamlessDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
87{
88 dprintf(("VBoxSeamlessDestroy\n"));
89 /* inform the host that we no longer support the seamless window mode */
90 VMMDevReqGuestCapabilities vmmreqGuestCaps = {0};
91 vmmdevInitRequest((VMMDevRequestHeader*)&vmmreqGuestCaps, VMMDevReq_ReportGuestCapabilities);
92 vmmreqGuestCaps.caps = 0;
93
94 DWORD cbReturned;
95 if (!DeviceIoControl(pEnv->hDriver, IOCTL_VBOXGUEST_VMMREQUEST, &vmmreqGuestCaps, sizeof(vmmreqGuestCaps),
96 &vmmreqGuestCaps, sizeof(vmmreqGuestCaps), &cbReturned, NULL))
97 {
98 dprintf(("VMMDevReq_ReportGuestCapabilities: error doing IOCTL, last error: %d\n", GetLastError()));
99 }
100
101 if (gCtx.pfnVBoxRemoveHook)
102 gCtx.pfnVBoxRemoveHook();
103 if (gCtx.hModule)
104 FreeLibrary(gCtx.hModule);
105 gCtx.hModule = 0;
106 return;
107}
108
109/**
110 * Thread function to wait for and process seamless mode change
111 * requests
112 */
113unsigned __stdcall VBoxSeamlessThread(void *pInstance)
114{
115 VBOXSEAMLESSCONTEXT *pCtx = (VBOXSEAMLESSCONTEXT *)pInstance;
116 HANDLE gVBoxDriver = pCtx->pEnv->hDriver;
117 bool fTerminate = false;
118 VBoxGuestFilterMaskInfo maskInfo;
119 DWORD cbReturned;
120
121 maskInfo.u32OrMask = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
122 maskInfo.u32NotMask = 0;
123 if (DeviceIoControl (gVBoxDriver, IOCTL_VBOXGUEST_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
124 {
125 dprintf(("VBoxSeamlessThread: DeviceIOControl(CtlMask - or) succeeded\n"));
126 }
127 else
128 {
129 dprintf(("VBoxSeamlessThread: DeviceIOControl(CtlMask) failed, SeamlessChangeThread exited\n"));
130 return 0;
131 }
132
133 do
134 {
135 /* wait for a seamless change event */
136 VBoxGuestWaitEventInfo waitEvent;
137 waitEvent.u32TimeoutIn = 1000;
138 waitEvent.u32EventMaskIn = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
139 if (DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL))
140 {
141 dprintf(("VBoxSeamlessThread: DeviceIOControl succeded\n"));
142
143 /* are we supposed to stop? */
144 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)
145 break;
146
147 dprintf(("VBoxSeamlessThread: checking event\n"));
148
149 /* did we get the right event? */
150 if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
151 {
152 dprintf(("VBoxService: going to get seamless change information.\n"));
153
154 /* We got at least one event. Read the requested resolution
155 * and try to set it until success. New events will not be seen
156 * but a new resolution will be read in this poll loop.
157 */
158 for (;;)
159 {
160 /* get the seamless change request */
161 VMMDevSeamlessChangeRequest seamlessChangeRequest = {0};
162 vmmdevInitRequest((VMMDevRequestHeader*)&seamlessChangeRequest, VMMDevReq_GetSeamlessChangeRequest);
163 seamlessChangeRequest.eventAck = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
164
165 BOOL fSeamlessChangeQueried = DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_VMMREQUEST, &seamlessChangeRequest, sizeof(seamlessChangeRequest),
166 &seamlessChangeRequest, sizeof(seamlessChangeRequest), &cbReturned, NULL);
167 if (fSeamlessChangeQueried)
168 {
169 dprintf(("VBoxSeamlessThread: mode change to %d\n", seamlessChangeRequest.mode));
170
171 switch(seamlessChangeRequest.mode)
172 {
173 case VMMDev_Seamless_Disabled:
174 if (pCtx->pfnVBoxRemoveHook)
175 pCtx->pfnVBoxRemoveHook();
176 break;
177
178 case VMMDev_Seamless_Visible_Region:
179 if (pCtx->pfnVBoxInstallHook)
180 pCtx->pfnVBoxInstallHook(pCtx->hModule);
181 break;
182
183 case VMMDev_Seamless_Host_Window:
184 break;
185
186 default:
187 AssertFailed();
188 break;
189 }
190
191 /* Retry the change a bit later. */
192 /* are we supposed to stop? */
193 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0)
194 {
195 fTerminate = true;
196 break;
197 }
198 break;
199 }
200 else
201 {
202 dprintf(("VBoxSeamlessThread: error from DeviceIoControl IOCTL_VBOXGUEST_VMMREQUEST\n"));
203 /* sleep a bit to not eat too much CPU while retrying */
204 /* are we supposed to stop? */
205 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 50) == WAIT_OBJECT_0)
206 {
207 fTerminate = true;
208 break;
209 }
210 }
211 }
212 }
213 }
214 else
215 {
216 dprintf(("VBoxService: error 0 from DeviceIoControl IOCTL_VBOXGUEST_WAITEVENT\n"));
217 /* sleep a bit to not eat too much CPU in case the above call always fails */
218 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
219 {
220 fTerminate = true;
221 break;
222 }
223 }
224 }
225 while (!fTerminate);
226
227 maskInfo.u32OrMask = 0;
228 maskInfo.u32NotMask = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
229 if (DeviceIoControl (gVBoxDriver, IOCTL_VBOXGUEST_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
230 {
231 dprintf(("VBoxSeamlessThread: DeviceIOControl(CtlMask - not) succeeded\n"));
232 }
233 else
234 {
235 dprintf(("VBoxSeamlessThread: DeviceIOControl(CtlMask) failed\n"));
236 }
237
238 dprintf(("VBoxSeamlessThread: finished seamless change request thread\n"));
239 return 0;
240}
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