- Timestamp:
- Jul 23, 2007 2:52:38 PM (17 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/VBoxService
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxService/VBoxSeamless.cpp
r3739 r3789 25 25 #include <VBoxHook.h> 26 26 #include <VBox/VBoxDev.h> 27 #include <iprt/assert.h> 27 28 #include "helpers.h" 28 29 29 static HMODULE hModule = 0; 30 31 BOOL (* pfnVBoxInstallHook)(HMODULE hDll) = NULL; 32 BOOL (* pfnVBoxRemoveHook)() = NULL; 33 30 typedef struct _VBOXSEAMLESSCONTEXT 31 { 32 const VBOXSERVICEENV *pEnv; 33 34 HMODULE hModule; 35 36 BOOL (* pfnVBoxInstallHook)(HMODULE hDll); 37 BOOL (* pfnVBoxRemoveHook)(); 38 39 } VBOXSEAMLESSCONTEXT; 40 41 static VBOXSEAMLESSCONTEXT gCtx = {0}; 34 42 35 43 void VBoxLogString(HANDLE hDriver, char *pszStr); … … 37 45 int VBoxSeamlessInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread) 38 46 { 47 dprintf(("VBoxSeamlessInit\n")); 48 39 49 *pfStartThread = false; 40 41 dprintf(("VBoxSeamlessInit\n")); 50 gCtx.pEnv = pEnv; 42 51 43 52 /* Will fail if SetWinEventHook is not present (version < NT4 SP6 apparently) */ 44 hModule = LoadLibrary(VBOXHOOK_DLL_NAME); 45 if (hModule) 46 { 47 *(uintptr_t *)&pfnVBoxInstallHook = (uintptr_t)GetProcAddress(hModule, "VBoxInstallHook"); 48 *(uintptr_t *)&pfnVBoxRemoveHook = (uintptr_t)GetProcAddress(hModule, "VBoxRemoveHook"); 49 } 50 else 51 dprintf(("VBoxSeamlessInit LoadLibrary failed with %d\n", GetLastError())); 52 53 if (pfnVBoxInstallHook) 54 { 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 55 59 /* inform the host that we support the seamless window mode */ 56 60 VMMDevReqGuestCapabilities vmmreqGuestCaps = {0}; … … 66 70 } 67 71 68 pfnVBoxInstallHook(hModule); 69 } 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 70 82 return VINF_SUCCESS; 71 83 } … … 86 98 dprintf(("VMMDevReq_ReportGuestCapabilities: error doing IOCTL, last error: %d\n", GetLastError())); 87 99 } 88 if (pfnVBoxRemoveHook) 89 pfnVBoxRemoveHook(); 90 91 FreeLibrary(hModule); 100 101 if (gCtx.pfnVBoxRemoveHook) 102 gCtx.pfnVBoxRemoveHook(); 103 if (gCtx.hModule) 104 FreeLibrary(gCtx.hModule); 105 gCtx.hModule = 0; 92 106 return; 93 107 } 108 109 /** 110 * Thread function to wait for and process seamless mode change 111 * requests 112 */ 113 unsigned __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(("VBoxService: DeviceIOControl(CtlMask - or) succeeded\n")); 126 } 127 else 128 { 129 dprintf(("VBoxService: 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(("VBoxService: 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(("VBoxService: 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->pfnVBoxInstallHook) 175 pCtx->pfnVBoxInstallHook(pCtx->hModule); 176 break; 177 178 case VMMDev_Seamless_Visible_Region: 179 if (pCtx->pfnVBoxRemoveHook) 180 pCtx->pfnVBoxRemoveHook(); 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 } 199 else 200 { 201 dprintf(("VBoxSeamlessThread: error from DeviceIoControl IOCTL_VBOXGUEST_VMMREQUEST\n")); 202 /* sleep a bit to not eat too much CPU while retrying */ 203 /* are we supposed to stop? */ 204 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 50) == WAIT_OBJECT_0) 205 { 206 fTerminate = true; 207 break; 208 } 209 } 210 } 211 } 212 } 213 else 214 { 215 dprintf(("VBoxService: error 0 from DeviceIoControl IOCTL_VBOXGUEST_WAITEVENT\n")); 216 /* sleep a bit to not eat too much CPU in case the above call always fails */ 217 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0) 218 { 219 fTerminate = true; 220 break; 221 } 222 } 223 } 224 while (!fTerminate); 225 226 maskInfo.u32OrMask = 0; 227 maskInfo.u32NotMask = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST; 228 if (DeviceIoControl (gVBoxDriver, IOCTL_VBOXGUEST_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL)) 229 { 230 dprintf(("VBoxSeamlessThread: DeviceIOControl(CtlMask - not) succeeded\n")); 231 } 232 else 233 { 234 dprintf(("VBoxSeamlessThread: DeviceIOControl(CtlMask) failed\n")); 235 } 236 237 dprintf(("VBoxSeamlessThread: finished seamless change request thread\n")); 238 return 0; 239 } -
trunk/src/VBox/Additions/WINNT/VBoxService/VBoxService.cpp
r3739 r3789 77 77 /* The seamless windows service prototypes */ 78 78 int VBoxSeamlessInit (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread); 79 unsigned __stdcall VBoxSeamlessThread (void *pInstance); 79 80 void VBoxSeamlessDestroy (const VBOXSERVICEENV *pEnv, void *pInstance); 80 81 … … 91 92 "Seamless Windows", 92 93 VBoxSeamlessInit, 93 NULL,94 VBoxSeamlessThread, 94 95 VBoxSeamlessDestroy 95 96 },
Note:
See TracChangeset
for help on using the changeset viewer.