Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 50912)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 50913)
@@ -519,5 +519,5 @@
     Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
-    PVBOXMP_CRSHGSMITRANSPORT pCon;
+    PVBOXMP_CRSHGSMITRANSPORT pCon = (PVBOXMP_CRSHGSMITRANSPORT)pvContext;
     PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
     VBOXCMDVBVA_CRCMD_CMD *pCmd;
@@ -1031,5 +1031,5 @@
     }
 
-#if 1 /*def DEBUG_misha*/
+#ifndef DEBUG_misha
     g_VBoxMpCrHostCaps &= ~CR_VBOX_CAP_CMDVBVA;
 #endif
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp	(revision 50912)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp	(revision 50913)
@@ -174,5 +174,5 @@
 static int vboxCmdVbvaCtlSubmitAsync(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, VBOXCMDVBVA_CTL * pCtl, FNVBOXSHGSMICMDCOMPLETION pfnCompletion, void *pvCompletion)
 {
-    const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepAsynch(&pHGSMICtx->heapCtx, pCtl, pfnCompletion, pvCompletion, 0);
+    const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepAsynch(&pHGSMICtx->heapCtx, pCtl, pfnCompletion, pvCompletion, VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ);
     HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pHGSMICtx->heapCtx, pHdr);
     if (offCmd == HGSMIOFFSET_VOID)
@@ -293,6 +293,9 @@
     // LogFunc(("flags = 0x%08X\n", pCtx->pVBVA? pCtx->pVBVA->u32HostEvents: -1));
 
-    if (   pCtx->pVBVA
-        && (pCtx->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
+    Assert(pCtx->pVBVA);
+    /* we do not use u32HostEvents & VBVA_F_MODE_ENABLED,
+     * VBVA stays enabled once ENABLE call succeeds, until it is disabled with DISABLED call */
+//    if (   pCtx->pVBVA
+//        && (pCtx->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
     {
         uint32_t indexRecordNext;
@@ -366,4 +369,10 @@
 }
 
+DECLINLINE(bool) vboxVBVAExIsEntryInRangeOrEmpty(uint32_t u32First, uint32_t u32Entry, uint32_t u32Free)
+{
+    return vboxVBVAExIsEntryInRange(u32First, u32Entry, u32Free)
+            || (    u32First == u32Entry
+                 && u32Entry == u32Free);
+}
 #ifdef DEBUG
 
@@ -371,10 +380,10 @@
 {
     VBVABUFFER *pVBVA = pCtx->pVBVA;
-    if (!vboxVBVAExIsEntryInRange(pCtx->indexRecordFirstUncompleted, pVBVA->indexRecordFirst, pVBVA->indexRecordFree))
+    if (!vboxVBVAExIsEntryInRangeOrEmpty(pCtx->indexRecordFirstUncompleted, pVBVA->indexRecordFirst, pVBVA->indexRecordFree))
     {
         WARN(("invalid record set"));
     }
 
-    if (!vboxVBVAExIsEntryInRange(pCtx->off32DataUncompleted, pVBVA->off32Data, pVBVA->off32Free))
+    if (!vboxVBVAExIsEntryInRangeOrEmpty(pCtx->off32DataUncompleted, pVBVA->off32Data, pVBVA->off32Free))
     {
         WARN(("invalid data set"));
@@ -904,8 +913,10 @@
     int rc = VINF_SUCCESS;
 
+    Assert(pCmd->u32FenceID);
+
     pCmd->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
     pVbva->u32FenceSubmitted = pCmd->u32FenceID;
 
-    if (VBoxVBVAExGetSize(&pVbva->Vbva) > cbCmd)
+    if (VBoxVBVAExGetSize(&pVbva->Vbva) < cbCmd)
     {
         WARN(("buffer does not fit the vbva buffer, we do not support splitting buffers"));
@@ -1073,5 +1084,5 @@
 }
 
-
+#if 0
 static uint32_t vboxCVDdiSysMemElBuild(VBOXCMDVBVA_SYSMEMEL *pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages)
 {
@@ -1103,9 +1114,5 @@
     VBOXCMDVBVA_SYSMEMEL *pEl = pCmd->aSysMem;
 
-    if (cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
-    {
-        WARN(("cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER)"));
-        goto done;
-    }
+    Assert(cbBuffer >= sizeof (VBOXCMDVBVA_PAGING_TRANSFER));
 
     cbBuffer -= RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aSysMem);
@@ -1116,8 +1123,27 @@
     }
 
-done:
     *pcPagesWritten = cInitPages - cPages;
     return cbInitBuffer - cbBuffer;
 }
+#endif
+
+uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten)
+{
+    uint32_t cbInitBuffer = cbBuffer;
+    uint32_t i = 0;
+    VBOXCMDVBVAPAGEIDX *pPageNumbers = pCmd->aPageNumbers;
+
+    cbBuffer -= RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aPageNumbers);
+
+    for (; i < cPages && cbBuffer >= sizeof (*pPageNumbers); ++i, cbBuffer -= sizeof (*pPageNumbers))
+    {
+        pPageNumbers[i] = (VBOXCMDVBVAPAGEIDX)(MmGetMdlPfnArray(pMdl)[iPfn + i]);
+    }
+
+    *pcPagesWritten = i;
+    Assert(cbInitBuffer - cbBuffer == RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aPageNumbers[i]));
+    return cbInitBuffer - cbBuffer;
+}
+
 
 int vboxCmdVbvaConConnect(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
@@ -1144,5 +1170,8 @@
         rc = pConnect->Hdr.i32Result;
         if (RT_SUCCESS(rc))
+        {
+            Assert(pConnect->Connect.Hdr.u32CmdClientId);
             *pu32ClientID = pConnect->Connect.Hdr.u32CmdClientId;
+        }
         else
             WARN(("VBOXCMDVBVA3DCTL_TYPE_CONNECT Disable failed %d", rc));
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 50912)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 50913)
@@ -1979,6 +1979,11 @@
             memset(pCaps, 0, sizeof (*pCaps));
 #endif
-
-            pCaps->HighestAcceptableAddress.QuadPart = ~((uintptr_t)0);
+            pCaps->HighestAcceptableAddress.LowPart = ~0UL;
+#ifdef RT_ARCH_AMD64
+            /* driver talks to host in terms of page numbers when reffering to RAM
+             * we use uint32_t field to pass page index to host, so max would be (~0UL) << PAGE_OFFSET,
+             * which seems quite enough */
+            pCaps->HighestAcceptableAddress.HighPart = PAGE_OFFSET_MASK;
+#endif
             pCaps->MaxPointerWidth  = VBOXWDDM_C_POINTER_MAX_WIDTH;
             pCaps->MaxPointerHeight = VBOXWDDM_C_POINTER_MAX_HEIGHT;
@@ -3095,20 +3100,5 @@
     {
         cbCmd = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset;
-        if (cbCmd < sizeof (VBOXCMDVBVA_HDR))
-        {
-            WARN(("DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXCMDVBVA_HDR) (%d)",
-                    pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset,
-                    pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset,
-                    sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
-            return STATUS_INVALID_PARAMETER;
-        }
-
-        if (cbCmd > 0xffff)
-        {
-            WARN(("cbCmd too big"));
-            return STATUS_INVALID_PARAMETER;
-        }
-
-        if (VBOXWDDM_DUMMY_DMABUFFER_SIZE == cbCmd)
+        if (!cbCmd || VBOXWDDM_DUMMY_DMABUFFER_SIZE == cbCmd)
         {
             SysMem.Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_NOPCMD;
@@ -3119,18 +3109,34 @@
         else
         {
+            if (cbCmd < sizeof (VBOXCMDVBVA_HDR))
+            {
+                WARN(("DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXCMDVBVA_HDR) (%d)",
+                        pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset,
+                        pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset,
+                        sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            if (cbCmd > 0xffff)
+            {
+                WARN(("cbCmd too big"));
+                return STATUS_INVALID_PARAMETER;
+            }
+
             SysMem.Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_SYSMEMCMD;
             SysMem.Hdr.u8Flags = cbCmd & 0xff;
             SysMem.Hdr.u.u8PrimaryID = (cbCmd >> 8) & 0xff;
             SysMem.Hdr.u8State = VBOXCMDVBVA_STATE_SUBMITTED;
-            SysMem.phSysMem = pSubmitCommand->DmaBufferPhysicalAddress.QuadPart + pSubmitCommand->DmaBufferSubmissionStartOffset;
-            if (SysMem.phSysMem & PAGE_OFFSET_MASK)
+            if (pSubmitCommand->DmaBufferPhysicalAddress.QuadPart & PAGE_OFFSET_MASK)
             {
                 WARN(("command should be page aligned for now"));
                 return STATUS_INVALID_PARAMETER;
             }
+            SysMem.iPage = (VBOXCMDVBVAPAGEIDX)(pSubmitCommand->DmaBufferPhysicalAddress.QuadPart >> PAGE_SHIFT);
+
+            cbCmd = sizeof (SysMem);
         }
 
         pHdr = &SysMem.Hdr;
-        cbCmd = sizeof (SysMem);
     }
     else
@@ -3403,12 +3409,4 @@
     LOGF(("ENTER, context(0x%x)", hAdapter));
 
-    /* paging buffer transfer is nop for hostID allocations */
-    if (pBuildPagingBuffer->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
-    {
-        WARN(("pBuildPagingBuffer->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)", pBuildPagingBuffer->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
-        /* @todo: can this actually happen? what status to return? */
-        return STATUS_INVALID_PARAMETER;
-    }
-
     switch (pBuildPagingBuffer->Operation)
     {
@@ -3471,15 +3469,17 @@
             }
 
-            uint32_t cPages = (uint32_t)((pBuildPagingBuffer->Transfer.TransferSize + 0xfff) >> PAGE_SHIFT);
-            uint32_t cTotalPages = cPages;
+            Assert(!(pBuildPagingBuffer->Transfer.TransferSize & PAGE_OFFSET_MASK));
+            Assert(!(offVRAM & PAGE_OFFSET_MASK));
+            uint32_t cPages = (uint32_t)(pBuildPagingBuffer->Transfer.TransferSize >> PAGE_SHIFT);
+            Assert(cPages > pBuildPagingBuffer->MultipassOffset);
             cPages -= pBuildPagingBuffer->MultipassOffset;
-            uint32_t iFirstPage = pBuildPagingBuffer->Transfer.MdlOffset + pBuildPagingBuffer->MultipassOffset;
+            uint32_t iFirstPage = pBuildPagingBuffer->MultipassOffset;
             uint32_t cPagesWritten;
-            offVRAM += pBuildPagingBuffer->Transfer.TransferOffset + pBuildPagingBuffer->MultipassOffset;
+            offVRAM += pBuildPagingBuffer->Transfer.TransferOffset + (pBuildPagingBuffer->MultipassOffset << PAGE_SHIFT);
 
             pPaging->Alloc.u.offVRAM = offVRAM;
             if (fIn)
                 pPaging->Hdr.u8Flags |= VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN;
-            cbBuffer = VBoxCVDdiPTransferVRamSysBuildEls(pPaging, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaBufferPrivateDataSize, &cPagesWritten);
+            cbBuffer = VBoxCVDdiPTransferVRamSysBuildEls(pPaging, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaSize, &cPagesWritten);
             if (cPagesWritten != cPages)
                 pBuildPagingBuffer->MultipassOffset += cPagesWritten;
@@ -3500,4 +3500,5 @@
             /** @todo: add necessary bits */
             WARN(("Impl!"));
+            cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
             break;
         }
@@ -3510,4 +3511,5 @@
                 return STATUS_INVALID_PARAMETER;
             }
+            WARN(("Do we need to do anything here?"));
             break;
         }
@@ -3521,4 +3523,5 @@
     Assert(!cbPrivateData);
 
+    Assert(pBuildPagingBuffer->Operation == DXGK_OPERATION_DISCARD_CONTENT || cbBuffer);
     pBuildPagingBuffer->pDmaBuffer = ((uint8_t*)pBuildPagingBuffer->pDmaBuffer) + cbBuffer;
     pBuildPagingBuffer->pDmaBufferPrivateData = ((uint8_t*)pBuildPagingBuffer->pDmaBufferPrivateData) + cbPrivateData;
@@ -6088,9 +6091,11 @@
 //    LOGF(("ENTER, hContext(0x%x)", hContext));
 
-    vboxVDbgBreakFv();
+    vboxVDbgBreakF();
 
     PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
     PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
     PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
+    uint32_t cbBuffer = 0;
+    uint32_t cbPrivateData = 0;
 
     if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
@@ -6191,5 +6196,6 @@
 
             paRects = pBlt->aRects;
-            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects);
+            cbPrivateData = RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects);
+            cbMaxRects = pPresent->DmaBufferPrivateDataSize - cbPrivateData;
         }
         else
@@ -6214,6 +6220,9 @@
 
             paRects = pBlt->aRects;
-            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects);
-        }
+            cbPrivateData = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects);
+            cbMaxRects = pPresent->DmaBufferPrivateDataSize - cbPrivateData;
+        }
+
+        cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     }
     else if (pPresent->Flags.Flip)
@@ -6247,4 +6256,7 @@
         if (VBoxCVDdiFillAllocInfo(pHdr, &pFlip->src, pSrcAlloc, pSrc, false))
             u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_FLIP, src.u.offVRAM);
+
+        cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+        cbPrivateData = sizeof (*pFlip);
     }
     else if (pPresent->Flags.ColorFill)
@@ -6278,5 +6290,8 @@
 
         paRects = pCFill->aRects;
-        cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, aRects);
+        cbPrivateData = RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, aRects);
+        cbMaxRects = pPresent->DmaBufferPrivateDataSize - cbPrivateData;
+
+        cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     }
     else
@@ -6300,6 +6315,8 @@
             pPresent->MultipassOffset = 0;
 
+        Assert(cRects);
         const RECT *paDstSubRects = &pPresent->pDstSubRects[iStartRect];
         VBoxCVDdiPackRects(paRects, paDstSubRects, cRects);
+        cbPrivateData += (cRects * sizeof (VBOXCMDVBVA_RECT));
     }
 
@@ -6324,5 +6341,8 @@
     pHdr->u32FenceID = 0;
 
-    pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+    Assert(cbBuffer);
+    Assert(cbPrivateData);
+    pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + cbBuffer;
+    pPresent->pDmaBufferPrivateData = ((uint8_t*)pPresent->pDmaBufferPrivateData) + cbPrivateData;
 
     if (pPresent->MultipassOffset)
Index: trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp	(revision 50912)
+++ trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp	(revision 50913)
@@ -97,4 +97,5 @@
     VBVAEXHOSTCTL_TYPE_HH_ENABLE,
     VBVAEXHOSTCTL_TYPE_HH_TERM,
+    VBVAEXHOSTCTL_TYPE_HH_ON_HGCM_TERM,
     VBVAEXHOSTCTL_TYPE_HH_RESET,
     VBVAEXHOSTCTL_TYPE_HH_SAVESTATE,
@@ -213,5 +214,5 @@
         else if (!fHostOnlyMode)
         {
-            if (ASMAtomicUoReadS32(&pCmdVbva->i32EnableState) > VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
+            if (ASMAtomicUoReadS32(&pCmdVbva->i32EnableState) != VBVAEXHOSTCONTEXT_ESTATE_PAUSED)
             {
                 pCtl = RTListGetFirst(&pCmdVbva->GuestCtlList, VBVAEXHOSTCTL, Node);
@@ -965,10 +966,38 @@
 }
 
+static DECLCALLBACK(void) vboxVDMACrHgcmNotifyTerminatingDoneCb(HVBOXCRCMDCTL_NOTIFY_TERMINATING hClient)
+{
+    struct VBOXVDMAHOST *pVdma = hClient;
+    Assert(pVdma->CmdVbva.i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+    int rc = VBoxVDMAThreadEventNotify(&pVdma->Thread);
+    AssertRC(rc);
+}
+
+static DECLCALLBACK(int) vboxVDMACrHgcmNotifyTerminatingCb(HVBOXCRCMDCTL_NOTIFY_TERMINATING hClient, VBOXCRCMDCTL_HGCMENABLE_DATA *pHgcmEnableData)
+{
+    struct VBOXVDMAHOST *pVdma = hClient;
+    VBVAEXHOSTCTL Ctl;
+    Ctl.enmType = VBVAEXHOSTCTL_TYPE_HH_ON_HGCM_TERM;
+    int rc = vdmaVBVACtlSubmitSync(pVdma, &Ctl, VBVAEXHOSTCTL_SOURCE_HOST_ANY);
+    if (!RT_SUCCESS(rc))
+    {
+        WARN(("vdmaVBVACtlSubmitSync failed %d\n", rc));
+        return rc;
+    }
+
+    Assert(pVdma->CmdVbva.i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
+
+    pHgcmEnableData->hRHCmd = pVdma;
+    pHgcmEnableData->pfnRHCmd = vboxVDMACrHgcmHandleEnableRemainingHostCommand;
+
+    return VINF_SUCCESS;
+}
+
 static int vboxVDMACrHgcmHandleEnable(struct VBOXVDMAHOST *pVdma)
 {
     VBOXCRCMDCTL_ENABLE Enable;
     Enable.Hdr.enmType = VBOXCRCMDCTL_TYPE_ENABLE;
-    Enable.hRHCmd = pVdma;
-    Enable.pfnRHCmd = vboxVDMACrHgcmHandleEnableRemainingHostCommand;
+    Enable.Data.hRHCmd = pVdma;
+    Enable.Data.pfnRHCmd = vboxVDMACrHgcmHandleEnableRemainingHostCommand;
 
     int rc = vboxVDMACrHgcmSubmitSync(pVdma, &Enable.Hdr, sizeof (Enable));
@@ -1012,7 +1041,10 @@
     if (RT_SUCCESS(rc))
     {
-        VBOXCRCMDCTL Ctl;
-        Ctl.enmType = VBOXCRCMDCTL_TYPE_DISABLE;
-        rc = vboxVDMACrHgcmSubmitSync(pVdma, &Ctl, sizeof (Ctl));
+        VBOXCRCMDCTL_DISABLE Disable;
+        Disable.Hdr.enmType = VBOXCRCMDCTL_TYPE_DISABLE;
+        Disable.Data.hNotifyTerm = pVdma;
+        Disable.Data.pfnNotifyTerm = vboxVDMACrHgcmNotifyTerminatingCb;
+        Disable.Data.pfnNotifyTermDone = vboxVDMACrHgcmNotifyTerminatingDoneCb;
+        rc = vboxVDMACrHgcmSubmitSync(pVdma, &Disable.Hdr, sizeof (Disable));
         if (RT_SUCCESS(rc))
         {
@@ -1042,5 +1074,5 @@
 }
 
-static int vdmaVBVADisableProcess(struct VBOXVDMAHOST *pVdma)
+static int vdmaVBVADisableProcess(struct VBOXVDMAHOST *pVdma, bool fDoHgcmEnable)
 {
     if (!VBoxVBVAExHSIsEnabled(&pVdma->CmdVbva))
@@ -1053,18 +1085,21 @@
     if (RT_SUCCESS(rc))
     {
-        /* disable is a bit tricky
-         * we need to ensure the host ctl commands do not come out of order
-         * and do not come over HGCM channel until after it is enabled */
-        rc = vboxVDMACrHgcmHandleEnable(pVdma);
-        if (RT_SUCCESS(rc))
-            return rc;
-
-        PVGASTATE pVGAState = pVdma->pVGAState;
-        VBOXCRCMD_SVRENABLE_INFO Info;
-        Info.hCltScr = pVGAState->pDrv;
-        Info.pfnCltScrUpdateBegin = pVGAState->pDrv->pfnVBVAUpdateBegin;
-        Info.pfnCltScrUpdateProcess = pVGAState->pDrv->pfnVBVAUpdateProcess;
-        Info.pfnCltScrUpdateEnd = pVGAState->pDrv->pfnVBVAUpdateEnd;
-        pVdma->CrSrvInfo.pfnEnable(pVdma->CrSrvInfo.hSvr, &Info);
+        if (fDoHgcmEnable)
+        {
+            /* disable is a bit tricky
+             * we need to ensure the host ctl commands do not come out of order
+             * and do not come over HGCM channel until after it is enabled */
+            rc = vboxVDMACrHgcmHandleEnable(pVdma);
+            if (RT_SUCCESS(rc))
+                return rc;
+
+            PVGASTATE pVGAState = pVdma->pVGAState;
+            VBOXCRCMD_SVRENABLE_INFO Info;
+            Info.hCltScr = pVGAState->pDrv;
+            Info.pfnCltScrUpdateBegin = pVGAState->pDrv->pfnVBVAUpdateBegin;
+            Info.pfnCltScrUpdateProcess = pVGAState->pDrv->pfnVBVAUpdateProcess;
+            Info.pfnCltScrUpdateEnd = pVGAState->pDrv->pfnVBVAUpdateEnd;
+            pVdma->CrSrvInfo.pfnEnable(pVdma->CrSrvInfo.hSvr, &Info);
+        }
     }
     else
@@ -1074,6 +1109,8 @@
 }
 
-static int vboxVDMACrHostCtlProcess(struct VBOXVDMAHOST *pVdma, VBVAEXHOSTCTL *pCmd)
-{
+static int vboxVDMACrHostCtlProcess(struct VBOXVDMAHOST *pVdma, VBVAEXHOSTCTL *pCmd, bool *pfContinue)
+{
+    *pfContinue = true;
+
     switch (pCmd->enmType)
     {
@@ -1101,5 +1138,5 @@
         case VBVAEXHOSTCTL_TYPE_HH_TERM:
         {
-            int rc = vdmaVBVADisableProcess(pVdma);
+            int rc = vdmaVBVADisableProcess(pVdma, true);
             if (!RT_SUCCESS(rc))
             {
@@ -1111,7 +1148,20 @@
             return VINF_SUCCESS;
         }
+        case VBVAEXHOSTCTL_TYPE_HH_ON_HGCM_TERM:
+        {
+            int rc = vdmaVBVADisableProcess(pVdma, false);
+            if (!RT_SUCCESS(rc))
+            {
+                WARN(("vdmaVBVADisableProcess failed %d\n", rc));
+                return rc;
+            }
+
+            *pfContinue = false;
+
+            return VINF_SUCCESS;
+        }
         case VBVAEXHOSTCTL_TYPE_HH_RESET:
         {
-            int rc = vdmaVBVADisableProcess(pVdma);
+            int rc = vdmaVBVADisableProcess(pVdma, true);
             if (!RT_SUCCESS(rc))
             {
@@ -1148,5 +1198,5 @@
             }
 
-            return vdmaVBVADisableProcess(pVdma);
+            return vdmaVBVADisableProcess(pVdma, true);
         }
         default:
@@ -1160,70 +1210,47 @@
  * the direction is VRA#M - related, so fIn == true - transfer to VRAM); false - transfer from VRAM
  */
-static int vboxVDMACrCmdVbvaProcessPagingEl(PPDMDEVINS pDevIns, const VBOXCMDVBVA_SYSMEMEL *pMemEl, uint8_t *pu8Vram, uint8_t *pu8VramMax, uint8_t **ppu8VramNext, bool fIn)
-{
-    uint32_t u32Cpages = pMemEl->cPagesAfterFirst + 1;
-    RTGCPHYS phPage = (pMemEl->iPage1 | (pMemEl->iPage2 << 20));
+static int vboxVDMACrCmdVbvaProcessPagingEl(PPDMDEVINS pDevIns, VBOXCMDVBVAPAGEIDX iPage, uint8_t *pu8Vram, bool fIn)
+{
+    RTGCPHYS phPage = (RTGCPHYS)(iPage >> PAGE_SHIFT);
     PGMPAGEMAPLOCK Lock;
-    uint32_t cbCopy = u32Cpages * PAGE_SIZE;
-    uint8_t* pu8VramNext = pu8Vram + cbCopy;
-
-    if (pu8VramNext <= pu8Vram && pu8VramNext > pu8VramMax)
-    {
-        WARN(("invalid copy size"));
-        return VERR_INVALID_PARAMETER;
-    }
-
     int rc;
+
     if (fIn)
     {
-        for (uint32_t i = 0; i < u32Cpages; ++i)
-        {
-            const void * pvPage;
-            rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, phPage, 0, &pvPage, &Lock);
-            if (!RT_SUCCESS(rc))
-            {
-                WARN(("PDMDevHlpPhysGCPhys2CCPtrReadOnly failed %d", rc));
-                return rc;
-            }
-
-            memcpy(pu8Vram, pvPage, PAGE_SIZE);
-
-            PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock);
-
-            pu8Vram += PAGE_SIZE;
-        }
+        const void * pvPage;
+        rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, phPage, 0, &pvPage, &Lock);
+        if (!RT_SUCCESS(rc))
+        {
+            WARN(("PDMDevHlpPhysGCPhys2CCPtrReadOnly failed %d", rc));
+            return rc;
+        }
+
+        memcpy(pu8Vram, pvPage, PAGE_SIZE);
+
+        PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock);
     }
     else
     {
-        for (uint32_t i = 0; i < u32Cpages; ++i)
-        {
-            void * pvPage;
-            rc = PDMDevHlpPhysGCPhys2CCPtr(pDevIns, phPage, 0, &pvPage, &Lock);
-            if (!RT_SUCCESS(rc))
-            {
-                WARN(("PDMDevHlpPhysGCPhys2CCPtr failed %d", rc));
-                return rc;
-            }
-
-            memcpy(pvPage, pu8Vram, PAGE_SIZE);
-
-            PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock);
-
-            pu8Vram += PAGE_SIZE;
-        }
-    }
-
-    if (ppu8VramNext)
-        *ppu8VramNext = pu8VramNext;
+        void * pvPage;
+        rc = PDMDevHlpPhysGCPhys2CCPtr(pDevIns, phPage, 0, &pvPage, &Lock);
+        if (!RT_SUCCESS(rc))
+        {
+            WARN(("PDMDevHlpPhysGCPhys2CCPtr failed %d", rc));
+            return rc;
+        }
+
+        memcpy(pvPage, pu8Vram, PAGE_SIZE);
+
+        PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock);
+    }
 
     return VINF_SUCCESS;
 }
 
-static int vboxVDMACrCmdVbvaProcessPagingEls(PPDMDEVINS pDevIns, const VBOXCMDVBVA_SYSMEMEL *pMemEl, uint32_t cMemEls, uint8_t *pu8Vram, uint8_t *pu8VramMax, uint8_t **ppu8VramNext, bool fIn)
-{
-    uint8_t *pu8VramNext = pu8Vram;
-    for (uint32_t i = 0; i < cMemEls; ++i, ++pMemEl)
-    {
-        int rc = vboxVDMACrCmdVbvaProcessPagingEl(pDevIns, pMemEl, pu8Vram, pu8VramMax, &pu8VramNext, fIn);
+static int vboxVDMACrCmdVbvaProcessPagingEls(PPDMDEVINS pDevIns, const VBOXCMDVBVAPAGEIDX *piPages, uint32_t cPages, uint8_t *pu8Vram, bool fIn)
+{
+    for (uint32_t i = 0; i < cPages; ++i)
+    {
+        int rc = vboxVDMACrCmdVbvaProcessPagingEl(pDevIns, piPages[i], pu8Vram, fIn);
         if (!RT_SUCCESS(rc))
         {
@@ -1233,13 +1260,10 @@
     }
 
-    if (ppu8VramNext)
-        *ppu8VramNext = pu8VramNext;
-
     return VINF_SUCCESS;
 }
 
 static int8_t vboxVDMACrCmdVbvaPagingDataInit(PVGASTATE pVGAState, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd,
-                            const VBOXCMDVBVA_SYSMEMEL **ppSysMem, uint32_t *pcSysMem,
-                            uint8_t **ppu8Vram, uint8_t **ppu8VramMax, bool *pfIn)
+                            const VBOXCMDVBVAPAGEIDX **ppPages, VBOXCMDVBVAPAGEIDX *pcPages,
+                            uint8_t **ppu8Vram, bool *pfIn)
 {
     if (cbCmd < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
@@ -1249,11 +1273,11 @@
     }
 
-    uint32_t cSysMem = cbCmd - RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aSysMem);
-    if (cSysMem % sizeof (VBOXCMDVBVA_SYSMEMEL))
+    VBOXCMDVBVAPAGEIDX cPages = cbCmd - RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aPageNumbers);
+    if (cPages % sizeof (VBOXCMDVBVAPAGEIDX))
     {
         WARN(("invalid cmd size"));
         return -1;
     }
-    cSysMem /= sizeof (VBOXCMDVBVA_SYSMEMEL);
+    cPages /= sizeof (VBOXCMDVBVAPAGEIDX);
 
     VBOXCMDVBVA_PAGING_TRANSFER *pTransfer = (VBOXCMDVBVA_PAGING_TRANSFER*)pCmd;
@@ -1264,9 +1288,9 @@
         return -1;
     }
-    const VBOXCMDVBVA_SYSMEMEL *pSysMem = pTransfer->aSysMem;
+    const VBOXCMDVBVAPAGEIDX *pPages = pTransfer->aPageNumbers;
 
     uint8_t * pu8VramBase = pVGAState->vram_ptrR3;
     uint8_t *pu8VramMax = pu8VramBase + pVGAState->vram_size;
-    if (pTransfer->Alloc.u.offVRAM >= pVGAState->vram_size)
+    if (offVRAM >= pVGAState->vram_size)
     {
         WARN(("invalid vram offset"));
@@ -1274,11 +1298,16 @@
     }
 
-    uint8_t *pu8Vram = pu8VramBase + pTransfer->Alloc.u.offVRAM;
+    if (offVRAM + (cPages << PAGE_SHIFT) >= pVGAState->vram_size)
+    {
+        WARN(("invalid cPages"));
+        return -1;
+    }
+
+    uint8_t *pu8Vram = pu8VramBase + offVRAM;
     bool fIn = !!(pTransfer->Hdr.u8Flags & VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN);
 
-    *ppSysMem = pSysMem;
-    *pcSysMem = cSysMem;
+    *ppPages = pPages;
+    *pcPages = cPages;
     *ppu8Vram = pu8Vram;
-    *ppu8VramMax = pu8VramMax;
     *pfIn = fIn;
     return 0;
@@ -1294,12 +1323,11 @@
         {
             PVGASTATE pVGAState = pVdma->pVGAState;
-            const VBOXCMDVBVA_SYSMEMEL *pSysMem;
-            uint32_t cSysMem;
+            const VBOXCMDVBVAPAGEIDX *pPages;
+            uint32_t cPages;
             uint8_t *pu8Vram;
-            uint8_t *pu8VramMax;
             bool fIn;
             int8_t i8Result = vboxVDMACrCmdVbvaPagingDataInit(pVGAState, pCmd, cbCmd,
-                                                                &pSysMem, &cSysMem,
-                                                                &pu8Vram, &pu8VramMax, &fIn);
+                                                                &pPages, &cPages,
+                                                                &pu8Vram, &fIn);
             if (i8Result < 0)
             {
@@ -1309,5 +1337,5 @@
 
             PPDMDEVINS pDevIns = pVGAState->pDevInsR3;
-            int rc = vboxVDMACrCmdVbvaProcessPagingEls(pDevIns, pSysMem, cSysMem, pu8Vram, pu8VramMax, &pu8Vram, fIn);
+            int rc = vboxVDMACrCmdVbvaProcessPagingEls(pDevIns, pPages, cPages, pu8Vram, fIn);
             if (!RT_SUCCESS(rc))
             {
@@ -1340,7 +1368,6 @@
 AssertCompile(sizeof (VBOXCMDVBVA_HDR) == 8);
 AssertCompile(sizeof (VBOXCMDVBVA_ALLOCINFO) == 4);
-AssertCompile(sizeof (VBOXCMDVBVA_SYSMEMEL) == 8);
-AssertCompile(!(PAGE_SIZE % sizeof (VBOXCMDVBVA_SYSMEMEL)));
-AssertCompile(!(sizeof (VBOXCMDVBVA_PAGING_TRANSFER) % 8));
+AssertCompile(sizeof (VBOXCMDVBVAPAGEIDX) == 4);
+AssertCompile(!(PAGE_SIZE % sizeof (VBOXCMDVBVAPAGEIDX)));
 
 #define VBOXCMDVBVA_NUM_SYSMEMEL_PER_PAGE (PAGE_SIZE / sizeof (VBOXCMDVBVA_SYSMEMEL))
@@ -1362,10 +1389,6 @@
             }
 
-            RTGCPHYS phPage = pSysmemCmd->phSysMem;
-            if (phPage & PAGE_OFFSET_MASK)
-            {
-                WARN(("cmd address is not on page boundary\n"));
-                return -1;
-            }
+            VBOXCMDVBVAPAGEIDX iPage = pSysmemCmd->iPage;
+            RTGCPHYS phPage = (RTGCPHYS)(iPage << PAGE_SHIFT);
 
             PGMPAGEMAPLOCK Lock;
@@ -1395,12 +1418,11 @@
                 case VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER:
                 {
-                    const VBOXCMDVBVA_SYSMEMEL *pSysMem;
-                    uint32_t cSysMem;
+                    const uint32_t *pPages;
+                    uint32_t cPages;
                     uint8_t *pu8Vram;
-                    uint8_t *pu8VramMax;
                     bool fIn;
                     i8Result = vboxVDMACrCmdVbvaPagingDataInit(pVGAState, pCmd, cbCmd,
-                                                                        &pSysMem, &cSysMem,
-                                                                        &pu8Vram, &pu8VramMax, &fIn);
+                                                                        &pPages, &cPages,
+                                                                        &pu8Vram, &fIn);
                     if (i8Result < 0)
                     {
@@ -1409,11 +1431,11 @@
                     }
 
-                    uint32_t cCurSysMem = PAGE_SIZE - RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aSysMem);
-                    cCurSysMem /= sizeof (VBOXCMDVBVA_SYSMEMEL);
-                    Assert(cCurSysMem < cSysMem);
+                    uint32_t cCurPages = PAGE_SIZE - RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aPageNumbers);
+                    cCurPages /= sizeof (VBOXCMDVBVAPAGEIDX);
+                    Assert(cCurPages < cPages);
 
                     do
                     {
-                        rc = vboxVDMACrCmdVbvaProcessPagingEls(pDevIns, pSysMem, cCurSysMem, pu8Vram, pu8VramMax, &pu8Vram, fIn);
+                        rc = vboxVDMACrCmdVbvaProcessPagingEls(pDevIns, pPages, cCurPages, pu8Vram, fIn);
                         if (!RT_SUCCESS(rc))
                         {
@@ -1423,8 +1445,8 @@
                         }
 
-                        Assert(cSysMem >= cCurSysMem);
-                        cSysMem -= cCurSysMem;
-
-                        if (!cSysMem)
+                        Assert(cPages >= cCurPages);
+                        cPages -= cCurPages;
+
+                        if (!cPages)
                             break;
 
@@ -1432,4 +1454,5 @@
 
                         phPage += PAGE_SIZE;
+                        pu8Vram += (cCurPages << PAGE_SHIFT);
 
                         rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, phPage, 0, &pvCmd, &Lock);
@@ -1440,8 +1463,7 @@
                         }
 
-                        if (cSysMem > VBOXCMDVBVA_NUM_SYSMEMEL_PER_PAGE)
-                            cCurSysMem = VBOXCMDVBVA_NUM_SYSMEMEL_PER_PAGE;
-                        else
-                            cCurSysMem = cSysMem;
+                        cCurPages = PAGE_SIZE / sizeof (VBOXCMDVBVAPAGEIDX);
+                        if (cCurPages > cPages)
+                            cCurPages = cPages;
                     } while (1);
                     break;
@@ -2034,12 +2056,16 @@
                 VBVARaiseIrqNoWait(pVGAState, 0);
                 break;
-            case VBVAEXHOST_DATA_TYPE_HOSTCTL:
-                rc = vboxVDMACrHostCtlProcess(pVdma, (VBVAEXHOSTCTL*)pCmd);
-                VBoxVBVAExHPDataCompleteCtl(pCmdVbva, (VBVAEXHOSTCTL*)pCmd, rc);
-                break;
             case VBVAEXHOST_DATA_TYPE_GUESTCTL:
                 rc = vboxVDMACrGuestCtlProcess(pVdma, (VBVAEXHOSTCTL*)pCmd);
                 VBoxVBVAExHPDataCompleteCtl(pCmdVbva, (VBVAEXHOSTCTL*)pCmd, rc);
                 break;
+            case VBVAEXHOST_DATA_TYPE_HOSTCTL:
+            {
+                bool fContinue = true;
+                rc = vboxVDMACrHostCtlProcess(pVdma, (VBVAEXHOSTCTL*)pCmd, &fContinue);
+                VBoxVBVAExHPDataCompleteCtl(pCmdVbva, (VBVAEXHOSTCTL*)pCmd, rc);
+                if (fContinue)
+                    break;
+            }
             case VBVAEXHOST_DATA_TYPE_NO_DATA:
                 rc = VBoxVDMAThreadEventWait(&pVdma->Thread, RT_INDEFINITE_WAIT);
Index: trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 50912)
+++ trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 50913)
@@ -413,4 +413,6 @@
 
     CR_SERVER_RPW RpwWorker;
+
+    VBOXCRCMDCTL_HGCMDISABLE_DATA DisableData;
 
     /** configuration options */
@@ -573,6 +575,6 @@
 #endif
 
-extern DECLEXPORT(int32_t) crVBoxServerHgcmEnable(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd);
-extern DECLEXPORT(int32_t) crVBoxServerHgcmDisable();
+extern DECLEXPORT(int32_t) crVBoxServerHgcmEnable(VBOXCRCMDCTL_HGCMENABLE_DATA *pData);
+extern DECLEXPORT(int32_t) crVBoxServerHgcmDisable(VBOXCRCMDCTL_HGCMDISABLE_DATA *pData);
 
 extern int crVBoxServerHostCtl(VBOXCRCMDCTL *pCtl, uint32_t cbCtl);
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp	(revision 50912)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp	(revision 50913)
@@ -1524,7 +1524,8 @@
                 case VBOXCRCMDCTL_TYPE_DISABLE:
                 {
-                    if (paParms->u.pointer.size != sizeof (VBOXCRCMDCTL))
+                    if (paParms->u.pointer.size != sizeof (VBOXCRCMDCTL_DISABLE))
                         WARN(("invalid param size"));
-                    int rc = crVBoxServerHgcmDisable();
+                    VBOXCRCMDCTL_DISABLE *pDisable = (VBOXCRCMDCTL_DISABLE*)pCtl;
+                    int rc = crVBoxServerHgcmDisable(&pDisable->Data);
                     if (RT_SUCCESS(rc))
                         g_u32fCrHgcmDisabled = 1;
@@ -1538,5 +1539,5 @@
                         WARN(("invalid param size"));
                     VBOXCRCMDCTL_ENABLE *pEnable = (VBOXCRCMDCTL_ENABLE*)pCtl;
-                    int rc = crVBoxServerHgcmEnable(pEnable->hRHCmd, pEnable->pfnRHCmd);
+                    int rc = crVBoxServerHgcmEnable(&pEnable->Data);
                     if (RT_SUCCESS(rc))
                         g_u32fCrHgcmDisabled = 0;
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 50912)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 50913)
@@ -51,5 +51,5 @@
 
 #define VBOXCRHGSMI_CMD_CHECK_COMPLETE(_pData, _rc) do { \
-        if (CRVBOXHGSMI_CMDDATA_IS_SET(_pData)) { \
+        if (CRVBOXHGSMI_CMDDATA_IS_HGSMICMD(_pData)) { \
             VBOXCRHGSMI_CMD_COMPLETE(_pData, _rc); \
         } \
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 50912)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 50913)
@@ -84,5 +84,4 @@
 {
     CRClient *pClient = NULL;
-    int32_t i;
 
     pClient = crVBoxServerClientById(u32ClientID);
@@ -158,4 +157,24 @@
 
     tearingdown = 1;
+
+    if (cr_server.DisableData.hNotifyTerm)
+    {
+        VBOXCRCMDCTL_HGCMENABLE_DATA EnableData;
+        int rc = cr_server.DisableData.pfnNotifyTerm(cr_server.DisableData.hNotifyTerm, &EnableData);
+        if (!RT_SUCCESS(rc))
+        {
+            WARN(("pfnNotifyTerm failed %d", rc));
+            return;
+        }
+
+        rc = crVBoxServerHgcmEnable(&EnableData);
+        if (!RT_SUCCESS(rc))
+        {
+            WARN(("crVBoxServerHgcmEnable failed %d", rc));
+            return;
+        }
+
+        cr_server.DisableData.pfnNotifyTermDone(cr_server.DisableData.hNotifyTerm);
+    }
 
     crStateSetCurrent( NULL );
@@ -2975,5 +2994,5 @@
         {
             spuCtx = cr_server.MainContextInfo.SpuContext;
-            spuWindow = pMural->CreateInfo.realVisualBits;
+            spuWindow = pMural->spuWindow;
         }
     }
@@ -3014,5 +3033,5 @@
     cParams = cBuffers-1;
 
-    if (cbCmd != RT_OFFSETOF(VBOXCMDVBVA_CRCMD_CMD, aBuffers[cBuffers]))
+    if (cbCmd < RT_OFFSETOF(VBOXCMDVBVA_CRCMD_CMD, aBuffers[cBuffers]))
     {
         WARN(("invalid buffer size"));
@@ -3363,5 +3382,8 @@
                     rc = CrHTablePutToSlot(&cr_server.clientTable, u32ClientId, pClient);
                     if (RT_SUCCESS(rc))
+                    {
+                        pConnect->Hdr.u32CmdClientId = u32ClientId;
                         return VINF_SUCCESS;
+                    }
                     else
                         WARN(("CrHTablePutToSlot failed %d", rc));
@@ -3454,5 +3476,4 @@
 static DECLCALLBACK(int8_t) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd)
 {
-    AssertFailed();
     switch (pCmd->u8OpCode)
     {
@@ -3884,9 +3905,11 @@
 }
 
-int32_t crVBoxServerHgcmEnable(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd)
+int32_t crVBoxServerHgcmEnable(VBOXCRCMDCTL_HGCMENABLE_DATA *pData)
 {
     int rc = VINF_SUCCESS;
     uint8_t* pCtl;
     uint32_t cbCtl;
+    HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd = pData->hRHCmd;
+    PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd = pData->pfnRHCmd;
 
     Assert(!cr_server.fCrCmdEnabled);
@@ -3908,5 +3931,5 @@
 }
 
-int32_t crVBoxServerHgcmDisable()
+int32_t crVBoxServerHgcmDisable(VBOXCRCMDCTL_HGCMDISABLE_DATA *pData)
 {
     Assert(!cr_server.fCrCmdEnabled);
@@ -3920,4 +3943,6 @@
     cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
 
+    cr_server.DisableData = *pData;
+
     return VINF_SUCCESS;
 }
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 50912)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 50913)
@@ -372,5 +372,5 @@
                         pCopyRect->yBottom - pCopyRect->yTop,
                         pu8Src,
-                        fSrcInvert ? -pSrc->pitch : pSrc->pitch,
+                        fSrcInvert ? -((GLint)pSrc->pitch) : pSrc->pitch,
                         UnscaledSrcWidth,
                         UnscaledSrcHeight
