儲存庫 vbox 的更動 68556
- 時間撮記:
- 2017-8-31 下午12:09:59 (7 年 以前)
- 位置:
- trunk/src/VBox/Additions/WINNT/Mouse/NT5
- 檔案:
-
- 修改 3 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMF.h
r62683 r68556 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Mouse filter header3 * VBox Mouse Filter Driver - Internal Header. 4 4 */ 5 5 … … 74 74 75 75 /* Internal functions */ 76 VOID VBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt); 77 VOID VBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt); 78 VOID VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt); 79 80 NTSTATUS VBoxNewProtInit(); 81 NTSTATUS VBoxNewProtTerm(); 76 void VBoxMouFltInitGlobals(void); 77 void VBoxMouFltDeleteGlobals(void); 78 void VBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt); 79 void VBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt); 80 void VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt); 82 81 83 82 VOID VBoxDrvNotifyServiceCB(PVBOXMOUSE_DEVEXT pDevExt, PMOUSE_INPUT_DATA InputDataStart, PMOUSE_INPUT_DATA InputDataEnd, PULONG InputDataConsumed); -
trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFDriver.cpp
r62522 r68556 30 30 NOREF(RegistryPath); 31 31 PAGED_CODE(); 32 LOGREL(("DriverEntry:")); 32 33 33 34 int irc = RTR0Init(0); … … 42 43 DriverObject->DriverExtension->AddDevice = VBoxDrvAddDevice; 43 44 44 for (int i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; ++i) 45 { 45 for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i) 46 46 DriverObject->MajorFunction[i] = VBoxIrpPassthrough; 47 }48 49 47 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxIrpInternalIOCTL; 50 DriverObject->MajorFunction[IRP_MJ_PNP] = VBoxIrpPnP; 51 DriverObject->MajorFunction[IRP_MJ_POWER] = VBoxIrpPower; 52 53 NTSTATUS tmpStatus = VBoxNewProtInit(); 54 if (!NT_SUCCESS(tmpStatus)) 55 { 56 WARN(("VBoxNewProtInit failed Status (0x%x)", tmpStatus)); 57 } 58 48 DriverObject->MajorFunction[IRP_MJ_PNP] = VBoxIrpPnP; 49 DriverObject->MajorFunction[IRP_MJ_POWER] = VBoxIrpPower; 50 51 VBoxMouFltInitGlobals(); 59 52 LOGF_LEAVE(); 60 53 return STATUS_SUCCESS; … … 67 60 LOGF_ENTER(); 68 61 69 NTSTATUS tmpStatus = VBoxNewProtTerm(); 70 if (!NT_SUCCESS(tmpStatus)) 71 { 72 WARN(("VBoxNewProtTerm failed Status (0x%x)", tmpStatus)); 73 } 74 75 62 VBoxMouFltDeleteGlobals(); 76 63 RTR0Term(); 77 64 } -
trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFInternal.cpp
r68550 r68556 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Mouse filter internal functions 3 * VBox Mouse Filter Driver - Internal functions. 4 * 5 * @todo r=bird: Would be better to merge this file into VBoxMFDriver.cpp... 4 6 */ 5 7 … … 16 18 */ 17 19 20 /********************************************************************************************************************************* 21 * Header Files * 22 *********************************************************************************************************************************/ 18 23 #undef WIN9X_COMPAT_SPINLOCK 19 24 #define WIN9X_COMPAT_SPINLOCK /* Avoid duplicate _KeInitializeSpinLock@4 error on x86. */ … … 23 28 #include <VBox/VBoxGuest.h> 24 29 #include <iprt/assert.h> 25 26 typedef struct VBOXGDC 27 { 28 PDEVICE_OBJECT pDo; 29 PFILE_OBJECT pFo; 30 } VBOXGDC, *PVBOXGDC; 31 30 #include <iprt/string.h> 31 32 33 /********************************************************************************************************************************* 34 * Structures and Typedefs * 35 *********************************************************************************************************************************/ 32 36 typedef struct _VBoxGlobalContext 33 37 { … … 37 41 volatile LONG fHostInformed; 38 42 volatile LONG fHostMouseFound; 39 VB OXGDC Gdc;43 VBGLIDCHANDLE IdcHandle; 40 44 KSPIN_LOCK SyncLock; 41 45 volatile PVBOXMOUSE_DEVEXT pCurrentDevExt; 42 46 LIST_ENTRY DevExtList; 43 BOOLEANfIsNewProtEnabled;47 bool fIsNewProtEnabled; 44 48 MOUSE_INPUT_DATA LastReportedData; 45 49 } VBoxGlobalContext; 46 50 51 52 /********************************************************************************************************************************* 53 * Global Variables * 54 *********************************************************************************************************************************/ 47 55 static VBoxGlobalContext g_ctx = {}; 48 56 49 /* Guest Device Communication API */ 50 NTSTATUS VBoxGdcInit() 51 { 52 UNICODE_STRING UniName; 53 RtlInitUnicodeString(&UniName, VBOXGUEST_DEVICE_NAME_NT); 54 NTSTATUS Status = IoGetDeviceObjectPointer(&UniName, FILE_ALL_ACCESS, &g_ctx.Gdc.pFo, &g_ctx.Gdc.pDo); 55 if (!NT_SUCCESS(Status)) 56 { 57 WARN(("IoGetDeviceObjectPointer failed Status(0x%x)", Status)); 58 memset(&g_ctx.Gdc, 0, sizeof (g_ctx.Gdc)); 59 } 60 return Status; 61 } 62 63 BOOLEAN VBoxGdcIsInitialized() 64 { 65 return !!g_ctx.Gdc.pDo; 66 } 67 68 NTSTATUS VBoxGdcTerm() 69 { 70 if (!g_ctx.Gdc.pFo) 71 return STATUS_SUCCESS; 72 /* this will dereference device object as well */ 73 ObDereferenceObject(g_ctx.Gdc.pFo); 74 return STATUS_SUCCESS; 75 } 76 77 static NTSTATUS vboxGdcSubmitAsync(ULONG uCtl, PVOID pvBuffer, SIZE_T cbBuffer, PKEVENT pEvent, PIO_STATUS_BLOCK pIoStatus) 78 { 79 NTSTATUS Status; 80 PIRP pIrp; 81 Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); 82 83 pIrp = IoBuildDeviceIoControlRequest(uCtl, g_ctx.Gdc.pDo, NULL, 0, NULL, 0, TRUE, pEvent, pIoStatus); 84 if (!pIrp) 85 { 86 WARN(("IoBuildDeviceIoControlRequest failed!!\n")); 87 pIoStatus->Status = STATUS_INSUFFICIENT_RESOURCES; 88 pIoStatus->Information = 0; 89 return STATUS_INSUFFICIENT_RESOURCES; 90 } 91 92 PIO_STACK_LOCATION pSl = IoGetNextIrpStackLocation(pIrp); 93 pSl->Parameters.Others.Argument1 = (PVOID)pvBuffer; 94 pSl->Parameters.Others.Argument2 = (PVOID)cbBuffer; 95 Status = IoCallDriver(g_ctx.Gdc.pDo, pIrp); 96 97 return Status; 98 } 99 100 static NTSTATUS vboxGdcSubmit(ULONG uCtl, PVOID pvBuffer, SIZE_T cbBuffer) 101 { 102 IO_STATUS_BLOCK IoStatus = {0}; 103 KEVENT Event; 104 NTSTATUS Status; 105 106 KeInitializeEvent(&Event, NotificationEvent, FALSE); 107 108 Status = vboxGdcSubmitAsync(uCtl, pvBuffer, cbBuffer, &Event, &IoStatus); 109 if (Status == STATUS_PENDING) 110 { 111 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 112 Status = IoStatus.Status; 113 } 114 115 return Status; 116 } 117 118 static DECLCALLBACK(void) vboxNewProtMouseEventCb(void *pvContext) 119 { 120 RT_NOREF(pvContext); 57 58 /** 59 * Called from DriverEntry to initialize g_ctx. 60 */ 61 void VBoxMouFltInitGlobals(void) 62 { 63 RT_ZERO(g_ctx); 64 KeInitializeSpinLock(&g_ctx.SyncLock); 65 InitializeListHead(&g_ctx.DevExtList); 66 } 67 68 69 /** 70 * Called on driver unload to clean up g_ctx. 71 */ 72 void VBoxMouFltDeleteGlobals(void) 73 { 74 Assert(IsListEmpty(&g_ctx.DevExtList)); 75 } 76 77 78 /** 79 * @callback_method_impl{FNVBOXGUESTMOUSENOTIFY} 80 */ 81 static DECLCALLBACK(void) vboxNewProtMouseEventCb(void *pvUser) 82 { 83 RT_NOREF(pvUser); 121 84 PVBOXMOUSE_DEVEXT pDevExt = (PVBOXMOUSE_DEVEXT)ASMAtomicUoReadPtr((void * volatile *)&g_ctx.pCurrentDevExt); 122 85 if (pDevExt) 123 86 { 124 #define VBOXMOUSE_POLLERTAG 'PMBV'125 87 NTSTATUS Status = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt); 126 88 if (NT_SUCCESS(Status)) … … 131 93 } 132 94 else 133 {134 95 WARN(("IoAcquireRemoveLock failed, Status (0x%x)", Status)); 135 }136 96 } 137 97 else 138 {139 98 WARN(("no current pDevExt specified")); 140 } 141 } 142 143 static BOOLEAN vboxNewProtIsEnabled() 144 { 145 return g_ctx.fIsNewProtEnabled; 146 } 147 148 static NTSTATUS vboxNewProtRegisterMouseEventCb(BOOLEAN fRegister) 149 { 150 VBGLIOCSETMOUSENOTIFYCALLBACK Info; 151 VBGLREQHDR_INIT(&Info.Hdr, SET_MOUSE_NOTIFY_CALLBACK); 152 Info.u.In.pfnNotify = fRegister ? vboxNewProtMouseEventCb : NULL; 153 Info.u.In.pvUser = NULL; 154 155 NTSTATUS Status = vboxGdcSubmit(VBGL_IOCTL_SET_MOUSE_NOTIFY_CALLBACK, &Info, sizeof(Info)); 156 if (!NT_SUCCESS(Status)) 157 WARN(("vboxGdcSubmit failed Status(0x%x)", Status)); 158 else if (RT_FAILURE(Info.Hdr.rc)) 159 { 160 WARN(("VBGL_IOCTL_SET_MOUSE_NOTIFY_CALLBACK failed: rc=%Rrc", Info.Hdr.rc)); 161 Status = STATUS_UNSUCCESSFUL; 162 } 163 return Status; 164 } 165 166 167 NTSTATUS VBoxNewProtInit() 168 { 169 NTSTATUS Status = VBoxGdcInit(); 170 if (NT_SUCCESS(Status)) 171 { 172 KeInitializeSpinLock(&g_ctx.SyncLock); 173 InitializeListHead(&g_ctx.DevExtList); 174 /* we assume the new prot data in g_ctx is zero-initialized (see g_ctx definition) */ 175 176 Status = vboxNewProtRegisterMouseEventCb(TRUE); 177 if (NT_SUCCESS(Status)) 178 { 179 g_ctx.fIsNewProtEnabled = TRUE; 180 return STATUS_SUCCESS; 181 } 182 VBoxGdcTerm(); 183 } 184 185 return Status; 186 } 187 188 NTSTATUS VBoxNewProtTerm() 99 } 100 101 /** 102 * Lazy init callback. 103 * 104 * We don't have control over when VBoxGuest.sys is loaded and therefore cannot 105 * be sure it is already around when we are started or our devices instantiated. 106 * So, we try lazily attaching to the device when we have a chance. 107 * 108 * @returns true on success, false on failure. 109 */ 110 static bool vboxNewProtLazyRegister(void) 111 { 112 if (g_ctx.fIsNewProtEnabled) 113 return true; 114 int rc = VbglSetMouseNotifyCallback(vboxNewProtMouseEventCb, NULL); 115 if (RT_SUCCESS(rc)) 116 { 117 g_ctx.fIsNewProtEnabled = true; 118 LOG(("Successfully register mouse event callback with VBoxGuest.")); 119 return true; 120 } 121 WARN(("VbglSetMouseNotifyCallback failed: %Rrc", rc)); 122 return false; 123 } 124 125 /** 126 * This is called when the last device instance is destroyed. 127 * 128 * @returns NT status. 129 */ 130 static void vboxNewProtTerm(void) 189 131 { 190 132 Assert(IsListEmpty(&g_ctx.DevExtList)); 191 if (!vboxNewProtIsEnabled()) 192 { 193 WARN(("New Protocol is disabled")); 194 return STATUS_SUCCESS; 195 } 196 197 g_ctx.fIsNewProtEnabled = FALSE; 198 199 NTSTATUS Status = vboxNewProtRegisterMouseEventCb(FALSE); 200 if (!NT_SUCCESS(Status)) 201 { 202 WARN(("KeWaitForSingleObject failed, Status (0x%x)", Status)); 203 return Status; 204 } 205 206 VBoxGdcTerm(); 207 208 return STATUS_SUCCESS; 209 } 210 211 static NTSTATUS vboxNewProtDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt) 212 { 213 if (!vboxNewProtIsEnabled()) 214 { 215 WARN(("New Protocol is disabled")); 216 return STATUS_UNSUCCESSFUL; 217 } 218 219 NTSTATUS Status = STATUS_SUCCESS; 133 if (g_ctx.fIsNewProtEnabled) 134 { 135 g_ctx.fIsNewProtEnabled = false; 136 int rc = VbglSetMouseNotifyCallback(NULL, NULL); 137 if (RT_FAILURE(rc)) 138 WARN(("VbglSetMouseNotifyCallback failed: %Rrc", rc)); 139 } 140 } 141 142 /** 143 * Worker for VBoxDeviceAdded that enables callback processing of pDevExt. 144 * 145 * @param pDevExt The device instance that was added. 146 */ 147 static void vboxNewProtDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt) 148 { 149 /* 150 * Always add the device to the list. 151 */ 220 152 KIRQL Irql; 221 153 KeAcquireSpinLock(&g_ctx.SyncLock, &Irql); 154 222 155 InsertHeadList(&g_ctx.DevExtList, &pDevExt->ListEntry); 156 223 157 /* g_ctx.pCurrentDevExt must be associated with the i8042prt device. */ 224 if ( pDevExt->bHostMouse && !g_ctx.pCurrentDevExt)225 {226 ASMAtomicWritePtr(&g_ctx.pCurrentDevExt, pDevExt);158 if ( pDevExt->bHostMouse 159 && ASMAtomicCmpXchgPtr(&g_ctx.pCurrentDevExt, pDevExt, NULL)) 160 { 227 161 /* ensure the object is not deleted while it is being used by a poller thread */ 228 162 ObReferenceObject(pDevExt->pdoSelf); 229 163 } 164 230 165 KeReleaseSpinLock(&g_ctx.SyncLock, Irql); 231 166 232 return Status; 233 } 234 235 #define PVBOXMOUSE_DEVEXT_FROM_LE(_pLe) ( (PVBOXMOUSE_DEVEXT)(((uint8_t*)(_pLe)) - RT_OFFSETOF(VBOXMOUSE_DEVEXT, ListEntry)) ) 236 237 static NTSTATUS vboxNewProtDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt) 238 { 239 if (!vboxNewProtIsEnabled()) 240 { 241 WARN(("New Protocol is disabled")); 242 return STATUS_UNSUCCESSFUL; 243 } 244 167 /* 168 * Do lazy callback registration. 169 */ 170 vboxNewProtLazyRegister(); 171 } 172 173 /** 174 * Worker for VBoxDeviceRemoved that disables callback processing of pDevExt. 175 * 176 * @param pDevExt The device instance that is being removed. 177 */ 178 static void vboxNewProtDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt) 179 { 180 /* 181 * Remove the device from the list. 182 */ 245 183 KIRQL Irql; 246 NTSTATUS Status = STATUS_SUCCESS;247 184 KeAcquireSpinLock(&g_ctx.SyncLock, &Irql); 185 248 186 RemoveEntryList(&pDevExt->ListEntry); 249 if (g_ctx.pCurrentDevExt == pDevExt) 250 {251 /* The PS/2 mouse is being removed. Usually never happens. */187 188 /* Check if the PS/2 mouse is being removed. Usually never happens. */ 189 if (ASMAtomicCmpXchgPtr(&g_ctx.pCurrentDevExt, NULL, pDevExt)) 252 190 ObDereferenceObject(pDevExt->pdoSelf); 253 g_ctx.pCurrentDevExt = NULL;254 }255 191 256 192 KeReleaseSpinLock(&g_ctx.SyncLock, Irql); 257 258 return Status; 259 } 260 261 VOID VBoxDrvNotifyServiceCB(PVBOXMOUSE_DEVEXT pDevExt, PMOUSE_INPUT_DATA InputDataStart, PMOUSE_INPUT_DATA InputDataEnd, PULONG InputDataConsumed) 262 { 263 KIRQL Irql; 193 } 194 195 VOID VBoxDrvNotifyServiceCB(PVBOXMOUSE_DEVEXT pDevExt, PMOUSE_INPUT_DATA InputDataStart, PMOUSE_INPUT_DATA InputDataEnd, 196 PULONG InputDataConsumed) 197 { 264 198 /* we need to avoid concurrency between the poller thread and our ServiceCB. 265 199 * this is perhaps not the best way of doing things, but the most easiest to avoid concurrency 266 200 * and to ensure the pfnServiceCB is invoked at DISPATCH_LEVEL */ 201 KIRQL Irql; 267 202 KeAcquireSpinLock(&g_ctx.SyncLock, &Irql); 268 203 if (pDevExt->pSCReq) 269 204 { 270 205 int rc = VbglGRPerform(&pDevExt->pSCReq->header); 271 272 206 if (RT_SUCCESS(rc)) 273 207 { … … 275 209 { 276 210 PMOUSE_INPUT_DATA pData = InputDataStart; 277 while (pData <InputDataEnd)211 while (pData < InputDataEnd) 278 212 { 279 213 pData->LastX = pDevExt->pSCReq->pointerXPos; 280 214 pData->LastY = pDevExt->pSCReq->pointerYPos; 281 215 pData->Flags = MOUSE_MOVE_ABSOLUTE; 282 if ( vboxNewProtIsEnabled())216 if (g_ctx.fIsNewProtEnabled) 283 217 pData->Flags |= MOUSE_VIRTUAL_DESKTOP; 284 218 pData++; … … 292 226 else 293 227 { 294 WARN(("VbglGRPerform failed with rc=% #x", rc));228 WARN(("VbglGRPerform failed with rc=%Rrc", rc)); 295 229 } 296 230 } 297 231 298 232 /* Call original callback */ 299 pDevExt->OriginalConnectData.pfnServiceCB(pDevExt->OriginalConnectData.pDO, 300 InputDataStart, InputDataEnd, InputDataConsumed); 233 pDevExt->OriginalConnectData.pfnServiceCB(pDevExt->OriginalConnectData.pDO, InputDataStart, InputDataEnd, InputDataConsumed); 301 234 KeReleaseSpinLock(&g_ctx.SyncLock, Irql); 302 235 } … … 307 240 } 308 241 309 static BOOLEAN vboxIsVBGLInitFailed 242 static BOOLEAN vboxIsVBGLInitFailed(void) 310 243 { 311 244 return InterlockedCompareExchange(&g_ctx.fVBGLInitFailed, TRUE, TRUE) == TRUE; … … 322 255 } 323 256 324 VOIDVBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt)257 void VBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt) 325 258 { 326 259 LOGF_ENTER(); 327 LONG c allCnt= InterlockedIncrement(&g_ctx.cDevicesStarted);260 LONG cCalls = InterlockedIncrement(&g_ctx.cDevicesStarted); 328 261 329 262 /* One time Vbgl initialization */ 330 if (callCnt == 1) 331 { 263 if (cCalls == 1) 264 { 265 KeInitializeSpinLock(&g_ctx.SyncLock); 266 InitializeListHead(&g_ctx.DevExtList); 267 332 268 if (!vboxIsVBGLInited() && !vboxIsVBGLInitFailed()) 333 269 { … … 337 273 InterlockedExchange(&g_ctx.fVBGLInited, TRUE); 338 274 LOG(("VBGL init OK")); 275 vboxNewProtLazyRegister(); 339 276 } 340 277 else 341 278 { 342 InterlockedExchange 343 WARN(("VBGL init failed with rc=% #x", rc));279 InterlockedExchange(&g_ctx.fVBGLInitFailed, TRUE); 280 WARN(("VBGL init failed with rc=%Rrc", rc)); 344 281 } 345 282 } … … 414 351 * For this device the filter will query absolute mouse coords from the host. 415 352 */ 353 /** @todo r=bird: The g_ctx.fHostMouseFound needs to be cleared 354 * when the device is removed... */ 416 355 InterlockedExchange(&g_ctx.fHostMouseFound, TRUE); 417 356 … … 427 366 } 428 367 429 VOIDVBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt)368 void VBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt) 430 369 { 431 370 LOGF_ENTER(); 432 433 if (!vboxIsVBGLInited()) 434 { 371 if (vboxIsVBGLInited()) 372 { 373 /* Do lazy callback installation. */ 374 vboxNewProtLazyRegister(); 375 376 /* Inform host we support absolute coordinates */ 377 if (pDevExt->bHostMouse && !vboxIsHostInformed()) 378 { 379 VMMDevReqMouseStatus *req = NULL; 380 int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus); 381 if (RT_SUCCESS(rc)) 382 { 383 req->mouseFeatures = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE; 384 if (g_ctx.fIsNewProtEnabled) 385 req->mouseFeatures |= VMMDEV_MOUSE_NEW_PROTOCOL; 386 387 req->pointerXPos = 0; 388 req->pointerYPos = 0; 389 390 rc = VbglGRPerform(&req->header); 391 if (RT_SUCCESS(rc)) 392 InterlockedExchange(&g_ctx.fHostInformed, TRUE); 393 else 394 WARN(("VbglGRPerform failed with rc=%Rrc", rc)); 395 396 VbglGRFree(&req->header); 397 } 398 else 399 WARN(("VbglGRAlloc failed with rc=%Rrc", rc)); 400 } 401 402 /* Preallocate request to be used in VBoxServiceCB*/ 403 if (pDevExt->bHostMouse && !pDevExt->pSCReq) 404 { 405 VMMDevReqMouseStatus *req = NULL; 406 int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus); 407 if (RT_SUCCESS(rc)) 408 InterlockedExchangePointer((PVOID volatile *)&pDevExt->pSCReq, req); 409 else 410 { 411 WARN(("VbglGRAlloc for service callback failed with rc=%Rrc", rc)); 412 } 413 } 414 } 415 else 435 416 WARN(("!vboxIsVBGLInited")); 436 return; 437 } 438 439 /* Inform host we support absolute coordinates */ 440 if (pDevExt->bHostMouse && !vboxIsHostInformed()) 417 LOGF_LEAVE(); 418 } 419 420 VOID VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt) 421 { 422 LOGF_ENTER(); 423 424 /* 425 * Tell the host that from now on we can't handle absolute coordinates anymore. 426 */ 427 if (pDevExt->bHostMouse && vboxIsHostInformed()) 441 428 { 442 429 VMMDevReqMouseStatus *req = NULL; 443 430 int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus); 444 445 if (RT_SUCCESS(rc))446 {447 req->mouseFeatures = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;448 if (vboxNewProtIsEnabled())449 req->mouseFeatures |= VMMDEV_MOUSE_NEW_PROTOCOL;450 451 req->pointerXPos = 0;452 req->pointerYPos = 0;453 454 rc = VbglGRPerform(&req->header);455 456 if (RT_SUCCESS(rc))457 {458 InterlockedExchange(&g_ctx.fHostInformed, TRUE);459 }460 else461 {462 WARN(("VbglGRPerform failed with rc=%#x", rc));463 }464 465 VbglGRFree(&req->header);466 }467 else468 {469 WARN(("VbglGRAlloc failed with rc=%#x", rc));470 }471 }472 473 /* Preallocate request to be used in VBoxServiceCB*/474 if (pDevExt->bHostMouse && !pDevExt->pSCReq)475 {476 VMMDevReqMouseStatus *req = NULL;477 478 int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);479 480 if (RT_SUCCESS(rc))481 {482 InterlockedExchangePointer((PVOID volatile *)&pDevExt->pSCReq, req);483 }484 else485 {486 WARN(("VbglGRAlloc for service callback failed with rc=%#x", rc));487 }488 }489 490 LOGF_LEAVE();491 }492 493 VOID VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt)494 {495 LOGF_ENTER();496 497 /* Save the allocated request pointer and clear the devExt. */498 VMMDevReqMouseStatus *pSCReq = (VMMDevReqMouseStatus *) InterlockedExchangePointer((PVOID volatile *)&pDevExt->pSCReq, NULL);499 500 if (pDevExt->bHostMouse && vboxIsHostInformed())501 {502 // tell the VMM that from now on we can't handle absolute coordinates anymore503 VMMDevReqMouseStatus *req = NULL;504 505 int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);506 507 431 if (RT_SUCCESS(rc)) 508 432 { … … 512 436 513 437 rc = VbglGRPerform(&req->header); 514 515 438 if (RT_FAILURE(rc)) 516 { 517 WARN(("VbglGRPerform failed with rc=%#x", rc)); 518 } 439 WARN(("VbglGRPerform failed with rc=%Rrc", rc)); 519 440 520 441 VbglGRFree(&req->header); 521 442 } 522 443 else 523 { 524 WARN(("VbglGRAlloc failed with rc=%#x", rc)); 525 } 444 WARN(("VbglGRAlloc failed with rc=%Rrc", rc)); 526 445 527 446 InterlockedExchange(&g_ctx.fHostInformed, FALSE); 528 447 } 529 448 449 /* 450 * Remove the device from the list so we won't get callouts any more. 451 */ 452 vboxNewProtDeviceRemoved(pDevExt); 453 454 /* 455 * Free the preallocated request. 456 * Note! This could benefit from merging with vboxNewProtDeviceRemoved to 457 * avoid taking the spinlock twice in a row. 458 */ 459 KIRQL Irql; 460 KeAcquireSpinLock(&g_ctx.SyncLock, &Irql); 461 VMMDevReqMouseStatus *pSCReq = ASMAtomicXchgPtrT(&pDevExt->pSCReq, NULL, VMMDevReqMouseStatus *); 462 KeReleaseSpinLock(&g_ctx.SyncLock, Irql); 530 463 if (pSCReq) 531 {532 464 VbglGRFree(&pSCReq->header); 533 } 534 535 LONG callCnt = InterlockedDecrement(&g_ctx.cDevicesStarted); 536 537 vboxNewProtDeviceRemoved(pDevExt); 538 539 if (callCnt == 0) 465 466 /* 467 * Do init ref count handling. 468 * Note! This sequence could potentially be racing VBoxDeviceAdded, depending 469 * on what the OS allows to run in parallel... 470 */ 471 LONG cCalls = InterlockedDecrement(&g_ctx.cDevicesStarted); 472 if (cCalls == 0) 540 473 { 541 474 if (vboxIsVBGLInited()) … … 544 477 InterlockedExchange(&g_ctx.fVBGLInitFailed, TRUE); 545 478 479 vboxNewProtTerm(); 546 480 VbglR0TerminateClient(); 547 481 … … 554 488 LOGF_LEAVE(); 555 489 } 490
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器