Index: trunk/include/VBox/VBoxGuest.h
===================================================================
--- trunk/include/VBox/VBoxGuest.h	(revision 37220)
+++ trunk/include/VBox/VBoxGuest.h	(revision 37221)
@@ -354,4 +354,9 @@
 #endif /* VBOX_WITH_HGCM */
 
+#ifdef RT_OS_WINDOWS
+# ifdef IN_RING0
+#  define VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_EVENT   VBOXGUEST_IOCTL_CODE_(30, sizeof(PKEVENT))
+# endif
+#endif
 
 #ifdef RT_OS_OS2
Index: trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMF.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMF.h	(revision 37220)
+++ trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMF.h	(revision 37221)
@@ -56,4 +56,5 @@
     VMMDevReqMouseStatus       *pSCReq;              /* Preallocated request to use in pfnServiceCB */
 
+    IO_REMOVE_LOCK RemoveLock;
 } VBOXMOUSE_DEVEXT, *PVBOXMOUSE_DEVEXT;
 
@@ -76,3 +77,5 @@
 VOID VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt);
 
+VOID VBoxDrvNotifyServiceCB(PVBOXMOUSE_DEVEXT pDevExt, PMOUSE_INPUT_DATA InputDataStart, PMOUSE_INPUT_DATA InputDataEnd, PULONG  InputDataConsumed);
+
 #endif /*VBOXMF_H*/
Index: trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFDriver.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFDriver.cpp	(revision 37220)
+++ trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFDriver.cpp	(revision 37221)
@@ -20,4 +20,5 @@
 #include <VBox/VBoxGuestLib.h>
 #include <iprt/initterm.h>
+#include <iprt/assert.h>
 
 #ifdef ALLOC_PRAGMA
@@ -63,4 +64,6 @@
 }
 
+#define VBOXUSB_RLTAG 'LRBV'
+
 NTSTATUS VBoxDrvAddDevice(IN PDRIVER_OBJECT Driver, IN PDEVICE_OBJECT PDO)
 {
@@ -82,7 +85,19 @@
     RtlZeroMemory(pDevExt, sizeof(VBOXMOUSE_DEVEXT));
 
+    IoInitializeRemoveLock(&pDevExt->RemoveLock, VBOXUSB_RLTAG, 1, 100);
+
+    rc = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt);
+    if (!NT_SUCCESS(rc))
+    {
+        WARN(("IoAcquireRemoveLock failed with %#x", rc));
+        IoDeleteDevice(pDO);
+        return rc;
+    }
+
     pDOParent = IoAttachDeviceToDeviceStack(pDO, PDO);
     if (!pDOParent)
     {
+        IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);
+
         WARN(("IoAttachDeviceToDeviceStack failed"));
         IoDeleteDevice(pDO);
@@ -105,9 +120,7 @@
 NTSTATUS VBoxIrpPassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 {
-    PIO_STACK_LOCATION pStack;
-    PVBOXMOUSE_DEVEXT pDevExt;
-    LOGF_ENTER();
-
-    pStack = IoGetCurrentIrpStackLocation(Irp);
+    PVBOXMOUSE_DEVEXT pDevExt;
+    LOGF_ENTER();
+
     pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
 
@@ -127,31 +140,5 @@
     pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
 
-    if (pDevExt->pSCReq)
-    {
-        int rc = VbglGRPerform(&pDevExt->pSCReq->header);
-
-        if (RT_SUCCESS(rc))
-        {
-            if (pDevExt->pSCReq->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
-            {
-                PMOUSE_INPUT_DATA pData = InputDataStart;
-                while (pData<InputDataEnd)
-                {
-                    pData->LastX = pDevExt->pSCReq->pointerXPos;
-                    pData->LastY = pDevExt->pSCReq->pointerYPos;
-                    pData->Flags = MOUSE_MOVE_ABSOLUTE;
-                    pData++;
-                }
-            }
-        }
-        else
-        {
-            WARN(("VbglGRPerform failed with rc=%#x", rc));
-        }
-    }
-
-    /* Call original callback */
-    pDevExt->OriginalConnectData.pfnServiceCB(pDevExt->OriginalConnectData.pDO,
-                                              InputDataStart, InputDataEnd, InputDataConsumed);
+    VBoxDrvNotifyServiceCB(pDevExt, InputDataStart, InputDataEnd, InputDataConsumed);
 
     LOGF_LEAVE();
@@ -219,4 +206,7 @@
         {
             LOGF(("IRP_MN_REMOVE_DEVICE"));
+
+            IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);
+
             VBoxDeviceRemoved(pDevExt);
 
Index: trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFInternal.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFInternal.cpp	(revision 37220)
+++ trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFInternal.cpp	(revision 37221)
@@ -19,4 +19,13 @@
 #include "VBoxMF.h"
 #include <VBox/VBoxGuestLib.h>
+#include <VBox/VBoxGuest.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+
+typedef struct VBOXGDC
+{
+    PDEVICE_OBJECT pDo;
+    PFILE_OBJECT pFo;
+} VBOXGDC, *PVBOXGDC;
 
 typedef struct _VBoxGlobalContext
@@ -27,7 +36,278 @@
     volatile LONG fHostInformed;
     volatile LONG fHostMouseFound;
+    VBOXGDC Gdc;
+    KSPIN_LOCK SyncLock;
+    KEVENT TerminateEvent;
+    KEVENT MouseEvent;
+    PKTHREAD pThread;
+    volatile PVBOXMOUSE_DEVEXT pCurrentDevExt;
+    LIST_ENTRY DevExtList;
+    MOUSE_INPUT_DATA LastReportedData;
 } VBoxGlobalContext;
 
-static VBoxGlobalContext g_ctx = {0, FALSE, FALSE, FALSE, FALSE};
+static VBoxGlobalContext g_ctx = {};
+
+NTSTATUS VBoxGdcInit()
+{
+    UNICODE_STRING UniName;
+    RtlInitUnicodeString(&UniName, VBOXGUEST_DEVICE_NAME_NT);
+    NTSTATUS Status = IoGetDeviceObjectPointer(&UniName, FILE_ALL_ACCESS, &g_ctx.Gdc.pFo, &g_ctx.Gdc.pDo);
+    if (!NT_SUCCESS(Status))
+    {
+        WARN(("IoGetDeviceObjectPointer failed Status(0x%x)", Status));
+        memset(&g_ctx.Gdc, 0, sizeof (g_ctx.Gdc));
+    }
+    return Status;
+}
+
+BOOLEAN VBoxGdcIsInitialized()
+{
+    return !!g_ctx.Gdc.pDo;
+}
+
+NTSTATUS VBoxGdcTerm()
+{
+    if (!g_ctx.Gdc.pFo)
+        return STATUS_SUCCESS;
+    /* this will dereference device object as well */
+    ObDereferenceObject(g_ctx.Gdc.pFo);
+    return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxGdcSubmitAsync(ULONG uCtl, PVOID pvBuffer, SIZE_T cbBuffer, PKEVENT pEvent, PIO_STATUS_BLOCK pIoStatus)
+{
+    NTSTATUS Status;
+    PIRP pIrp;
+    KIRQL Irql = KeGetCurrentIrql();
+    Assert(Irql == PASSIVE_LEVEL);
+
+    pIrp = IoBuildDeviceIoControlRequest(uCtl, g_ctx.Gdc.pDo, NULL, 0, NULL, 0, TRUE, pEvent, pIoStatus);
+    if (!pIrp)
+    {
+        WARN(("IoBuildDeviceIoControlRequest failed!!\n"));
+        pIoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
+        pIoStatus->Information = 0;
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    PIO_STACK_LOCATION pSl = IoGetNextIrpStackLocation(pIrp);
+    pSl->Parameters.Others.Argument1 = (PVOID)pvBuffer;
+    pSl->Parameters.Others.Argument2 = (PVOID)cbBuffer;
+    Status = IoCallDriver(g_ctx.Gdc.pDo, pIrp);
+
+    return Status;
+}
+
+static NTSTATUS vboxGdcSubmit(ULONG uCtl, PVOID pvBuffer, SIZE_T cbBuffer)
+{
+    IO_STATUS_BLOCK IoStatus = {0};
+    KEVENT Event;
+    NTSTATUS Status;
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    Status = vboxGdcSubmitAsync(uCtl, pvBuffer, cbBuffer, &Event, &IoStatus);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        Status = IoStatus.Status;
+    }
+
+    return Status;
+}
+
+/* overwrites the previously set one, can be NULL to clear the event */
+NTSTATUS VBoxGdcSetMouseNotifyEvent(PKEVENT pEvent)
+{
+    if (!VBoxGdcIsInitialized())
+    {
+        WARN(("Guest Device Communication not initialized"));
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    NTSTATUS Status = vboxGdcSubmit(VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_EVENT, pEvent, sizeof (pEvent));
+    if (!NT_SUCCESS(Status))
+    {
+        WARN(("vboxGdcSubmit failed Status(0x%x)", Status));
+    }
+    return Status;
+}
+
+/**
+ * helper function used for system thread creation
+ */
+static NTSTATUS vboxCreateSystemThread(PKTHREAD *ppThread, PKSTART_ROUTINE pfnStartRoutine, PVOID pvStartContext)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
+
+    InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+
+    HANDLE hThread;
+    NTSTATUS Status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &ObjectAttributes, NULL, NULL, (PKSTART_ROUTINE)pfnStartRoutine, pvStartContext);
+    Assert(Status == STATUS_SUCCESS);
+    if (Status == STATUS_SUCCESS)
+    {
+        Status = ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)ppThread, NULL);
+        Assert(Status == STATUS_SUCCESS);
+        ZwClose(hThread);
+        if (Status == STATUS_SUCCESS)
+        {
+            return STATUS_SUCCESS;
+        }
+
+        /* @todo: how would we fail in this case ?*/
+    }
+    return Status;
+}
+
+static VOID vboxMouseEventPollerThread(PVOID pvContext)
+{
+    PKEVENT apEvents[] = {&g_ctx.MouseEvent, &g_ctx.TerminateEvent};
+    NTSTATUS Status;
+    while (1)
+    {
+        Status = KeWaitForMultipleObjects(RT_ELEMENTS(apEvents), (PVOID*)apEvents,
+                WaitAny, Executive, KernelMode, FALSE /* BOOLEAN  Alertable */,
+                NULL /* PLARGE_INTEGER Timeout */,
+                NULL /* PKWAIT_BLOCK WaitBlockArray */
+                );
+        Assert(NT_SUCCESS(Status));
+
+        if (Status != STATUS_WAIT_0)
+        {
+            /* terminate event */
+            Assert(Status == STATUS_WAIT_1);
+            break;
+        }
+
+        ULONG InputDataConsumed = 0;
+        PVBOXMOUSE_DEVEXT pDevExt = (PVBOXMOUSE_DEVEXT)ASMAtomicUoReadPtr((void * volatile *)&g_ctx.pCurrentDevExt);
+        if (pDevExt)
+        {
+#define VBOXMOUSE_POLLERTAG 'PMBV'
+            Status = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt);
+            if (NT_SUCCESS(Status))
+            {
+                VBoxDrvNotifyServiceCB(pDevExt, &g_ctx.LastReportedData, &g_ctx.LastReportedData + 1, &InputDataConsumed);
+                IoReleaseRemoveLock(&pDevExt->RemoveLock, pDevExt);
+            }
+            else
+            {
+                WARN(("IoAcquireRemoveLock failed, Status (0x%x)", Status));
+            }
+        }
+        else
+        {
+            WARN(("no current pDevExt specified"));
+        }
+    }
+
+    PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
+static NTSTATUS vboxNewProtInit(PVBOXMOUSE_DEVEXT pCurrentDevExt)
+{
+    NTSTATUS Status = VBoxGdcInit();
+    if (NT_SUCCESS(Status))
+    {
+        KeInitializeSpinLock(&g_ctx.SyncLock);
+        KeInitializeEvent(&g_ctx.TerminateEvent, NotificationEvent, FALSE);
+        KeInitializeEvent(&g_ctx.MouseEvent, SynchronizationEvent, FALSE);
+
+        Status = VBoxGdcSetMouseNotifyEvent(&g_ctx.MouseEvent);
+        if (NT_SUCCESS(Status))
+        {
+            Status = vboxCreateSystemThread(&g_ctx.pThread, vboxMouseEventPollerThread, NULL);
+            if (NT_SUCCESS(Status))
+            {
+                g_ctx.pCurrentDevExt = pCurrentDevExt;
+                return STATUS_SUCCESS;
+            }
+            g_ctx.pThread = NULL;
+            NTSTATUS tmpStatus = VBoxGdcSetMouseNotifyEvent(NULL);
+            Assert(NT_SUCCESS(tmpStatus));
+        }
+    }
+
+    return Status;
+}
+
+static BOOLEAN vboxNewProtIsSupported()
+{
+    return !!g_ctx.pThread;
+}
+
+static NTSTATUS vboxNewProtTerm()
+{
+    KeSetEvent(&g_ctx.TerminateEvent, 0, FALSE);
+    NTSTATUS Status = KeWaitForSingleObject(g_ctx.pThread, Executive, KernelMode, FALSE, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        WARN(("KeWaitForSingleObject failed, Status (0x%x)", Status));
+        return Status;
+    }
+
+    Status = VBoxGdcSetMouseNotifyEvent(NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        WARN(("VBoxGdcSetMouseNotifyEvent failed, Status (0x%x)", Status));
+        return Status;
+    }
+
+    ObDereferenceObject(g_ctx.pThread);
+    g_ctx.pThread = NULL;
+
+    return Status;
+}
+
+static NTSTATUS vboxNewProtSetCurrentDevExt(PVBOXMOUSE_DEVEXT pCurrentDevExt)
+{
+    ASMAtomicWritePtrVoid((void * volatile *)&g_ctx.pCurrentDevExt, pCurrentDevExt);
+    return STATUS_SUCCESS;
+}
+
+VOID VBoxDrvNotifyServiceCB(PVBOXMOUSE_DEVEXT pDevExt, PMOUSE_INPUT_DATA InputDataStart, PMOUSE_INPUT_DATA InputDataEnd, PULONG  InputDataConsumed)
+{
+    KIRQL Irql;
+    /* we need to avoid concurrency between the poller thread and our ServiceCB.
+     * this is perhaps not the best way of doing things, but the most easiest to avoid concurrency
+     * and to ensure the pfnServiceCB is invoked at DISPATCH_LEVEL */
+    KeAcquireSpinLock(&g_ctx.SyncLock, &Irql);
+    if (pDevExt->pSCReq)
+    {
+        int rc = VbglGRPerform(&pDevExt->pSCReq->header);
+
+        if (RT_SUCCESS(rc))
+        {
+            if (pDevExt->pSCReq->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
+            {
+                PMOUSE_INPUT_DATA pData = InputDataStart;
+                while (pData<InputDataEnd)
+                {
+                    pData->LastX = pDevExt->pSCReq->pointerXPos;
+                    pData->LastY = pDevExt->pSCReq->pointerYPos;
+                    pData->Flags = MOUSE_MOVE_ABSOLUTE;
+                    if (vboxNewProtIsSupported())
+                        pData->Flags |= MOUSE_VIRTUAL_DESKTOP;
+                    pData++;
+                }
+
+                /* get the last data & cache it */
+                --pData;
+                g_ctx.LastReportedData.UnitId = pData->UnitId;
+            }
+        }
+        else
+        {
+            WARN(("VbglGRPerform failed with rc=%#x", rc));
+        }
+    }
+
+    /* Call original callback */
+    pDevExt->OriginalConnectData.pfnServiceCB(pDevExt->OriginalConnectData.pDO,
+                                              InputDataStart, InputDataEnd, InputDataConsumed);
+    KeReleaseSpinLock(&g_ctx.SyncLock, Irql);
+}
 
 static BOOLEAN vboxIsVBGLInited(void)
@@ -73,4 +353,6 @@
                 WARN(("VBGL init failed with rc=%#x", rc));
             }
+
+            vboxNewProtInit(pDevExt);
         }
     }
@@ -172,4 +454,7 @@
         {
             req->mouseFeatures = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
+            if (vboxNewProtIsSupported())
+                req->mouseFeatures |= VMMDEV_MOUSE_NEW_PROTOCOL;
+
             req->pointerXPos = 0;
             req->pointerYPos = 0;
@@ -260,4 +545,6 @@
     if (callCnt == 0)
     {
+        vboxNewProtTerm();
+
         if (vboxIsVBGLInited())
         {
Index: trunk/src/VBox/Additions/WINNT/Mouse/common/VBoxMouseLog.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Mouse/common/VBoxMouseLog.h	(revision 37220)
+++ trunk/src/VBox/Additions/WINNT/Mouse/common/VBoxMouseLog.h	(revision 37221)
@@ -19,4 +19,8 @@
 #ifndef VBOXMOUSELOG_H
 #define VBOXMOUSELOG_H
+
+#ifdef DEBUG_misha
+#include <iprt/assert.h>
+#endif
 
 #define VBOX_MOUSE_LOG_NAME "VBoxMouse"
@@ -44,4 +48,10 @@
     } while (0)
 
+#ifdef DEBUG_misha
+# define BREAK_WARN() AssertFailed()
+#else
+# define BREAK_WARN() do {} while(0)
+#endif
+
 #define WARN(_a)                                                                  \
     do                                                                            \
@@ -50,4 +60,5 @@
         Log(_a);                                                                  \
         Log((VBOX_MOUSE_LOG_SUFFIX_FMT VBOX_MOUSE_LOG_SUFFIX_PARMS));             \
+        BREAK_WARN(); \
     } while (0)
 
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp	(revision 37220)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp	(revision 37221)
@@ -51,4 +51,5 @@
 static NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
 static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
 static NTSTATUS vboxguestwinSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
 static NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp);
@@ -88,5 +89,4 @@
 /** The detected Windows version. */
 winVersion_t g_winVersion;
-
 
 /**
@@ -166,5 +166,5 @@
         pDrvObj->MajorFunction[IRP_MJ_CLOSE]                   = vboxguestwinClose;
         pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]          = vboxguestwinIOCtl;
-        pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vboxguestwinIOCtl;
+        pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vboxguestwinInternalIOCtl;
         pDrvObj->MajorFunction[IRP_MJ_SHUTDOWN]                = vboxguestwinShutdown;
         pDrvObj->MajorFunction[IRP_MJ_READ]                    = vboxguestwinNotSupportedStub;
@@ -221,4 +221,6 @@
             pDevExt = (PVBOXGUESTDEVEXT)pDeviceObject->DeviceExtension;
             RtlZeroMemory(pDevExt, sizeof(VBOXGUESTDEVEXT));
+
+            KeInitializeSpinLock(&pDevExt->win.s.MouseEventAccessLock);
 
             pDevExt->win.s.pDeviceObject = pDeviceObject;
@@ -795,4 +797,56 @@
 }
 
+/* we do not want to allow some IOCTLs to be originated from user mode,
+ * this is why we have a separate vboxguestwinInternalIOCtl for internal IOCTLs */
+NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+    PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+    unsigned int uCmd = (unsigned int)pStack->Parameters.DeviceIoControl.IoControlCode;
+    BOOLEAN fProcessed = FALSE;
+    unsigned Info = 0;
+
+    switch (uCmd)
+    {
+        case VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_EVENT:
+        {
+            PVOID pvBuf = pStack->Parameters.Others.Argument1;
+            size_t cbData = (size_t)pStack->Parameters.Others.Argument2;
+            fProcessed = true;
+            if (cbData != sizeof (PKEVENT))
+            {
+                AssertFailed();
+                Status = STATUS_INVALID_PARAMETER;
+                break;
+            }
+
+            KIRQL OldIrql;
+            /* we need a lock here to avoid concurrency with the set event functionality */
+            KeAcquireSpinLock(&pDevExt->win.s.MouseEventAccessLock, &OldIrql);
+            pDevExt->win.s.pMouseEvent =  (PKEVENT)pvBuf;
+            KeReleaseSpinLock(&pDevExt->win.s.MouseEventAccessLock, OldIrql);
+
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        default:
+            break;
+    }
+
+
+    if (fProcessed)
+    {
+        pIrp->IoStatus.Status = Status;
+        pIrp->IoStatus.Information = Info;
+
+        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+        return Status;
+    }
+
+    return vboxguestwinIOCtl(pDevObj, pIrp);
+}
+
 
 /**
@@ -879,4 +933,19 @@
     Log(("VBoxGuest::vboxguestwinGuestDpcHandler: pDevExt=0x%p\n", pDevExt));
 
+    /* test & reset the counter */
+    if (ASMAtomicXchgU32(&pDevExt->u32MousePosChangedSeq, 0))
+    {
+        Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+        /* we need a lock here to avoid concurrency with the set event ioctl handler thread,
+         * i.e. to prevent the event from destroyed while we're using it */
+        KeAcquireSpinLockAtDpcLevel(&pDevExt->win.s.MouseEventAccessLock);
+        PKEVENT pEvent = pDevExt->win.s.pMouseEvent;
+        if (pEvent)
+        {
+            KeSetEvent(pEvent, 0, FALSE);
+        }
+        KeReleaseSpinLockFromDpcLevel(&pDevExt->win.s.MouseEventAccessLock);
+    }
+
     /* Process the wake-up list we were asked by the scheduling a DPC
      *  in vboxguestwinIsrHandler(). */
@@ -910,5 +979,5 @@
         Log(("VBoxGuest::vboxguestwinGuestIsrHandler: IRQ was taken! pInterrupt = 0x%p, pDevExt = 0x%p\n",
              pInterrupt, pDevExt));
-        if (!RTListIsEmpty(&pDevExt->WakeUpList))
+        if (ASMAtomicUoReadU32(&pDevExt->u32MousePosChangedSeq) || !RTListIsEmpty(&pDevExt->WakeUpList))
         {
             Log(("VBoxGuest::vboxguestwinGuestIsrHandler: Requesting DPC ...\n"));
@@ -921,6 +990,5 @@
 
 /*
- * Overridden routine for mouse polling events.  Not
- * used at the moment on Windows.
+ * Overridden routine for mouse polling events.
  *
  * @param pDevExt     Device extension structure.
@@ -929,4 +997,7 @@
 {
     NOREF(pDevExt);
+    /* nothing to do here - i.e. since we can not KeSetEvent from ISR level,
+     * we rely on the pDevExt->u32MousePosChangedSeq to be set to a non-zero value on a mouse event
+     * and queue the DPC in our ISR routine in that case doing KeSetEvent from the DPC routine */
 }
 
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h	(revision 37220)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h	(revision 37221)
@@ -116,4 +116,9 @@
       * for handling kernel IOCtls. */
     PVBOXGUESTSESSION pKernelSession;
+
+
+    KSPIN_LOCK MouseEventAccessLock;
+    /* event to be signalled on mouse event arrival from host */
+    PKEVENT pMouseEvent;
 } VBOXGUESTDEVEXTWIN, *PVBOXGUESTDEVEXTWIN;
 
