Index: trunk/src/VBox/Additions/WINNT/Graphics/Display/dd.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Display/dd.c	(revision 21905)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Display/dd.c	(revision 21939)
@@ -46,5 +46,4 @@
 #define VBOXVHWA_CAP(_pdev, _cap) ((_pdev)->vhwaInfo.caps & (_cap))
 static bool getDDHALInfo(PPDEV pDev, DD_HALINFO* pHALInfo);
-static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
 static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
 static DECLCALLBACK(void) vboxVHWASurfFlipCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
@@ -76,4 +75,7 @@
  *
  */
+
+DD_HALINFO g_h2;
+
 BOOL APIENTRY DrvGetDirectDrawInfo(
     DHPDEV        dhpdev,
@@ -615,48 +617,4 @@
         DDPIXELFORMAT * pFormat = &lpSurfaceGlobal->ddpfSurface;
 
-        if(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
-        {
-            lBpp = pDev->ulBitCount;
-            lPitch = pDev->lDeltaScreen;
-        }
-        else
-        {
-            if (pFormat->dwFlags & DDPF_PALETTEINDEXED4)
-            {
-                lBpp = 4;
-                lPitch = lpSurfaceGlobal->wWidth/2;
-                lPitch = (lPitch + 31) & ~31;
-            }
-            else
-            if (pFormat->dwFlags & DDPF_PALETTEINDEXED8)
-            {
-                lBpp = 8;
-                lPitch = lpSurfaceGlobal->wWidth;
-                lPitch = (lPitch + 31) & ~31;
-            }
-            else
-            {
-                lBpp   = pFormat->dwRGBBitCount;
-                lPitch = lpSurfaceGlobal->wWidth*(lBpp/8);
-            }
-        }
-
-        DISPDBG((0, "New surface (%d,%d)\n", lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight));
-        DISPDBG((0, "BPP %d lPitch=%d\n", lBpp, lPitch));
-#if 1
-        lpSurfaceGlobal->dwBlockSizeX   = lPitch;
-        lpSurfaceGlobal->dwBlockSizeY   = lpSurfaceGlobal->wHeight;
-        lpSurfaceGlobal->lPitch         = lPitch;
-#else
-        lpSurfaceGlobal->dwBlockSizeX   = lPitch * lpSurfaceGlobal->wHeight;
-        lpSurfaceGlobal->dwBlockSizeY   = 1;
-        lpSurfaceGlobal->lPitch         = lPitch;
-#endif
-
-#if 1
-        lpSurfaceDesc->lPitch   = lpSurfaceGlobal->lPitch;
-        lpSurfaceDesc->dwFlags |= DDSD_PITCH;
-#endif
-
         //
         // Modify surface descriptions as appropriate and let Direct
@@ -683,15 +641,15 @@
             memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE));
 
-            rc = vboxVHWAFromDDSURFACEDESC(&pBody->u.in.SurfInfo, lpSurfaceDesc);
-
-            pBody->u.in.SurfInfo.surfCaps = vboxVHWAFromDDSCAPS(lpSurfaceLocal->ddsCaps.dwCaps);
-            pBody->u.in.SurfInfo.flags |= DDSD_CAPS;
-
-            pBody->u.in.SurfInfo.height = lpSurfaceGlobal->wHeight;
-            pBody->u.in.SurfInfo.width = lpSurfaceGlobal->wWidth;
-            pBody->u.in.SurfInfo.flags |= DDSD_HEIGHT | DDSD_WIDTH;
-
-            vboxVHWAFromDDPIXELFORMAT(&pBody->u.in.SurfInfo.PixelFormat, pFormat);
-            pBody->u.in.SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT;
+            rc = vboxVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpSurfaceDesc);
+
+            pBody->SurfInfo.surfCaps = vboxVHWAFromDDSCAPS(lpSurfaceLocal->ddsCaps.dwCaps);
+            pBody->SurfInfo.flags |= DDSD_CAPS;
+
+            pBody->SurfInfo.height = lpSurfaceGlobal->wHeight;
+            pBody->SurfInfo.width = lpSurfaceGlobal->wWidth;
+            pBody->SurfInfo.flags |= DDSD_HEIGHT | DDSD_WIDTH;
+
+            vboxVHWAFromDDPIXELFORMAT(&pBody->SurfInfo.PixelFormat, pFormat);
+            pBody->SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT;
 
             if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
@@ -708,5 +666,4 @@
             if(pDesc)
             {
-                pDesc->cBitsPerPixel = lBpp;
                 vboxVHWACommandSubmit(pDev, pCmd);
                 Assert(pCmd->rc == VINF_SUCCESS);
@@ -715,4 +672,21 @@
                     pDesc->hHostHandle = pBody->u.out.hSurf;
                     lpSurfaceGlobal->dwReserved1 = (ULONG_PTR)pDesc;
+                    lPitch = pBody->SurfInfo.pitch;
+                    lBpp = pBody->SurfInfo.bitsPerPixel;
+                    pDesc->cBitsPerPixel = lBpp;
+#if 0
+                    lpSurfaceGlobal->dwBlockSizeX   = lPitch;
+                    lpSurfaceGlobal->dwBlockSizeY   = lpSurfaceGlobal->wHeight;
+                    lpSurfaceGlobal->lPitch         = lPitch;
+#else
+                    lpSurfaceGlobal->dwBlockSizeX   = lPitch * lpSurfaceGlobal->wHeight;
+                    lpSurfaceGlobal->dwBlockSizeY   = 1;
+                    lpSurfaceGlobal->lPitch         = lPitch;
+#endif
+#if 1
+                    lpSurfaceDesc->lPitch   = lpSurfaceGlobal->lPitch;
+                    lpSurfaceDesc->dwFlags |= DDSD_PITCH;
+#endif
+
                     lpCreateSurface->ddRVal = DD_OK;
                 }
@@ -831,5 +805,5 @@
             memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CANCREATE));
 
-            rc = vboxVHWAFromDDSURFACEDESC(&pBody->u.in.SurfInfo, lpDDS);
+            rc = vboxVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpDDS);
             pBody->u.in.bIsDifferentPixelFormat = lpCanCreateSurface->bIsDifferentPixelFormat;
 
@@ -1029,14 +1003,17 @@
         DD_SURFACE_GLOBAL*  lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
         PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
-        VBOXVHWACMD* pCmd;
-        /* ensure we have host cmds processed to update pending blits and flips */
-        vboxVHWACommandCheckHostCmds(pDev);
-
-    //    if(VBOXDD_CHECKFLAG(lpLock, DDLOCK_DONOTWAIT))
-        {
+        RECTL tmpRect, *pRect;
+
+        if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
+                || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
+                || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
+                || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg))
+        {
+            /* ensure we have host cmds processed to update pending blits and flips */
+            vboxVHWACommandCheckHostCmds(pDev);
             if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
-                    || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
-                    || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
-                    || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr))
+                        || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
+                        || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
+                        || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg))
             {
                 lpLock->ddRVal = DDERR_WASSTILLDRAWING;
@@ -1051,65 +1028,70 @@
 //        }
 
-        pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_LOCK, sizeof(VBOXVHWACMD_SURF_LOCK));
-        if(pCmd)
-        {
-            VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
-            RECTL tmpRect, *pRect;
-            memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK));
-
-            pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
-
-            if (lpLock->bHasRect)
+        if (lpLock->bHasRect)
+        {
+            pRect = &lpLock->rArea;
+        }
+        else
+        {
+            tmpRect.left=0;
+            tmpRect.top=0;
+            tmpRect.right=lpSurfaceGlobal->wWidth-1;
+            tmpRect.bottom=lpSurfaceGlobal->wHeight-1;
+            pRect = &tmpRect;
+        }
+
+        if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_DISCARDCONTENTS))
+        {
+//            pBody->u.in.flags |= VBOXVHWA_LOCK_DISCARDCONTENTS;
+
+            vboxVHWARegionTrySubstitute(&pDesc->NonupdatedMemRegion, pRect);
+//                /* we're not interested in completion, just send the command */
+//                vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
+            vboxVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect);
+            lpLock->ddRVal = DD_OK;
+        }
+        else if(!vboxVHWARegionIntersects(&pDesc->NonupdatedMemRegion, pRect))
+        {
+//                vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
+            vboxVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect);
+            lpLock->ddRVal = DD_OK;
+        }
+        else
+        {
+            VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_LOCK, sizeof(VBOXVHWACMD_SURF_LOCK));
+            if(pCmd)
             {
-                DISPDBG((0, "%d,%d %dx%d\n", lpLock->rArea.left, lpLock->rArea.top, lpLock->rArea.right - lpLock->rArea.left, lpLock->rArea.bottom - lpLock->rArea.top));
-                vboxVHWAFromRECTL(&pBody->u.in.rect, &lpLock->rArea);
+                VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
+                memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK));
+
+                pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
+
+//            if (lpLock->bHasRect)
+//            {
+//                DISPDBG((0, "%d,%d %dx%d\n", lpLock->rArea.left, lpLock->rArea.top, lpLock->rArea.right - lpLock->rArea.left, lpLock->rArea.bottom - lpLock->rArea.top));
+//                vboxVHWAFromRECTL(&pBody->u.in.rect, &lpLock->rArea);
+//                pBody->u.in.rectValid = 1;
+//
+//            }
+//            else
+//            {
+//                pBody->u.in.rectValid = 0;
+//            }
+                Assert(pDesc->NonupdatedMemRegion.bValid);
+                vboxVHWAFromRECTL(&pBody->u.in.rect, &pDesc->NonupdatedMemRegion.Rect);
                 pBody->u.in.rectValid = 1;
 
-                pRect = &lpLock->rArea;
-
+                pBody->u.in.hSurf = pDesc->hHostHandle;
+
+                /* wait for the surface to be locked and memory buffer updated */
+                vboxVHWACommandSubmit(pDev, pCmd);
+                vboxVHWACommandFree(pDev, pCmd);
+                vboxVHWARegionClear(&pDesc->NonupdatedMemRegion);
+                lpLock->ddRVal = DD_OK;
             }
             else
             {
-                pBody->u.in.rectValid = 0;
-
-                tmpRect.left=0;
-                tmpRect.top=0;
-                tmpRect.right=lpSurfaceGlobal->wWidth-1;
-                tmpRect.bottom=lpSurfaceGlobal->wHeight-1;
-                pRect = &tmpRect;
+                lpLock->ddRVal = DDERR_GENERIC;
             }
-
-            pBody->u.in.hSurf = pDesc->hHostHandle;
-
-            if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_DISCARDCONTENTS))
-            {
-                pBody->u.in.flags |= VBOXVHWA_LOCK_DISCARDCONTENTS;
-
-                if(vboxVHWARegionIncluded(&pDesc->DirtyRegion, pRect))
-                {
-                    vboxVHWARegionClear(&pDesc->DirtyRegion);
-                }
-//            }
-//            else if(vboxVHWARegionInterse)
-                /* we're not interested in completion, just send the command */
-                vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
-            }
-            else if(!vboxVHWARegionIntersects(&pDesc->DirtyRegion, pRect))
-            {
-                vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
-            }
-            else
-            {
-                /* wait for the surface to be locked and memory buffer updated */
-                vboxVHWACommandSubmit(pDev, pCmd);
-                vboxVHWACommandFree(pDev, pCmd);
-                vboxVHWARegionClear(&pDesc->DirtyRegion);
-            }
-
-            lpLock->ddRVal = DD_OK;
-        }
-        else
-        {
-            lpLock->ddRVal = DDERR_GENERIC;
         }
         return DDHAL_DRIVER_NOTHANDLED;
@@ -1174,5 +1156,4 @@
         DD_SURFACE_GLOBAL*  lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
         PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
-        VBOXVHWACMD* pCmd;
 
         //TODO: hadle vrdp properly
@@ -1186,23 +1167,43 @@
         }
 
-        /* ensure we have host cmds processed to update pending blits and flips */
-        vboxVHWACommandCheckHostCmds(pDev);
-
-        pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK));
-    //    int rc = VERR_GENERAL_FAILURE;
-        if(pCmd)
-        {
-            VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
-            memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK));
-
-            pBody->u.in.hSurf = pDesc->hHostHandle;
-
-            vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
-
-            lpUnlock->ddRVal = DD_OK;
-        }
-        else
-        {
-            lpUnlock->ddRVal = DDERR_GENERIC;
+//        /* ensure we have host cmds processed to update pending blits and flips */
+//        vboxVHWACommandCheckHostCmds(pDev);
+
+        if(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_VISIBLE
+                || (
+                        !(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_COMPLEX)
+                        && (
+                                lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE
+                                || (
+                                        (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
+                                        && !pDesc->bHidden
+                                    )
+                           )
+                   )
+          )
+        {
+            VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK));
+        //    int rc = VERR_GENERAL_FAILURE;
+            if(pCmd)
+            {
+                VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
+                memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK));
+
+                pBody->u.in.hSurf = pDesc->hHostHandle;
+                if(pDesc->UpdatedMemRegion.bValid)
+                {
+                    pBody->u.in.xUpdatedMemValid = 1;
+                    vboxVHWAFromRECTL(&pBody->u.in.xUpdatedMemRect, &pDesc->UpdatedMemRegion.Rect);
+                    vboxVHWARegionClear(&pDesc->UpdatedMemRegion);
+                }
+
+                vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
+
+                lpUnlock->ddRVal = DD_OK;
+            }
+            else
+            {
+                lpUnlock->ddRVal = DDERR_GENERIC;
+            }
         }
 
@@ -1308,5 +1309,5 @@
 
             /* we're not interested in completion, just send the command */
-            vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
+            vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
 
             vboxVHWASurfDescFree(pDesc);
@@ -1406,4 +1407,5 @@
 
 #ifdef VBOX_WITH_VIDEOHWACCEL
+#if 1
 DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA  lpSetColorKey)
 {
@@ -1428,5 +1430,5 @@
         vboxVHWAFromDDCOLORKEY(&pBody->u.in.CKey, &lpSetColorKey->ckNew);
 
-        vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
+        vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
         lpSetColorKey->ddRVal = DD_OK;
     }
@@ -1482,5 +1484,14 @@
             ASMAtomicIncU32(&pDestDesc->cPendingBltsDst);
 
-            vboxVHWARegionAdd(&pDestDesc->DirtyRegion, &lpBlt->rDest);
+            vboxVHWARegionAdd(&pDestDesc->NonupdatedMemRegion, &lpBlt->rDest);
+            vboxVHWARegionTrySubstitute(&pDestDesc->UpdatedMemRegion, &lpBlt->rDest);
+
+            if(pSrcDesc->UpdatedMemRegion.bValid)
+            {
+                pBody->u.in.xUpdatedSrcMemValid = 1;
+                vboxVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect);
+                vboxVHWARegionClear(&pSrcDesc->UpdatedMemRegion);
+            }
+
             vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfBltCompletion, NULL);
 
@@ -1516,17 +1527,23 @@
     DISPDBG((0, "%s\n", __FUNCTION__));
 
-    /* ensure we have host cmds processed to update pending blits and flips */
-    vboxVHWACommandCheckHostCmds(pDev);
-
-//    if(VBOXDD_CHECKFLAG(lpLock, DDLOCK_DONOTWAIT))
-    {
-        if(
+    if(
 //                ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
 //                || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
 //                ||
-                ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
-                || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
-                || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
-                || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
+            ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
+            || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
+            || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
+            || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
+    {
+        /* ensure we have host cmds processed to update pending blits and flips */
+        vboxVHWACommandCheckHostCmds(pDev);
+        if(
+    //                ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
+    //                || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
+    //                ||
+                    ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
+                    || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
+                    || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
+                    || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
         {
             lpFlip->ddRVal = DDERR_WASSTILLDRAWING;
@@ -1534,4 +1551,5 @@
         }
     }
+
 
     pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
@@ -1556,4 +1574,11 @@
         ASMAtomicIncU32(&pTargDesc->cPendingFlipsTarg);
 
+        if(pTargDesc->UpdatedMemRegion.bValid)
+        {
+            pBody->u.in.xUpdatedTargMemValid = 1;
+            vboxVHWAFromRECTL(&pBody->u.in.xUpdatedTargMemRect, &pTargDesc->UpdatedMemRegion.Rect);
+            vboxVHWARegionClear(&pTargDesc->UpdatedMemRegion);
+        }
+
         vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfFlipCompletion, NULL);
 
@@ -1582,7 +1607,4 @@
         DD_SURFACE_GLOBAL*  lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
         PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
-
-        /* ensure we have host cmds processed to update pending blits and flips */
-        vboxVHWACommandCheckHostCmds(pDev);
 
         if(
@@ -1593,5 +1615,20 @@
                     )
         {
-            lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
+            /* ensure we have host cmds processed to update pending blits and flips */
+            vboxVHWACommandCheckHostCmds(pDev);
+
+            if(
+                        ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
+                        || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
+        //                || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
+        //                || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
+                        )
+            {
+                lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
+            }
+            else
+            {
+                lpGetBltStatus->ddRVal = DD_OK;
+            }
         }
         else
@@ -1612,7 +1649,4 @@
 
     DISPDBG((0, "%s\n", __FUNCTION__));
-
-    /* ensure we have host cmds processed to update pending blits and flips */
-    vboxVHWACommandCheckHostCmds(pDev);
 
     if(
@@ -1624,5 +1658,21 @@
                 )
     {
-        lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING;
+        /* ensure we have host cmds processed to update pending blits and flips */
+        vboxVHWACommandCheckHostCmds(pDev);
+
+        if(
+    //                ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
+    //                || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
+    //                ||
+                    ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
+                    || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
+                    )
+        {
+            lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING;
+        }
+        else
+        {
+            lpGetFlipStatus->ddRVal = DD_OK;
+        }
     }
     else
@@ -1679,5 +1729,5 @@
         pBody->u.in.yPos = lpSetOverlayPosition->lYPos;
 
-        vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
+        vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
         lpSetOverlayPosition->ddRVal = DD_OK;
     }
@@ -1728,4 +1778,10 @@
         {
             pSrcDesc->bHidden = false;
+            if(pSrcDesc->UpdatedMemRegion.bValid)
+            {
+                pBody->u.in.xUpdatedSrcMemValid = 1;
+                vboxVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect);
+                vboxVHWARegionClear(&pSrcDesc->UpdatedMemRegion);
+            }
         }
 
@@ -1738,5 +1794,5 @@
         }
 
-        vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
+        vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
         lpUpdateOverlay->ddRVal = DD_OK;
     }
@@ -1744,4 +1800,88 @@
     return DDHAL_DRIVER_HANDLED;
 }
+#else
+DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA  lpSetColorKey)
+{
+    DISPDBG((0, "%s\n", __FUNCTION__));
+    lpSetColorKey->ddRVal = DD_OK;
+    return DDHAL_DRIVER_HANDLED;
+}
+
+DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA  lpAddAttachedSurface)
+{
+    DISPDBG((0, "%s\n", __FUNCTION__));
+    lpAddAttachedSurface->ddRVal = DD_OK;
+    return DDHAL_DRIVER_HANDLED;
+}
+
+DWORD APIENTRY DdBlt(PDD_BLTDATA  lpBlt)
+{
+    DISPDBG((0, "%s\n", __FUNCTION__));
+    lpBlt->ddRVal = DD_OK;
+    return DDHAL_DRIVER_HANDLED;
+}
+
+//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA  lpDestroySurface)
+//{
+//    DISPDBG((0, "%s\n", __FUNCTION__));
+//    lpDestroySurface->ddRVal = DD_OK;
+//    return DDHAL_DRIVER_HANDLED;
+//}
+
+DWORD APIENTRY DdFlip(PDD_FLIPDATA  lpFlip)
+{
+    DISPDBG((0, "%s\n", __FUNCTION__));
+    lpFlip->ddRVal = DD_OK;
+    return DDHAL_DRIVER_HANDLED;
+}
+
+DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA  lpGetBltStatus)
+{
+    DISPDBG((0, "%s\n", __FUNCTION__));
+
+    if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
+    {
+        lpGetBltStatus->ddRVal = DD_OK;
+    }
+    else
+    {
+        lpGetBltStatus->ddRVal = DD_OK;
+    }
+
+    return DDHAL_DRIVER_HANDLED;
+}
+
+DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA  lpGetFlipStatus)
+{
+    DISPDBG((0, "%s\n", __FUNCTION__));
+    if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
+    {
+        lpGetFlipStatus->ddRVal = DD_OK;
+    }
+    else
+    {
+        lpGetFlipStatus->ddRVal = DD_OK;
+    }
+
+    return DDHAL_DRIVER_HANDLED;
+}
+
+DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA  lpSetOverlayPosition)
+{
+    DISPDBG((0, "%s\n", __FUNCTION__));
+
+    lpSetOverlayPosition->ddRVal = DD_OK;
+    return DDHAL_DRIVER_HANDLED;
+}
+
+DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA  lpUpdateOverlay)
+{
+    DISPDBG((0, "%s\n", __FUNCTION__));
+
+    lpUpdateOverlay->ddRVal = DD_OK;
+    return DDHAL_DRIVER_HANDLED;
+}
+
+#endif
 
 //-----------------------------------------------------------------------------
@@ -1813,4 +1953,5 @@
 static DWORD rops[DD_ROP_SPACE] = { 0 };
 
+#if 1
 static bool
 getDDHALInfo(
@@ -1831,4 +1972,12 @@
                      rops,
                      sizeof(ropListNT)/sizeof(ropListNT[0]));
+
+        //
+        // ROPS supported
+        //
+        for( i=0;i<DD_ROP_SPACE;i++ )
+        {
+            pHALInfo->ddCaps.dwRops[i] = rops[i];
+        }
     }
 
@@ -1861,8 +2010,8 @@
     // We need to flag we can run in windowed mode, otherwise we
     // might get restricted by apps to run in fullscreen only
-    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
+//    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
 
     // Also permit surfaces wider than the display buffer.
-    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
+//    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
 //#endif
 
@@ -1931,15 +2080,15 @@
     }
 
-    if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
-            && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTFOURCC))
-    {
-        pHALInfo->ddCaps.dwCaps |= DDCAPS_BLTFOURCC;
-
-        // Enable copy blts between Four CC formats for DShow acceleration
-        pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COPYFOURCC;
-    }
-
-    if((VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) || VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
-            && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_COLORKEY))
+//    if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
+//            && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTFOURCC))
+//    {
+//        pHALInfo->ddCaps.dwCaps |= DDCAPS_BLTFOURCC;
+//
+//        // Enable copy blts between Four CC formats for DShow acceleration
+//        pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COPYFOURCC;
+//    }
+
+//    if((VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) || VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
+//            && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_COLORKEY))
     {
         pHALInfo->ddCaps.dwCKeyCaps = vboxVHWAToDDCKEYCAPS(pDev->vhwaInfo.colorKeyCaps);
@@ -2055,11 +2204,4 @@
 //                                                  DDBD_8;
 
-    //
-    // ROPS supported
-    //
-    for( i=0;i<DD_ROP_SPACE;i++ )
-    {
-        pHALInfo->ddCaps.dwRops[i] = rops[i];
-    }
 
 //Reenable:    // For DX5 and beyond we support this new informational callback.
@@ -2075,9 +2217,268 @@
     return true;
 } // getDDHALInfo
-
-static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
-{
-    vboxVHWACommandFree(ppdev, pCmd);
-}
+#else
+bool
+getDDHALInfo2(
+    PPDEV pDev,
+    DD_HALINFO* pHALInfo)
+{
+    int i;
+
+#if 0
+    /* TODO: only enable features supported by the host backend & host hw
+     * for now this just combines all caps we might use */
+
+    // Setup the ROPS we do.
+    setupRops( ropListNT,
+                 rops,
+                 sizeof(ropListNT)/sizeof(ropListNT[0]));
+
+    // The most basic DirectDraw functionality
+    pHALInfo->ddCaps.dwCaps |=   DDCAPS_BLT
+                                 | DDCAPS_BLTQUEUE
+                                 | DDCAPS_BLTCOLORFILL
+//                                | DDCAPS_READSCANLINE
+                                ;
+#endif
+    pHALInfo->ddCaps.ddsCaps.dwCaps |=   DDSCAPS_OFFSCREENPLAIN
+                                         | DDSCAPS_PRIMARYSURFACE
+                                         | DDSCAPS_FLIP;
+#if 0
+    pHALInfo->ddCaps.dwCaps |= DDCAPS_3D           |
+                               DDCAPS_BLTDEPTHFILL;
+
+    pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE |
+                                       DDSCAPS_ZBUFFER |
+                                       DDSCAPS_ALPHA;
+#endif
+    pHALInfo->ddCaps.dwCaps2 = 0;
+
+//#if DX7_TEXMANAGEMENT
+    // We need to set this bit up in order to be able to do
+    // out own texture management
+//    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGETEXTURE;
+//#if DX8_DDI
+//    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGERESOURCE;
+//#endif
+//#endif
+
+//#if DX8_DDI
+    // We need to flag we can run in windowed mode, otherwise we
+    // might get restricted by apps to run in fullscreen only
+    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
+//#endif
+
+//#if DX8_DDI
+    // We need to flag we support dynamic textures. That is , apps can
+        // lock with high frequency video memory textures without paying a
+        // penalty for it. Since on this sample driver we only support
+        // linear memory formats for textures we don't need to do anything
+        // else for this support. Otherwise we would have to keep two surfaces
+        // for textures created with the DDSCAPS2_HINTDYNAMIC hint in order
+        // to efficiently do the linear<->swizzled transformation or keep the
+        // texture permanantly in an unswizzled state.
+//        pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_DYNAMICTEXTURES;
+    #if DX9_DDI
+        // Notice that dynamic textures MUST be supported in order to instantiate a DX9 device
+    #endif // DX9_DDI
+//#endif
+
+//    pHALInfo->ddCaps.dwFXCaps = 0;
+
+    // P3RX can do:
+    // 1. Stretching/Shrinking
+    // 2. YUV->RGB conversion
+    // 3. Mirroring in X and Y
+    // 4. ColorKeying from a source color and a source color space
+    pHALInfo->ddCaps.dwCaps |=
+#if 0
+        DDCAPS_BLTSTRETCH
+                               | DDCAPS_BLTFOURCC
+                               |
+#endif
+                               DDCAPS_COLORKEY
+//                               | DDCAPS_CANBLTSYSMEM
+                               ;
+#if 0
+    // Special effects caps
+    pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTSTRETCHY  |
+                                DDFXCAPS_BLTSTRETCHX  |
+                                DDFXCAPS_BLTSTRETCHYN |
+                                DDFXCAPS_BLTSTRETCHXN |
+                                DDFXCAPS_BLTSHRINKY   |
+                                DDFXCAPS_BLTSHRINKX   |
+                                DDFXCAPS_BLTSHRINKYN  |
+                                DDFXCAPS_BLTSHRINKXN;
+
+    // ColorKey caps
+    pHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_SRCBLT         |
+                                  DDCKEYCAPS_SRCBLTCLRSPACE |
+                                  DDCKEYCAPS_DESTBLT        |
+                                  DDCKEYCAPS_DESTBLTCLRSPACE;
+#endif
+//    pHALInfo->ddCaps.dwSVBCaps = DDCAPS_BLT;
+
+//    // We can do a texture from sysmem to video mem.
+//    pHALInfo->ddCaps.dwSVBCKeyCaps |= DDCKEYCAPS_DESTBLT         |
+//                                     DDCKEYCAPS_DESTBLTCLRSPACE;
+    pHALInfo->ddCaps.dwSVBFXCaps = 0;
+
+//    // Fill in the sysmem->vidmem rops (only can copy);
+//    for( i=0;i<DD_ROP_SPACE;i++ )
+//    {
+//        pHALInfo->ddCaps.dwSVBRops[i] = rops[i];
+//    }
+#if 0
+    //mirroring with blitting
+    pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTMIRRORUPDOWN  |
+                                DDFXCAPS_BLTMIRRORLEFTRIGHT;
+
+    pHALInfo->ddCaps.dwCKeyCaps |=  DDCKEYCAPS_SRCBLTCLRSPACEYUV;
+
+    pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
+#endif
+//#if DX7_STEREO
+//    // Report the stereo capability back to runtime
+//    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_STEREO;
+//    pHALInfo->ddCaps.dwSVCaps = DDSVCAPS_STEREOSEQUENTIAL;
+//#endif
+
+    // Z Buffer is only 16 Bits
+//    pHALInfo->ddCaps.dwZBufferBitDepths = DDBD_16;
+//    pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
+
+        pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
+
+    {
+//#ifdef SUPPORT_VIDEOPORT
+//        // We support 1 video port.  Must set CurrVideoPorts to 0
+//        // We can't do interleaved bobbing yet - maybe in the future.
+//        pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_VIDEOPORT            |
+//                                    DDCAPS2_CANBOBNONINTERLEAVED;
+//
+//        pHALInfo->ddCaps.dwMaxVideoPorts = 1;
+//        pHALInfo->ddCaps.dwCurrVideoPorts = 0;
+//
+//
+//#endif // SUPPORT_VIDEOPORT
+
+
+        {
+            // Overlay is free to use.
+            pHALInfo->ddCaps.dwMaxVisibleOverlays = 1;
+            pHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
+
+            pHALInfo->ddCaps.dwCaps |=  DDCAPS_OVERLAY          |
+                                        DDCAPS_OVERLAYFOURCC    |
+                                        DDCAPS_OVERLAYSTRETCH   |
+                                        DDCAPS_COLORKEYHWASSIST |
+                                        DDCAPS_OVERLAYCANTCLIP;
+
+            pHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_SRCOVERLAY           |
+                                           DDCKEYCAPS_SRCOVERLAYONEACTIVE  |
+                                           DDCKEYCAPS_SRCOVERLAYYUV        |
+                                           DDCKEYCAPS_DESTOVERLAY          |
+                                           DDCKEYCAPS_DESTOVERLAYONEACTIVE |
+                                           DDCKEYCAPS_DESTOVERLAYYUV;
+
+            pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
+
+            pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYSHRINKX   |
+                                         DDFXCAPS_OVERLAYSHRINKXN  |
+                                         DDFXCAPS_OVERLAYSHRINKY   |
+                                         DDFXCAPS_OVERLAYSHRINKYN  |
+                                         DDFXCAPS_OVERLAYSTRETCHX  |
+                                         DDFXCAPS_OVERLAYSTRETCHXN |
+                                         DDFXCAPS_OVERLAYSTRETCHY  |
+                                         DDFXCAPS_OVERLAYSTRETCHYN;
+
+            // Indicates that Perm3 has no stretch ratio limitation
+            pHALInfo->ddCaps.dwMinOverlayStretch = 1;
+            pHALInfo->ddCaps.dwMaxOverlayStretch = 32000;
+        }
+    }
+
+//#ifdef W95_DDRAW
+//#ifdef USE_DD_CONTROL_COLOR
+//    // Enable colour control asc brightness, contrast, gamma.
+//    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COLORCONTROLPRIMARY;
+//#endif
+//#endif
+
+    // Also permit surfaces wider than the display buffer.
+    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
+#if 0
+    // Enable copy blts betweemn Four CC formats for DShow acceleration
+    pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COPYFOURCC;
+#endif
+    // Won't do Video-Sys mem Blits.
+    pHALInfo->ddCaps.dwVSBCaps = 0;
+    pHALInfo->ddCaps.dwVSBCKeyCaps = 0;
+    pHALInfo->ddCaps.dwVSBFXCaps = 0;
+    for( i=0;i<DD_ROP_SPACE;i++ )
+    {
+        pHALInfo->ddCaps.dwVSBRops[i] = 0;
+    }
+
+    // Won't do Sys-Sys mem Blits
+    pHALInfo->ddCaps.dwSSBCaps = 0;
+    pHALInfo->ddCaps.dwSSBCKeyCaps = 0;
+    pHALInfo->ddCaps.dwSSBFXCaps = 0;
+    for( i=0;i<DD_ROP_SPACE;i++ )
+    {
+        pHALInfo->ddCaps.dwSSBRops[i] = 0;
+    }
+
+    //
+    // bit depths supported for alpha and Z
+    //
+//    pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
+//                                                DDBD_4 |
+//                                                DDBD_8;
+//
+//    pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
+//                                                DDBD_8;
+//    pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
+//                                                  DDBD_2 |
+//                                                  DDBD_4 |
+//                                                  DDBD_8;
+#if 0
+    // No alpha blending for overlays, so I'm not sure what these should be.
+    // Because we support 32bpp overlays, it's just that you can't use the
+    // alpha bits for blending. Pass.
+    pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
+                                                DDBD_4 |
+                                                DDBD_8;
+
+    pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
+                                                DDBD_8;
+
+    pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
+                                                  DDBD_2 |
+                                                  DDBD_4 |
+                                                  DDBD_8;
+
+    //
+    // ROPS supported
+    //
+    for( i=0;i<DD_ROP_SPACE;i++ )
+    {
+        pHALInfo->ddCaps.dwRops[i] = rops[i];
+    }
+#endif
+//Reenable:    // For DX5 and beyond we support this new informational callback.
+//    pHALInfo->GetDriverInfo = DdGetDriverInfo;
+//    pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
+//
+//#if DX8_DDI
+//    // Flag our support for a new class of GUIDs that may come through
+//    // GetDriverInfo for DX8 drivers. (This support will be compulsory)
+//    pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFO2;
+//#endif DX8_DDI
+
+    return true;
+} // getDDHALInfo
+
+#endif
 
 static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
Index: trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h	(revision 21905)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h	(revision 21939)
@@ -110,5 +110,6 @@
     uint32_t cBitsPerPixel;
     bool bHidden;
-    VBOXVHWAREGION DirtyRegion;
+    VBOXVHWAREGION UpdatedMemRegion;
+    VBOXVHWAREGION NonupdatedMemRegion;
 }VBOXVHWASURFDESC, *PVBOXVHWASURFDESC;
 
@@ -307,4 +308,6 @@
 void vboxVHWARegionInit(PVBOXVHWAREGION pReg);
 void vboxVHWARegionClear(PVBOXVHWAREGION pReg);
+bool vboxVHWARegionValid(PVBOXVHWAREGION pReg);
+void vboxVHWARegionTrySubstitute(PVBOXVHWAREGION pReg, const RECTL *pRect);
 
 VBOXVHWACMD* vboxVHWACommandCreate (PPDEV ppdev, VBOXVHWACMD_TYPE enmCmd, VBOXVHWACMD_LENGTH cbCmd);
@@ -314,4 +317,5 @@
 void vboxVHWACommandSubmitAsynchByEvent (PPDEV ppdev, VBOXVHWACMD* pCmd, PEVENT pEvent);
 void vboxVHWACommandCheckHostCmds(PPDEV ppdev);
+void vboxVHWACommandSubmitAsynchAndComplete (PPDEV ppdev, VBOXVHWACMD* pCmd);
 
 int vboxVHWAInitHostInfo1(PPDEV ppdev);
Index: trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c	(revision 21905)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c	(revision 21939)
@@ -782,8 +782,8 @@
 
     /* complete it asynchronously by setting event */
-    pCmd->Flags |= VBOXVHWACMD_FLAG_ASYNCH_EVENT;
+    pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_EVENT;
     vboxHGSMIBufferSubmit (ppdev, pCmd);
 
-    if(!(ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags)  & VBOXVHWACMD_FLAG_ASYNCH))
+    if(!(ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags)  & VBOXVHWACMD_FLAG_HG_ASYNCH))
     {
         /* the command is completed */
@@ -800,5 +800,5 @@
     if(brc)
     {
-        pCmd->Flags = VBOXVHWACMD_FLAG_ASYNCH_IRQ;
+        pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ;
         vboxVHWACommandSubmitAsynchByEvent (ppdev, pCmd, pEvent);
 
@@ -822,11 +822,32 @@
     pCmd->GuestVBVAReserved2 = (uintptr_t)pContext;
 
-    pCmd->Flags = 0;
     vboxHGSMIBufferSubmit (ppdev, pCmd);
 
-    if(!(pCmd->Flags  & VBOXVHWACMD_FLAG_ASYNCH))
+    if(!(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH))
     {
         /* the command is completed */
         pfnCompletion(ppdev, pCmd, pContext);
+    }
+}
+
+static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
+{
+    vboxVHWACommandFree(ppdev, pCmd);
+}
+
+void vboxVHWACommandSubmitAsynchAndComplete (PPDEV ppdev, VBOXVHWACMD* pCmd)
+{
+//    Assert(0);
+    pCmd->GuestVBVAReserved1 = (uintptr_t)vboxVHWAFreeCmdCompletion;
+
+    pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION;
+
+    vboxHGSMIBufferSubmit (ppdev, pCmd);
+
+    if(!(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH)
+            || pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED)
+    {
+        /* the command is completed */
+        vboxVHWAFreeCmdCompletion(ppdev, pCmd, NULL);
     }
 }
@@ -919,5 +940,6 @@
     int rc = VINF_SUCCESS;
 
-    if(pInfo)
+    Assert(pInfo);
+    if(!pInfo)
         return VERR_OUT_OF_RESOURCES;
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 21905)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 21939)
@@ -1327,5 +1327,5 @@
         {
             /* schedule a DPC*/
-            BOOLEAN bResult = VideoPortQueueDpc(PrimaryExtension, VBoxVideoHGSMIDpc, NULL);
+            BOOLEAN bResult = VideoPortQueueDpc(PrimaryExtension, VBoxVideoHGSMIDpc, (PVOID)1);
             Assert(bResult);
         }
