Changeset 37225 in vbox for trunk/src/VBox
- Timestamp:
- May 26, 2011 2:49:59 PM (14 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Mouse/NT5
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMF.h
r37221 r37225 47 47 typedef struct _VBOXMOUSE_DEVEXT 48 48 { 49 LIST_ENTRY ListEntry; 49 50 PDEVICE_OBJECT pdoMain; /* PDO passed to VBoxDrvAddDevice */ 50 51 PDEVICE_OBJECT pdoSelf; /* our PDO created in VBoxDrvAddDevice*/ … … 77 78 VOID VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt); 78 79 80 NTSTATUS VBoxNewProtInit(); 81 NTSTATUS VBoxNewProtTerm(); 82 79 83 VOID VBoxDrvNotifyServiceCB(PVBOXMOUSE_DEVEXT pDevExt, PMOUSE_INPUT_DATA InputDataStart, PMOUSE_INPUT_DATA InputDataEnd, PULONG InputDataConsumed); 80 84 -
trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFDriver.cpp
r37221 r37225 51 51 DriverObject->MajorFunction[IRP_MJ_PNP] = VBoxIrpPnP; 52 52 53 NTSTATUS tmpStatus = VBoxNewProtInit(); 54 if (!NT_SUCCESS(tmpStatus)) 55 { 56 WARN(("VBoxNewProtInit failed Status (0x%x)", tmpStatus)); 57 } 58 53 59 LOGF_LEAVE(); 54 60 return STATUS_SUCCESS; … … 60 66 PAGED_CODE(); 61 67 LOGF_ENTER(); 68 69 NTSTATUS tmpStatus = VBoxNewProtTerm(); 70 if (!NT_SUCCESS(tmpStatus)) 71 { 72 WARN(("VBoxNewProtTerm failed Status (0x%x)", tmpStatus)); 73 } 74 62 75 63 76 RTR0Term(); -
trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFInternal.cpp
r37221 r37225 43 43 volatile PVBOXMOUSE_DEVEXT pCurrentDevExt; 44 44 LIST_ENTRY DevExtList; 45 volatile bool fIsNewProtEnabled; 45 46 MOUSE_INPUT_DATA LastReportedData; 46 47 } VBoxGlobalContext; … … 48 49 static VBoxGlobalContext g_ctx = {}; 49 50 51 /* Guest Device Communication API */ 50 52 NTSTATUS VBoxGdcInit() 51 53 { … … 207 209 } 208 210 209 static NTSTATUS vboxNewProtInit(PVBOXMOUSE_DEVEXT pCurrentDevExt) 211 static BOOLEAN vboxNewProtIsInitialized() 212 { 213 return !!g_ctx.pThread; 214 } 215 216 static BOOLEAN vboxNewProtIsStarted() 217 { 218 return (BOOLEAN)ASMAtomicReadBool(&g_ctx.fIsNewProtEnabled); 219 } 220 221 NTSTATUS VBoxNewProtInit() 210 222 { 211 223 NTSTATUS Status = VBoxGdcInit(); … … 215 227 KeInitializeEvent(&g_ctx.TerminateEvent, NotificationEvent, FALSE); 216 228 KeInitializeEvent(&g_ctx.MouseEvent, SynchronizationEvent, FALSE); 217 218 Status = VBoxGdcSetMouseNotifyEvent(&g_ctx.MouseEvent); 229 InitializeListHead(&g_ctx.DevExtList); 230 /* we assume the new prot data in g_ctx is zero-initialized (see g_ctx definition) */ 231 232 Status = vboxCreateSystemThread(&g_ctx.pThread, vboxMouseEventPollerThread, NULL); 219 233 if (NT_SUCCESS(Status)) 220 234 { 221 Status = vboxCreateSystemThread(&g_ctx.pThread, vboxMouseEventPollerThread, NULL); 222 if (NT_SUCCESS(Status)) 223 { 224 g_ctx.pCurrentDevExt = pCurrentDevExt; 225 return STATUS_SUCCESS; 226 } 227 g_ctx.pThread = NULL; 228 NTSTATUS tmpStatus = VBoxGdcSetMouseNotifyEvent(NULL); 229 Assert(NT_SUCCESS(tmpStatus)); 230 } 231 } 232 233 return Status; 234 } 235 236 static BOOLEAN vboxNewProtIsSupported() 237 { 238 return !!g_ctx.pThread; 239 } 240 241 static NTSTATUS vboxNewProtTerm() 242 { 235 return STATUS_SUCCESS; 236 } 237 g_ctx.pThread = NULL; 238 } 239 240 return Status; 241 } 242 243 NTSTATUS VBoxNewProtTerm() 244 { 245 Assert(IsListEmpty(&g_ctx.DevExtList)); 246 Assert(!vboxNewProtIsStarted()); 247 if (!vboxNewProtIsInitialized()) 248 return STATUS_SUCCESS; 249 243 250 KeSetEvent(&g_ctx.TerminateEvent, 0, FALSE); 244 251 NTSTATUS Status = KeWaitForSingleObject(g_ctx.pThread, Executive, KernelMode, FALSE, NULL); … … 249 256 } 250 257 251 Status = VBoxGdcSetMouseNotifyEvent(NULL);252 if (!NT_SUCCESS(Status))253 {254 WARN(("VBoxGdcSetMouseNotifyEvent failed, Status (0x%x)", Status));255 return Status;256 }257 258 258 ObDereferenceObject(g_ctx.pThread); 259 259 g_ctx.pThread = NULL; … … 262 262 } 263 263 264 static NTSTATUS vboxNewProtSetCurrentDevExt(PVBOXMOUSE_DEVEXT pCurrentDevExt) 265 { 266 ASMAtomicWritePtrVoid((void * volatile *)&g_ctx.pCurrentDevExt, pCurrentDevExt); 267 return STATUS_SUCCESS; 264 static NTSTATUS vboxNewProtDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt) 265 { 266 if (!vboxNewProtIsInitialized()) 267 return STATUS_UNSUCCESSFUL; 268 269 NTSTATUS Status = STATUS_SUCCESS; 270 KIRQL Irql; 271 BOOLEAN fDoEventRegister = FALSE; 272 KeAcquireSpinLock(&g_ctx.SyncLock, &Irql); 273 InsertHeadList(&g_ctx.DevExtList, &pDevExt->ListEntry); 274 if (!g_ctx.pCurrentDevExt) 275 { 276 ASMAtomicWritePtr(&g_ctx.pCurrentDevExt, pDevExt); 277 /* ensure the object is not deleted while it is being used by a poller thread */ 278 ObReferenceObject(pDevExt->pdoSelf); 279 fDoEventRegister = TRUE; 280 } 281 KeReleaseSpinLock(&g_ctx.SyncLock, Irql); 282 283 if (fDoEventRegister) 284 { 285 /* to ensure we do not concur with vboxNewProtDeviceRemoved cleaning the event, 286 * do it in a loop until the cauuent state of fIsNewProtEnabled is false, 287 * setting one and the same event multiple times will not hutr */ 288 do 289 { 290 Status = VBoxGdcSetMouseNotifyEvent(&g_ctx.MouseEvent); 291 if (!NT_SUCCESS(Status)) 292 { 293 WARN(("VBoxGdcSetMouseNotifyEvent failed, Status (0x%x)", Status)); 294 break; 295 } 296 } while (ASMAtomicCmpXchgBool(&g_ctx.fIsNewProtEnabled, true, false)); 297 298 if (NT_SUCCESS(Status)) 299 { 300 /* signal the event to ensure we did not miss anything */ 301 KeSetEvent(&g_ctx.MouseEvent, 0, FALSE); 302 Status = STATUS_SUCCESS; 303 } 304 } 305 #ifdef DEBUG_misha 306 else 307 { 308 Assert(g_ctx.fIsNewProtEnabled); 309 } 310 #endif 311 312 return Status; 313 } 314 315 #define PVBOXMOUSE_DEVEXT_FROM_LE(_pLe) ( (PVBOXMOUSE_DEVEXT)(((uint8_t*)(_pLe)) - RT_OFFSETOF(VBOXMOUSE_DEVEXT, ListEntry)) ) 316 317 static NTSTATUS vboxNewProtDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt) 318 { 319 if (!vboxNewProtIsInitialized()) 320 return STATUS_UNSUCCESSFUL; 321 322 KIRQL Irql; 323 NTSTATUS Status = STATUS_SUCCESS; 324 BOOLEAN fDoEventUnregister = FALSE; 325 KeAcquireSpinLock(&g_ctx.SyncLock, &Irql); 326 RemoveEntryList(&pDevExt->ListEntry); 327 if (g_ctx.pCurrentDevExt == pDevExt) 328 { 329 ObDereferenceObject(pDevExt->pdoSelf); 330 g_ctx.pCurrentDevExt = NULL; 331 for (PLIST_ENTRY pCur = g_ctx.DevExtList.Flink; pCur != &g_ctx.DevExtList; pCur = pCur->Flink) 332 { 333 PVBOXMOUSE_DEVEXT pNewCurDevExt = PVBOXMOUSE_DEVEXT_FROM_LE(pCur); 334 ASMAtomicWritePtr(&g_ctx.pCurrentDevExt, pNewCurDevExt); 335 /* ensure the object is not deleted while it is being used by a poller thread */ 336 ObReferenceObject(pNewCurDevExt->pdoSelf); 337 break; 338 } 339 } 340 341 fDoEventUnregister = IsListEmpty(&g_ctx.DevExtList); 342 KeReleaseSpinLock(&g_ctx.SyncLock, Irql); 343 344 if (fDoEventUnregister) 345 { 346 if (vboxNewProtIsStarted()) 347 { 348 Status = VBoxGdcSetMouseNotifyEvent(NULL); 349 if (!NT_SUCCESS(Status)) 350 { 351 WARN(("VBoxGdcSetMouseNotifyEvent failed, Status (0x%x)", Status)); 352 } 353 354 ASMAtomicWriteBool(&g_ctx.fIsNewProtEnabled, false); 355 } 356 } 357 358 return Status; 268 359 } 269 360 … … 289 380 pData->LastY = pDevExt->pSCReq->pointerYPos; 290 381 pData->Flags = MOUSE_MOVE_ABSOLUTE; 291 if (vboxNewProtIsS upported())382 if (vboxNewProtIsStarted()) 292 383 pData->Flags |= MOUSE_VIRTUAL_DESKTOP; 293 384 pData++; … … 353 444 WARN(("VBGL init failed with rc=%#x", rc)); 354 445 } 355 356 vboxNewProtInit(pDevExt);357 } 358 }446 } 447 } 448 449 vboxNewProtDeviceAdded(pDevExt); 359 450 360 451 if (!vboxIsHostMouseFound()) … … 454 545 { 455 546 req->mouseFeatures = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE; 456 if (vboxNewProtIsS upported())547 if (vboxNewProtIsStarted()) 457 548 req->mouseFeatures |= VMMDEV_MOUSE_NEW_PROTOCOL; 458 549 … … 543 634 LONG callCnt = InterlockedDecrement(&g_ctx.cDevicesStarted); 544 635 636 vboxNewProtDeviceRemoved(pDevExt); 637 545 638 if (callCnt == 0) 546 639 { 547 vboxNewProtTerm();548 549 640 if (vboxIsVBGLInited()) 550 641 {
Note:
See TracChangeset
for help on using the changeset viewer.