Index: /trunk/include/VBox/VBoxVideo.h
===================================================================
--- /trunk/include/VBox/VBoxVideo.h	(revision 29797)
+++ /trunk/include/VBox/VBoxVideo.h	(revision 29798)
@@ -948,4 +948,6 @@
 /* extended VBVA to be used with WDDM */
 #define VBVA_F_EXTENDED 0x00000004
+/* vbva offset is absolute VRAM offset */
+#define VBVA_F_ABSOFFSET 0x00000008
 #endif
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 29798)
@@ -1768,5 +1768,13 @@
 {
     vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
-    AssertBreakpoint();
+
+    PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
+    if (pDevice->DefaultContext.ContextInfo.hContext)
+    {
+        D3DDDICB_DESTROYCONTEXT DestroyContext;
+        DestroyContext.hContext = pDevice->DefaultContext.ContextInfo.hContext;
+        HRESULT tmpHr = pDevice->RtCallbacks.pfnDestroyContextCb(pDevice->hDevice, &DestroyContext);
+        Assert(tmpHr == S_OK);
+    }
     RTMemFree(hDevice);
     vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
@@ -1974,31 +1982,57 @@
         do
         {
+            Assert(!pCreateData->AllocationListSize
+                    && !pCreateData->PatchLocationListSize);
             if (!pCreateData->AllocationListSize
                     && !pCreateData->PatchLocationListSize)
             {
-                /* check whether this is a D3D or DDraw, use wine lib only in the former (D3D) case */
-                /* TODO: is this a correct way to check this ? */
-                if (pDevice->RtCallbacks.pfnCreateOverlayCb)
+                pDevice->DefaultContext.ContextInfo.NodeOrdinal = 0;
+                pDevice->DefaultContext.ContextInfo.EngineAffinity = 0;
+                pDevice->DefaultContext.ContextInfo.Flags.Value = 0;
+                pDevice->DefaultContext.ContextInfo.pPrivateDriverData = NULL;
+                pDevice->DefaultContext.ContextInfo.PrivateDriverDataSize = 0;
+                pDevice->DefaultContext.ContextInfo.hContext = 0;
+                pDevice->DefaultContext.ContextInfo.pCommandBuffer = NULL;
+                pDevice->DefaultContext.ContextInfo.CommandBufferSize = 0;
+                pDevice->DefaultContext.ContextInfo.pAllocationList = NULL;
+                pDevice->DefaultContext.ContextInfo.AllocationListSize = 0;
+                pDevice->DefaultContext.ContextInfo.pPatchLocationList = NULL;
+                pDevice->DefaultContext.ContextInfo.PatchLocationListSize = 0;
+
+                hr = pDevice->RtCallbacks.pfnCreateContextCb(pDevice->hDevice, &pDevice->DefaultContext.ContextInfo);
+                Assert(hr == S_OK);
+                if (hr == S_OK)
                 {
-                    /* DDraw */
-                    vboxVDbgPrint((__FUNCTION__": DirectDraw Device Created\n"));
-                    break;
-                }
-                else
-                {
-                    /* D3D */
-                    if (pAdapter->pD3D9If)
+                    if (pDevice->u32IfVersion > 7)
                     {
-                        /* */
-                        vboxVDbgPrint((__FUNCTION__": TODO: Implement D3D Device Creation\n"));
-                        break;
+                        /* D3D */
+                        if (pAdapter->pD3D9If)
+                        {
+                            /* */
+                            vboxVDbgPrint((__FUNCTION__": TODO: Implement D3D Device Creation\n"));
+                            break;
+                        }
+                        else
+                        {
+                            /* ballback */
+                            vboxVDbgPrint((__FUNCTION__": D3D Device Being Created, but D3D is unavailable\n"));
+                            break;
+                        }
                     }
                     else
                     {
-                        /* ballback */
-                        vboxVDbgPrint((__FUNCTION__": D3D Device Being Created, but D3D is unavailable\n"));
+                        /* DDraw */
+                        vboxVDbgPrint((__FUNCTION__": DirectDraw Device Created\n"));
                         break;
                     }
+
+                    D3DDDICB_DESTROYCONTEXT DestroyContext;
+                    DestroyContext.hContext = pDevice->DefaultContext.ContextInfo.hContext;
+
+                    HRESULT tmpHr = pDevice->RtCallbacks.pfnDestroyContextCb(pDevice->hDevice, &DestroyContext);
+                    Assert(tmpHr == S_OK);
                 }
+                else
+                    vboxVDbgPrintR((__FUNCTION__": pfnCreateContextCb failed, hr(%d)\n", hr));
             }
             else
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.h	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.h	(revision 29798)
@@ -55,4 +55,10 @@
 } VBOXWDDMDISP_ADAPTER, *PVBOXWDDMDISP_ADAPTER;
 
+typedef struct VBOXWDDMDISP_CONTEXT
+{
+    struct VBOXWDDMDISP_DEVICE *pDevice;
+    D3DDDICB_CREATECONTEXT ContextInfo;
+} VBOXWDDMDISP_CONTEXT, *PVBOXWDDMDISP_CONTEXT;
+
 typedef struct VBOXWDDMDISP_DEVICE
 {
@@ -65,4 +71,5 @@
     UINT cbCmdBuffer;
     D3DDDI_CREATEDEVICEFLAGS fFlags;
+    VBOXWDDMDISP_CONTEXT DefaultContext;
 } VBOXWDDMDISP_DEVICE, *PVBOXWDDMDISP_DEVICE;
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 29798)
@@ -861,5 +861,8 @@
                                 PVIDEO_POINTER_ATTRIBUTES pointerAttr,
                                 uint32_t cbLength);
-#ifndef VBOXWDDM
+
+#ifdef VBOXWDDM
+int VBoxFreeDisplaysHGSMI(PDEVICE_EXTENSION PrimaryExtension);
+#else
 DECLCALLBACK(void) hgsmiHostCmdComplete (HVBOXVIDEOHGSMI hHGSMI, struct _VBVAHOSTCMD * pCmd);
 DECLCALLBACK(int) hgsmiHostCmdRequest (HVBOXVIDEOHGSMI hHGSMI, uint8_t u8Channel, struct _VBVAHOSTCMD ** ppCmd);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideoHGSMI.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideoHGSMI.cpp	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideoHGSMI.cpp	(revision 29798)
@@ -1045,4 +1045,52 @@
 }
 
+#ifdef VBOXWDDM
+int VBoxFreeDisplaysHGSMI(PDEVICE_EXTENSION PrimaryExtension)
+{
+    int rc;
+    for (int i = PrimaryExtension->cSources-1; i >= 0; --i)
+    {
+        rc = vboxVbvaDisable(PrimaryExtension, &PrimaryExtension->aSources[i].Vbva);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+        {
+            rc = vboxVbvaDestroy(PrimaryExtension, &PrimaryExtension->aSources[i].Vbva);
+            AssertRC(rc);
+            if (RT_SUCCESS(rc))
+            {
+                rc = vboxVdmaDisable(PrimaryExtension, &PrimaryExtension->u.primary.Vdma);
+                AssertRC(rc);
+                if (RT_SUCCESS(rc))
+                {
+                    rc = vboxVdmaDestroy(PrimaryExtension, &PrimaryExtension->u.primary.Vdma);
+                    AssertRC(rc);
+                    if (RT_SUCCESS(rc))
+                    {
+                        /*rc = */VBoxUnmapAdapterMemory(PrimaryExtension, &PrimaryExtension->u.primary.pvMiniportHeap, PrimaryExtension->u.primary.cbMiniportHeap);
+/*
+                        AssertRC(rc);
+                        if (RT_SUCCESS(rc))
+*/
+                        {
+                            HGSMIHeapDestroy(&PrimaryExtension->u.primary.hgsmiAdapterHeap);
+
+                            /* Map the adapter information. It will be needed for HGSMI IO. */
+                            /*rc = */VBoxUnmapAdapterMemory(PrimaryExtension, &PrimaryExtension->u.primary.pvAdapterInformation, VBVA_ADAPTER_INFORMATION_SIZE);
+/*
+                            AssertRC(rc);
+                            if (RT_FAILURE(rc))
+                                drprintf((__FUNCTION__"VBoxUnmapAdapterMemory PrimaryExtension->u.primary.pvAdapterInformation failed, rc(%d)\n", rc));
+*/
+
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return rc;
+}
+#endif
 
 /*
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVbva.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVbva.cpp	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVbva.cpp	(revision 29798)
@@ -39,5 +39,5 @@
         VBVAENABLE *pEnable = &pEnableEx->Base;
         pEnable->u32Flags  = bEnable? VBVA_F_ENABLE: VBVA_F_DISABLE;
-        pEnable->u32Flags |= VBVA_F_EXTENDED;
+        pEnable->u32Flags |= VBVA_F_EXTENDED | VBVA_F_ABSOFFSET;
         pEnable->u32Offset = (uint32_t)pVbva->offVBVA;
         pEnable->i32Result = VERR_NOT_SUPPORTED;
@@ -119,4 +119,20 @@
 }
 
+int vboxVbvaDestroy(PDEVICE_EXTENSION pDevExt, VBOXVBVAINFO *pVbva)
+{
+    int rc = VINF_SUCCESS;
+    /*rc = */VBoxUnmapAdapterMemory(pDevExt, (void**)&pVbva->pVBVA, pVbva->cbVBVA);
+/*
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+*/
+        memset(pVbva, 0, sizeof(VBOXVBVAINFO));
+/*
+    else
+        drprintf((__FUNCTION__": VBoxUnmapAdapterMemory failed, rc (%d)\n", rc));
+*/
+    return rc;
+}
+
 /*
  * Private operations.
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVbva.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVbva.h	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVbva.h	(revision 29798)
@@ -25,4 +25,5 @@
 int vboxVbvaEnable (struct _DEVICE_EXTENSION* pDevExt, VBOXVBVAINFO *pVbva);
 int vboxVbvaDisable (struct _DEVICE_EXTENSION* pDevExt, VBOXVBVAINFO *pVbva);
+int vboxVbvaDestroy(PDEVICE_EXTENSION pDevExt, VBOXVBVAINFO *pVbva);
 int vboxVbvaCreate(struct _DEVICE_EXTENSION* pDevExt, VBOXVBVAINFO *pVbva, ULONG offBuffer, ULONG cbBuffer, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId);
 int vboxVbvaReportCmdOffset (struct _DEVICE_EXTENSION* pDevExt, VBOXVBVAINFO *pVbva, uint32_t offCmd);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp	(revision 29798)
@@ -403,2 +403,12 @@
     }
 }
+
+void vboxVHWAFree(PDEVICE_EXTENSION pDevExt)
+{
+    /* we do not allocate/map anything, just issue a Disable command
+     * to ensure all pending commands are flushed */
+    for (uint32_t i = 0; i < pDevExt->cSources; ++i)
+    {
+        vboxVHWADisable(pDevExt, i);
+    }
+}
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h	(revision 29798)
@@ -52,4 +52,5 @@
 int vboxVHWADisable(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId);
 void vboxVHWAInit(PDEVICE_EXTENSION pDevExt);
+void vboxVHWAFree(PDEVICE_EXTENSION pDevExt);
 
 #endif /* #ifndef ___VBoxVideoVhwa_h___ */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 29797)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 29798)
@@ -595,4 +595,16 @@
 }
 
+static void vboxWddmDevExtZeroinit(PDEVICE_EXTENSION pDevExt, CONST PDEVICE_OBJECT pPDO)
+{
+    memset(pDevExt, 0, sizeof (DEVICE_EXTENSION));
+    pDevExt->pPDO = pPDO;
+#ifdef VBOXWDDM_RENDER_FROM_SHADOW
+    for (int i = 0; i < RT_ELEMENTS(pDevExt->aSources); ++i)
+    {
+        pDevExt->aSources[i].offVram = VBOXVIDEOOFFSET_VOID;
+    }
+#endif
+}
+
 /* driver callbacks */
 NTSTATUS DxgkDdiAddDevice(
@@ -613,12 +625,6 @@
     if (pContext)
     {
-        pContext->pPDO = PhysicalDeviceObject;
+        vboxWddmDevExtZeroinit(pContext, PhysicalDeviceObject);
         *MiniportDeviceContext = pContext;
-#ifdef VBOXWDDM_RENDER_FROM_SHADOW
-        for (int i = 0; i < RT_ELEMENTS(pContext->aSources); ++i)
-        {
-            pContext->aSources[i].offVram = VBOXVIDEOOFFSET_VOID;
-        }
-#endif
     }
     else
@@ -694,4 +700,6 @@
                 {
                     drprintf(("VBoxVideoWddm: HGSMI failed to initialize, returning err\n"));
+
+                    VbglTerminate();
                     /* @todo: report a better status */
                     Status = STATUS_UNSUCCESSFUL;
@@ -729,10 +737,27 @@
     dfprintf(("==> "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
 
-    AssertBreakpoint();
-    /* @todo: fixme: implement */
-
-    dfprintf(("<== "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
-
-    return STATUS_SUCCESS;
+    vboxVDbgBreakF();
+
+    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* do everything we did on DxgkDdiStartDevice in the reverse order */
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    vboxVHWAFree(pDevExt);
+#endif
+
+    int rc = VBoxFreeDisplaysHGSMI(pDevExt);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        VbglTerminate();
+
+        /* revert back to the state we were right after the DxgkDdiAddDevice */
+        vboxWddmDevExtZeroinit(pDevExt, pDevExt->pPDO);
+    }
+    else
+        Status = STATUS_UNSUCCESSFUL;
+
+    return Status;
 }
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp	(revision 29797)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp	(revision 29798)
@@ -1568,5 +1568,11 @@
             {
                 /* Guest reported offset relative to view. */
-                uint32_t u32Offset = pEnable->u32Offset + pCtx->aViews[uScreenId].view.u32ViewOffset;
+                uint32_t u32Offset = pEnable->u32Offset;
+#ifdef VBOXWDDM_WITH_VBVA
+                if (!(pEnable->u32Flags & VBVA_F_ABSOFFSET))
+#endif
+                {
+                    u32Offset += pCtx->aViews[uScreenId].view.u32ViewOffset;
+                }
 
                 VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost (pIns, u32Offset);
Index: /trunk/src/VBox/GuestHost/HGSMI/HGSMICommon.cpp
===================================================================
--- /trunk/src/VBox/GuestHost/HGSMI/HGSMICommon.cpp	(revision 29797)
+++ /trunk/src/VBox/GuestHost/HGSMI/HGSMICommon.cpp	(revision 29798)
@@ -288,4 +288,5 @@
     if (pHeap)
     {
+        Assert(!pHeap->cRefs);
         pHeap->u.hPtr = NIL_RTHEAPSIMPLE;
         HGSMIAreaClear (&pHeap->area);
