VirtualBox

儲存庫 vbox 的更動 68556


忽略:
時間撮記:
2017-8-31 下午12:09:59 (7 年 以前)
作者:
vboxsync
訊息:

merging vbglioc r117707: Mouse/NT5: Use always Vbgl APIs to talking to the driver. Must do lazy registration of the event callback as we don't know when VBoxGuest will show up.

位置:
trunk/src/VBox/Additions/WINNT/Mouse/NT5
檔案:
修改 3 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMF.h

    r62683 r68556  
    11/* $Id$ */
    22/** @file
    3  * VBox Mouse filter header
     3 * VBox Mouse Filter Driver - Internal Header.
    44 */
    55
     
    7474
    7575/* 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();
     76void VBoxMouFltInitGlobals(void);
     77void VBoxMouFltDeleteGlobals(void);
     78void VBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt);
     79void VBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt);
     80void VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt);
    8281
    8382VOID 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  
    3030    NOREF(RegistryPath);
    3131    PAGED_CODE();
     32LOGREL(("DriverEntry:"));
    3233
    3334    int irc = RTR0Init(0);
     
    4243    DriverObject->DriverExtension->AddDevice = VBoxDrvAddDevice;
    4344
    44     for (int i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; ++i)
    45     {
     45    for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
    4646        DriverObject->MajorFunction[i] = VBoxIrpPassthrough;
    47     }
    48 
    4947    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();
    5952    LOGF_LEAVE();
    6053    return STATUS_SUCCESS;
     
    6760    LOGF_ENTER();
    6861
    69     NTSTATUS tmpStatus = VBoxNewProtTerm();
    70     if (!NT_SUCCESS(tmpStatus))
    71     {
    72         WARN(("VBoxNewProtTerm failed Status (0x%x)", tmpStatus));
    73     }
    74 
    75 
     62    VBoxMouFltDeleteGlobals();
    7663    RTR0Term();
    7764}
  • trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFInternal.cpp

    r68550 r68556  
    11/* $Id$ */
    22/** @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...
    46 */
    57
     
    1618 */
    1719
     20/*********************************************************************************************************************************
     21*   Header Files                                                                                                                 *
     22*********************************************************************************************************************************/
    1823#undef WIN9X_COMPAT_SPINLOCK
    1924#define WIN9X_COMPAT_SPINLOCK /* Avoid duplicate _KeInitializeSpinLock@4 error on x86. */
     
    2328#include <VBox/VBoxGuest.h>
    2429#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*********************************************************************************************************************************/
    3236typedef struct _VBoxGlobalContext
    3337{
     
    3741    volatile LONG fHostInformed;
    3842    volatile LONG fHostMouseFound;
    39     VBOXGDC Gdc;
     43    VBGLIDCHANDLE IdcHandle;
    4044    KSPIN_LOCK SyncLock;
    4145    volatile PVBOXMOUSE_DEVEXT pCurrentDevExt;
    4246    LIST_ENTRY DevExtList;
    43     BOOLEAN fIsNewProtEnabled;
     47    bool fIsNewProtEnabled;
    4448    MOUSE_INPUT_DATA LastReportedData;
    4549} VBoxGlobalContext;
    4650
     51
     52/*********************************************************************************************************************************
     53*   Global Variables                                                                                                             *
     54*********************************************************************************************************************************/
    4755static VBoxGlobalContext g_ctx = {};
    4856
    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 */
     61void 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 */
     72void VBoxMouFltDeleteGlobals(void)
     73{
     74    Assert(IsListEmpty(&g_ctx.DevExtList));
     75}
     76
     77
     78/**
     79 * @callback_method_impl{FNVBOXGUESTMOUSENOTIFY}
     80 */
     81static DECLCALLBACK(void) vboxNewProtMouseEventCb(void *pvUser)
     82{
     83    RT_NOREF(pvUser);
    12184    PVBOXMOUSE_DEVEXT pDevExt = (PVBOXMOUSE_DEVEXT)ASMAtomicUoReadPtr((void * volatile *)&g_ctx.pCurrentDevExt);
    12285    if (pDevExt)
    12386    {
    124 #define VBOXMOUSE_POLLERTAG 'PMBV'
    12587        NTSTATUS Status = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt);
    12688        if (NT_SUCCESS(Status))
     
    13193        }
    13294        else
    133         {
    13495            WARN(("IoAcquireRemoveLock failed, Status (0x%x)", Status));
    135         }
    13696    }
    13797    else
    138     {
    13998        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 */
     110static 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 */
     130static void vboxNewProtTerm(void)
    189131{
    190132    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 */
     147static void vboxNewProtDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt)
     148{
     149    /*
     150     * Always add the device to the list.
     151     */
    220152    KIRQL Irql;
    221153    KeAcquireSpinLock(&g_ctx.SyncLock, &Irql);
     154
    222155    InsertHeadList(&g_ctx.DevExtList, &pDevExt->ListEntry);
     156
    223157    /* 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    {
    227161        /* ensure the object is not deleted while it is being used by a poller thread */
    228162        ObReferenceObject(pDevExt->pdoSelf);
    229163    }
     164
    230165    KeReleaseSpinLock(&g_ctx.SyncLock, Irql);
    231166
    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 */
     178static void vboxNewProtDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt)
     179{
     180    /*
     181     * Remove the device from the list.
     182     */
    245183    KIRQL Irql;
    246     NTSTATUS Status = STATUS_SUCCESS;
    247184    KeAcquireSpinLock(&g_ctx.SyncLock, &Irql);
     185
    248186    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))
    252190        ObDereferenceObject(pDevExt->pdoSelf);
    253         g_ctx.pCurrentDevExt = NULL;
    254     }
    255191
    256192    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
     195VOID VBoxDrvNotifyServiceCB(PVBOXMOUSE_DEVEXT pDevExt, PMOUSE_INPUT_DATA InputDataStart, PMOUSE_INPUT_DATA InputDataEnd,
     196                            PULONG InputDataConsumed)
     197{
    264198    /* we need to avoid concurrency between the poller thread and our ServiceCB.
    265199     * this is perhaps not the best way of doing things, but the most easiest to avoid concurrency
    266200     * and to ensure the pfnServiceCB is invoked at DISPATCH_LEVEL */
     201    KIRQL Irql;
    267202    KeAcquireSpinLock(&g_ctx.SyncLock, &Irql);
    268203    if (pDevExt->pSCReq)
    269204    {
    270205        int rc = VbglGRPerform(&pDevExt->pSCReq->header);
    271 
    272206        if (RT_SUCCESS(rc))
    273207        {
     
    275209            {
    276210                PMOUSE_INPUT_DATA pData = InputDataStart;
    277                 while (pData<InputDataEnd)
     211                while (pData < InputDataEnd)
    278212                {
    279213                    pData->LastX = pDevExt->pSCReq->pointerXPos;
    280214                    pData->LastY = pDevExt->pSCReq->pointerYPos;
    281215                    pData->Flags = MOUSE_MOVE_ABSOLUTE;
    282                     if (vboxNewProtIsEnabled())
     216                    if (g_ctx.fIsNewProtEnabled)
    283217                        pData->Flags |= MOUSE_VIRTUAL_DESKTOP;
    284218                    pData++;
     
    292226        else
    293227        {
    294             WARN(("VbglGRPerform failed with rc=%#x", rc));
     228            WARN(("VbglGRPerform failed with rc=%Rrc", rc));
    295229        }
    296230    }
    297231
    298232    /* Call original callback */
    299     pDevExt->OriginalConnectData.pfnServiceCB(pDevExt->OriginalConnectData.pDO,
    300                                               InputDataStart, InputDataEnd, InputDataConsumed);
     233    pDevExt->OriginalConnectData.pfnServiceCB(pDevExt->OriginalConnectData.pDO, InputDataStart, InputDataEnd, InputDataConsumed);
    301234    KeReleaseSpinLock(&g_ctx.SyncLock, Irql);
    302235}
     
    307240}
    308241
    309 static BOOLEAN vboxIsVBGLInitFailed (void)
     242static BOOLEAN vboxIsVBGLInitFailed(void)
    310243{
    311244   return InterlockedCompareExchange(&g_ctx.fVBGLInitFailed, TRUE, TRUE) == TRUE;
     
    322255}
    323256
    324 VOID VBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt)
     257void VBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt)
    325258{
    326259    LOGF_ENTER();
    327     LONG callCnt = InterlockedIncrement(&g_ctx.cDevicesStarted);
     260    LONG cCalls = InterlockedIncrement(&g_ctx.cDevicesStarted);
    328261
    329262    /* 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
    332268        if (!vboxIsVBGLInited() && !vboxIsVBGLInitFailed())
    333269        {
     
    337273                InterlockedExchange(&g_ctx.fVBGLInited, TRUE);
    338274                LOG(("VBGL init OK"));
     275                vboxNewProtLazyRegister();
    339276            }
    340277            else
    341278            {
    342                 InterlockedExchange (&g_ctx.fVBGLInitFailed, TRUE);
    343                 WARN(("VBGL init failed with rc=%#x", rc));
     279                InterlockedExchange(&g_ctx.fVBGLInitFailed, TRUE);
     280                WARN(("VBGL init failed with rc=%Rrc", rc));
    344281            }
    345282        }
     
    414351             * For this device the filter will query absolute mouse coords from the host.
    415352             */
     353            /** @todo r=bird: The g_ctx.fHostMouseFound needs to be cleared
     354             *        when the device is removed... */
    416355            InterlockedExchange(&g_ctx.fHostMouseFound, TRUE);
    417356
     
    427366}
    428367
    429 VOID VBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt)
     368void VBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt)
    430369{
    431370    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
    435416        WARN(("!vboxIsVBGLInited"));
    436         return;
    437     }
    438 
    439     /* Inform host we support absolute coordinates */
    440     if (pDevExt->bHostMouse && !vboxIsHostInformed())
     417    LOGF_LEAVE();
     418}
     419
     420VOID 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())
    441428    {
    442429        VMMDevReqMouseStatus *req = NULL;
    443430        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             else
    461             {
    462                 WARN(("VbglGRPerform failed with rc=%#x", rc));
    463             }
    464 
    465             VbglGRFree(&req->header);
    466         }
    467         else
    468         {
    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         else
    485         {
    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 anymore
    503         VMMDevReqMouseStatus *req = NULL;
    504 
    505         int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
    506 
    507431        if (RT_SUCCESS(rc))
    508432        {
     
    512436
    513437            rc = VbglGRPerform(&req->header);
    514 
    515438            if (RT_FAILURE(rc))
    516             {
    517                 WARN(("VbglGRPerform failed with rc=%#x", rc));
    518             }
     439                WARN(("VbglGRPerform failed with rc=%Rrc", rc));
    519440
    520441            VbglGRFree(&req->header);
    521442        }
    522443        else
    523         {
    524             WARN(("VbglGRAlloc failed with rc=%#x", rc));
    525         }
     444            WARN(("VbglGRAlloc failed with rc=%Rrc", rc));
    526445
    527446        InterlockedExchange(&g_ctx.fHostInformed, FALSE);
    528447    }
    529448
     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);
    530463    if (pSCReq)
    531     {
    532464        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)
    540473    {
    541474        if (vboxIsVBGLInited())
     
    544477            InterlockedExchange(&g_ctx.fVBGLInitFailed, TRUE);
    545478
     479            vboxNewProtTerm();
    546480            VbglR0TerminateClient();
    547481
     
    554488    LOGF_LEAVE();
    555489}
     490
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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