VirtualBox

Changeset 5083 in vbox


Ignore:
Timestamp:
Sep 27, 2007 6:21:19 PM (17 years ago)
Author:
vboxsync
Message:

Fixed the Windows guest additions mouse filter driver trap with two or more mouse devices.

Location:
trunk/src/VBox/Additions/WINNT/MouseFilter
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/MouseFilter/VBoxMouse.cpp

    r4071 r5083  
    8484}
    8585
     86#ifdef LOG_ENABLED
     87void dumpDevExt (PDEVICE_EXTENSION devExt)
     88{
     89    dprintf ((
     90             "devExt %p\n"
     91             "  %p %p %p\n"
     92             "  %d %p %p %p %p\n"
     93             "  %p\n"
     94             "  %p %p\n"
     95             "  %d %d %d %d\n"
     96             "  %p %d\n",
     97             devExt,
     98             devExt->Self, devExt->PDO, devExt->TopOfStack,
     99             devExt->EnableCount, devExt->UpperContext, devExt->UpperIsrHook, devExt->IsrWritePort, devExt->CallContext,
     100             devExt->QueueMousePacket,
     101             devExt->UpperConnectData.ClassDeviceObject, devExt->UpperConnectData.ClassService,
     102             devExt->DeviceState, devExt->Started, devExt->SurpriseRemoved, devExt->Removed,
     103             devExt->reqSC, devExt->HostMouse
     104            ));
     105}
     106#else
     107#define dumpDevExt(a) do {} while (0)
     108#endif /* LOG_ENABLED */
     109
    86110// VBOX start
    87 void vboxInformHost (PDEVICE_EXTENSION devExt)
    88 {
    89     dprintf (("VBoxMouse::vboxInformHost: devExt->HostInformed = %d\n", devExt->HostInformed));
    90    
    91     if (!devExt->HostInformed)
     111typedef struct _VBoxGlobalContext
     112{
     113    volatile LONG cDevicesStarted;
     114    volatile LONG fVBGLInited;
     115    volatile LONG fVBGLInitFailed;
     116    volatile LONG fHostInformed;
     117} VBoxGlobalContext;
     118
     119VBoxGlobalContext g_ctx = { 0, FALSE, FALSE, FALSE };
     120
     121BOOLEAN vboxIsVBGLInited (void)
     122{
     123   return InterlockedCompareExchange (&g_ctx.fVBGLInited, TRUE, TRUE) == TRUE;
     124}
     125
     126BOOLEAN vboxIsVBGLInitFailed (void)
     127{
     128   return InterlockedCompareExchange (&g_ctx.fVBGLInitFailed, TRUE, TRUE) == TRUE;
     129}
     130
     131BOOLEAN vboxIsHostInformed (void)
     132{
     133   return InterlockedCompareExchange (&g_ctx.fVBGLInitFailed, TRUE, TRUE) == TRUE;
     134}
     135
     136void vboxDeviceAdded (PDEVICE_EXTENSION devExt)
     137{
     138    LONG c = InterlockedIncrement (&g_ctx.cDevicesStarted);
     139
     140    if (c == 1)
    92141    {
    93         VMMDevReqMouseStatus *req = NULL;
    94 
    95         int vboxRC = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
    96 
    97         if (VBOX_SUCCESS(vboxRC))
     142        if (   !vboxIsVBGLInited ()
     143            && !vboxIsVBGLInitFailed ())
    98144        {
    99             /* Inform host that we support absolute */
    100             req->mouseFeatures = VBOXGUEST_MOUSE_GUEST_CAN_ABSOLUTE;
    101             req->pointerXPos = 0;
    102             req->pointerYPos = 0;
    103 
    104             vboxRC = VbglGRPerform (&req->header);
    105 
    106             if (VBOX_FAILURE(vboxRC) || VBOX_FAILURE(req->header.rc))
     145            /*  Do one time initialization. */
     146            int vboxRC = VbglInit ();
     147
     148            if (VBOX_SUCCESS (vboxRC))
    107149            {
    108                  dprintf(("VBoxMouse::vboxInformHost: ERROR communicating new mouse capabilities to VMMDev."
    109                           "rc = %d, VMMDev rc = %Vrc\n", vboxRC, req->header.rc));
     150                /* Atomically set the flag. */
     151                InterlockedExchange (&g_ctx.fVBGLInited, TRUE);
     152                dprintf(("VBoxMouse::vboxDeviceStarted: guest library initialization OK\n"));
     153
     154                /* Mark the first device as the Host one, that is the emulated mouse.
     155                 * For this device the filter will query absolute mouse coords from the host.
     156                 * @todo: Better would be to query the device information and detect the emulated device.
     157                 */
     158                devExt->HostMouse = TRUE;
    110159            }
    111160            else
    112161            {
    113                 devExt->HostInformed = TRUE;
    114 
    115                 if (!devExt->reqSC)
     162                InterlockedExchange (&g_ctx.fVBGLInitFailed, TRUE);
     163                dprintf(("VBoxMouse::vboxDeviceStarted: guest library initialization failed\n"));
     164            }
     165        }
     166    }
     167}
     168
     169void vboxDeviceRemoved (PDEVICE_EXTENSION devExt)
     170{
     171    dprintf(("VBoxMouse::vboxDeviceRemoved\n"));
     172
     173    LONG c = InterlockedIncrement (&g_ctx.cDevicesStarted);
     174
     175    if (c == 0)
     176    {
     177        if (vboxIsVBGLInited ())
     178        {
     179            /* Set the flag to prevent reinitializing of the VBGL. */
     180            InterlockedExchange (&g_ctx.fVBGLInitFailed, TRUE);
     181
     182            /* Save the allocated request pointer and clear the devExt. */
     183            VMMDevReqMouseStatus *reqSC = devExt->reqSC;
     184            devExt->reqSC = NULL;
     185
     186            // tell the VMM that from now on we can't handle absolute coordinates anymore
     187            VMMDevReqMouseStatus *req = NULL;
     188
     189            int vboxRC = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
     190
     191            if (VBOX_SUCCESS(vboxRC))
     192            {
     193                req->mouseFeatures = 0;
     194                req->pointerXPos = 0;
     195                req->pointerYPos = 0;
     196
     197                vboxRC = VbglGRPerform (&req->header);
     198
     199                if (VBOX_FAILURE(vboxRC) || VBOX_FAILURE(req->header.rc))
    116200                {
    117                     /* Preallocate request for ServiceCallback */
    118                     VMMDevReqMouseStatus *req = NULL;
    119 
    120                     vboxRC = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);
    121 
    122                     if (VBOX_SUCCESS(vboxRC))
    123                     {
    124                         devExt->reqSC = req;
    125                     }
    126                     else
    127                     {
    128                         dprintf(("VBoxMouse::vboxInformHost: request allocation for service callback failed\n"));
    129                     }
     201                    dprintf(("VBoxMouse::vboxDeviceRemoved: ERROR communicating new mouse capabilities to VMMDev.\n"
     202                             "rc = %d, VMMDev rc = %Vrc\n", vboxRC, req->header.rc));
    130203                }
     204
     205                VbglGRFree (&req->header);
    131206            }
    132207
    133             VbglGRFree(&req->header);
     208            if (reqSC)
     209            {
     210                VbglGRFree (&reqSC->header);
     211            }
     212
     213            VbglTerminate ();
     214
     215            /* The VBGL is now in the not initialized state. */
     216            InterlockedExchange (&g_ctx.fHostInformed, FALSE);
     217            InterlockedExchange (&g_ctx.fVBGLInited, FALSE);
     218            InterlockedExchange (&g_ctx.fVBGLInitFailed, FALSE);
     219        }
     220    }
     221}
     222
     223void vboxInformHost (PDEVICE_EXTENSION devExt)
     224{
     225    dprintf (("VBoxMouse::vboxInformHost: %p\n", devExt));
     226
     227    if (vboxIsVBGLInited ())
     228    {
     229        if (!vboxIsHostInformed ())
     230        {
     231            VMMDevReqMouseStatus *req = NULL;
     232
     233            int vboxRC = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
     234
     235            if (VBOX_SUCCESS(vboxRC))
     236            {
     237                /* Inform host that we support absolute */
     238                req->mouseFeatures = VBOXGUEST_MOUSE_GUEST_CAN_ABSOLUTE;
     239                req->pointerXPos = 0;
     240                req->pointerYPos = 0;
     241
     242                vboxRC = VbglGRPerform (&req->header);
     243
     244                if (VBOX_FAILURE(vboxRC) || VBOX_FAILURE(req->header.rc))
     245                {
     246                    dprintf(("VBoxMouse::vboxInformHost: ERROR communicating new mouse capabilities to VMMDev."
     247                              "rc = %d, VMMDev rc = %Vrc\n", vboxRC, req->header.rc));
     248                }
     249                else
     250                {
     251                    InterlockedExchange (&g_ctx.fHostInformed, TRUE);
     252                }
     253
     254                VbglGRFree(&req->header);
     255            }
     256        }
     257
     258        if (devExt->HostMouse && !devExt->reqSC)
     259        {
     260            /* Preallocate request for ServiceCallback */
     261            VMMDevReqMouseStatus *req = NULL;
     262
     263            int vboxRC = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);
     264
     265            if (VBOX_SUCCESS(vboxRC))
     266            {
     267                devExt->reqSC = req;
     268                dumpDevExt (devExt);
     269            }
     270            else
     271            {
     272                dprintf(("VBoxMouse::vboxInformHost: request allocation for service callback failed\n"));
     273            }
    134274        }
    135275    }
     
    152292    UNREFERENCED_PARAMETER(errorLogEntry);
    153293
    154     dprintf(("VBoxMouse::AddDevice\n"));
     294    dprintf(("VBoxMouse::AddDevice Driver %p, PDO %p\n", Driver, PDO));
    155295
    156296    status = IoCreateDevice(Driver,
     
    186326    devExt->Started =         FALSE;
    187327
     328// VBOX start
     329    vboxDeviceAdded (devExt);
     330// VBOX end
     331
    188332    device->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    189333    device->Flags &= ~DO_DEVICE_INITIALIZING;
    190334
    191     dprintf(("returning from AddDevice with rc = 0x%x\n", status));
     335    dprintf(("DevExt = %p, returning from AddDevice with rc = 0x%x\n", devExt, status));
    192336    return status;
    193337}
     
    214358    pDevExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    215359
    216     dprintf(("VBoxMouse_StartComplete\n"));
     360    dprintf(("VBoxMouse_StartComplete %p\n", pDevExt));
    217361
    218362    //
     
    244388    PAGED_CODE();
    245389
    246     dprintf(("VBoxMouse::CreateClose\n"));
    247 
    248390    irpStack = IoGetCurrentIrpStackLocation(Irp);
    249391    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
     392
     393    dprintf(("VBoxMouse::CreateClose %p\n", devExt));
    250394
    251395    status = Irp->IoStatus.Status;
     
    276420    case IRP_MJ_CLOSE:
    277421
     422        dprintf(("IRP_MJ_CLOSE\n"));
    278423        ASSERT(0 < devExt->EnableCount);
    279424
     
    376521    NTSTATUS                    status = STATUS_SUCCESS;
    377522
    378     dprintf(("VBoxMouse_InternIoCtl\n"));
    379 
    380523    UNREFERENCED_PARAMETER(event);
    381524
     
    383526    Irp->IoStatus.Information = 0;
    384527    irpStack = IoGetCurrentIrpStackLocation(Irp);
     528
     529    dprintf(("VBoxMouse_InternIoCtl %p\n", devExt));
    385530
    386531    dprintf(("VBoxMouse_InternIoCtl: %08X, fn = %d(%04X)\n",
     
    389534              (irpStack->Parameters.DeviceIoControl.IoControlCode >> 2) & 0xFFF
    390535              ));
    391              
    392     dprintf (("VBoxMouse_InternIoCtl: devExt->HostInformed = %d\n", devExt->HostInformed));
    393536
    394537    switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
     
    556699    UNREFERENCED_PARAMETER(oldIrql);
    557700
    558     dprintf(("VBoxMouse_PnP\n"));
    559 
    560701    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    561702    irpStack = IoGetCurrentIrpStackLocation(Irp);
     703
     704    dprintf(("VBoxMouse_PnP %p\n", devExt));
    562705
    563706    switch (irpStack->MinorFunction) {
     
    598741        dprintf(("status: %x, irp status: %x\n", Irp->IoStatus.Status));
    599742
    600         if (NT_SUCCESS(Irp->IoStatus.Status))
    601         {
    602 // VBOX start
    603             devExt->reqSC = NULL;
    604 
    605             int vboxRC = VbglInit ();
    606 
    607             if (VBOX_FAILURE(vboxRC))
    608             {
    609                 dprintf(("VBoxMouse::VBoxMouse_PnP: guest library initialization failed\n"));
    610 
    611                 /* Still a success, the mouse filter will still work to let the mouse working. */
    612                 status = STATUS_SUCCESS;
    613             }
    614 // VBOX end
    615 
    616             if (NT_SUCCESS(status))
    617             {
    618                 devExt->Started = TRUE;
    619                 devExt->Removed = FALSE;
    620                 devExt->SurpriseRemoved = FALSE;
    621 
    622             }
     743        if (NT_SUCCESS(status) && NT_SUCCESS(Irp->IoStatus.Status)) {
     744            devExt->Started = TRUE;
     745            devExt->Removed = FALSE;
     746            devExt->SurpriseRemoved = FALSE;
    623747        }
    624748
     
    651775    case IRP_MN_REMOVE_DEVICE:
    652776    {
     777        dprintf(("IRP_MN_REMOVE_DEVICE\n"));
    653778// VBOX start
    654         dprintf(("IRP_MN_REMOVE_DEVICE\n"));
    655        
    656         // tell the VMM that from now on we can't handle absolute coordinates anymore
    657         VMMDevReqMouseStatus *req = NULL;
    658 
    659         int vboxRC = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
    660 
    661         if (VBOX_SUCCESS(vboxRC))
    662         {
    663             req->mouseFeatures = 0;
    664             req->pointerXPos = 0;
    665             req->pointerYPos = 0;
    666 
    667             vboxRC = VbglGRPerform (&req->header);
    668 
    669             if (VBOX_FAILURE(vboxRC) || VBOX_FAILURE(req->header.rc))
    670             {
    671                 dprintf(("VBoxMouse::VBoxMouse_PnP: REMOVE_DEVICE: ERROR communicating new mouse capabilities to VMMDev."
    672                          "rc = %d, VMMDev rc = %Vrc\n", vboxRC, req->header.rc));
    673             }
    674 
    675             VbglGRFree (&req->header);
    676         }
    677 
    678         req = devExt->reqSC;
    679         devExt->reqSC = NULL;
    680 
    681         if (req)
    682         {
    683             VbglGRFree (&req->header);
    684         }
    685 
    686         VbglTerminate ();
     779        vboxDeviceRemoved (devExt);
    687780// VBOX end
    688781
     
    762855    PAGED_CODE();
    763856
    764     dprintf(("VBoxMouse_Power\n"));
    765 
    766857    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    767858    irpStack = IoGetCurrentIrpStackLocation(Irp);
     859
     860    dprintf(("VBoxMouse_Power %p\n", devExt));
    768861
    769862    powerType = irpStack->Parameters.Power.Type;
     
    904997    devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    905998
    906     //dprintf(("VBoxMouse_ServiceCallback\n"));
    907 
    908999// VBOX start
     1000    // dprintf(("VBoxMouse_ServiceCallback: devExt = %p, reqSC = %p\n", devExt, devExt->reqSC));
     1001
    9091002    VMMDevReqMouseStatus *req = devExt->reqSC;
    910 
    911     dprintf(("VBoxMouse::VBoxMouse_ServiceCallback: req = %p\n", req));
    9121003
    9131004    if (req)
  • trunk/src/VBox/Additions/WINNT/MouseFilter/VBoxMouse.h

    r4071 r5083  
    139139    VMMDevReqMouseStatus *reqSC;
    140140
    141     BOOLEAN HostInformed;
     141    BOOLEAN HostMouse;
    142142// VBOX end
    143143
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette