Index: /trunk/include/VBox/VBoxCrHgsmi.h
===================================================================
--- /trunk/include/VBox/VBoxCrHgsmi.h	(revision 33713)
+++ /trunk/include/VBox/VBoxCrHgsmi.h	(revision 33714)
@@ -39,4 +39,5 @@
 #endif
 
+#ifdef VBOX_CRHGSMI_WITH_D3DDEV
 typedef void * HVBOXCRHGSMI_CLIENT;
 
@@ -54,6 +55,11 @@
 
 VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit(PVBOXCRHGSMI_CALLBACKS pCallbacks);
+VBOXCRHGSMI_DECL(HVBOXCRHGSMI_CLIENT) VBoxCrHgsmiQueryClient();
+#else
+VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit();
+VBOXCRHGSMI_DECL(PVBOXUHGSMI) VBoxCrHgsmiCreate();
+VBOXCRHGSMI_DECL(void) VBoxCrHgsmiDestroy(PVBOXUHGSMI pHgsmi);
+#endif
 VBOXCRHGSMI_DECL(int) VBoxCrHgsmiTerm();
-VBOXCRHGSMI_DECL(HVBOXCRHGSMI_CLIENT) VBoxCrHgsmiQueryClient();
 
 VBOXCRHGSMI_DECL(void) VBoxCrHgsmiLog(char * szString);
Index: /trunk/include/VBox/VBoxVideo.h
===================================================================
--- /trunk/include/VBox/VBoxVideo.h	(revision 33713)
+++ /trunk/include/VBox/VBoxVideo.h	(revision 33714)
@@ -740,4 +740,5 @@
             VBOXVHWA_OVERLAYFX desc;
             VBOXVHWA_RECTL xUpdatedSrcMemRect;
+            VBOXVHWA_RECTL xUpdatedDstMemRect;
         } in;
     } u;
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxCrHgsmi.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxCrHgsmi.cpp	(revision 33713)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxCrHgsmi.cpp	(revision 33714)
@@ -4,9 +4,12 @@
 #include "VBoxUhgsmiKmt.h"
 
+static VBOXDISPKMT_CALLBACKS g_VBoxCrHgsmiKmtCallbacks;
+static int g_bVBoxKmtCallbacksInited = 0;
+
+#ifdef VBOX_CRHGSMI_WITH_D3DDEV
 static VBOXCRHGSMI_CALLBACKS g_VBoxCrHgsmiCallbacks;
 static HMODULE g_hVBoxCrHgsmiProvider = NULL;
 static uint32_t g_cVBoxCrHgsmiProvider = 0;
 
-static VBOXDISPKMT_CALLBACKS g_VBoxCrHgsmiKmtCallbacks;
 
 typedef VBOXWDDMDISP_DECL(int) FNVBOXDISPCRHGSMI_INIT(PVBOXCRHGSMI_CALLBACKS pCallbacks);
@@ -25,17 +28,16 @@
 VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit(PVBOXCRHGSMI_CALLBACKS pCallbacks)
 {
-    static int bKmtCallbacksInited = 0;
-    if (!bKmtCallbacksInited)
+    if (!g_bVBoxKmtCallbacksInited)
     {
         HRESULT hr = vboxDispKmtCallbacksInit(&g_VBoxCrHgsmiKmtCallbacks);
         Assert(hr == S_OK);
         if (hr == S_OK)
-            bKmtCallbacksInited = 1;
+            g_bVBoxKmtCallbacksInited = 1;
         else
-            bKmtCallbacksInited = -1;
-    }
-
-    Assert(bKmtCallbacksInited);
-    if (bKmtCallbacksInited < 0)
+            g_bVBoxKmtCallbacksInited = -1;
+    }
+
+    Assert(g_bVBoxKmtCallbacksInited);
+    if (g_bVBoxKmtCallbacksInited < 0)
     {
         Assert(0);
@@ -135,8 +137,62 @@
     return NULL;
 }
+#else
+VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit()
+{
+    if (!g_bVBoxKmtCallbacksInited)
+    {
+        HRESULT hr = vboxDispKmtCallbacksInit(&g_VBoxCrHgsmiKmtCallbacks);
+        Assert(hr == S_OK);
+        if (hr == S_OK)
+            g_bVBoxKmtCallbacksInited = 1;
+        else
+            g_bVBoxKmtCallbacksInited = -1;
+    }
+
+    Assert(g_bVBoxKmtCallbacksInited);
+    if (g_bVBoxKmtCallbacksInited < 0)
+    {
+        Assert(0);
+        return VERR_NOT_SUPPORTED;
+    }
+
+    return VINF_SUCCESS;
+}
+
+VBOXCRHGSMI_DECL(PVBOXUHGSMI) VBoxCrHgsmiCreate()
+{
+    PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = (PVBOXUHGSMI_PRIVATE_KMT)RTMemAllocZ(sizeof (*pHgsmiGL));
+    if (pHgsmiGL)
+    {
+#if 0
+        HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
+#else
+        HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
+#endif
+        Assert(hr == S_OK);
+        if (hr == S_OK)
+        {
+            return &pHgsmiGL->BasePrivate.Base;
+        }
+        RTMemFree(pHgsmiGL);
+    }
+
+    return NULL;
+}
+
+VBOXCRHGSMI_DECL(void) VBoxCrHgsmiDestroy(PVBOXUHGSMI pHgsmi)
+{
+    PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = VBOXUHGSMIKMT_GET(pHgsmi);
+    HRESULT hr = vboxUhgsmiKmtDestroy(pHgsmiGL);
+    Assert(hr == S_OK);
+    if (hr == S_OK)
+    {
+        RTMemFree(pHgsmiGL);
+    }
+}
+#endif
 
 VBOXCRHGSMI_DECL(int) VBoxCrHgsmiTerm()
 {
-    Assert(0);
 #if 0
     PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = gt_pHgsmiGL;
@@ -151,4 +207,8 @@
         g_pfnVBoxDispCrHgsmiTerm();
 #endif
+    if (g_bVBoxKmtCallbacksInited > 0)
+    {
+        vboxDispKmtCallbacksTerm(&g_VBoxCrHgsmiKmtCallbacks);
+    }
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 33713)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 33714)
@@ -740,5 +740,4 @@
 #ifdef VBOX_WITH_CRHGSMI
 static __declspec(thread) PVBOXUHGSMI_PRIVATE_BASE gt_pHgsmi = NULL;
-#endif
 
 VBOXWDDMDISP_DECL(int) VBoxDispCrHgsmiInit(PVBOXCRHGSMI_CALLBACKS pCallbacks)
@@ -786,5 +785,4 @@
 }
 
-#ifdef VBOX_WITH_CRHGSMI
 static HRESULT vboxUhgsmiGlobalRetain()
 {
@@ -876,4 +874,19 @@
 #define VBOXDISPCRHGSMI_SCOPE_SET_DEV(_pDev) do {} while(0)
 #define VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL() do {} while(0)
+
+VBOXWDDMDISP_DECL(int) VBoxDispCrHgsmiInit(void*)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+VBOXWDDMDISP_DECL(int) VBoxDispCrHgsmiTerm()
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+VBOXWDDMDISP_DECL(void*) VBoxDispCrHgsmiQueryClient()
+{
+    return NULL;
+}
 #endif
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxUhgsmiBase.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxUhgsmiBase.h	(revision 33713)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxUhgsmiBase.h	(revision 33714)
@@ -32,5 +32,7 @@
 {
     VBOXUHGSMI Base;
+#ifdef VBOX_CRHGSMI_WITH_D3DDEV
     HVBOXCRHGSMI_CLIENT hClient;
+#endif
 } VBOXUHGSMI_PRIVATE_BASE, *PVBOXUHGSMI_PRIVATE_BASE;
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxUhgsmiKmt.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxUhgsmiKmt.cpp	(revision 33713)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxUhgsmiKmt.cpp	(revision 33714)
@@ -437,5 +437,7 @@
     pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiKmtBufferCreate;
     pHgsmi->BasePrivate.Base.pfnBufferSubmitAsynch = vboxUhgsmiKmtBufferSubmitAsynch;
+#ifdef VBOX_CRHGSMI_WITH_D3DDEV
     pHgsmi->BasePrivate.hClient = NULL;
+#endif
     return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
 }
@@ -445,5 +447,7 @@
     pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiKmtEscBufferCreate;
     pHgsmi->BasePrivate.Base.pfnBufferSubmitAsynch = vboxUhgsmiKmtEscBufferSubmitAsynch;
+#ifdef VBOX_CRHGSMI_WITH_D3DDEV
     pHgsmi->BasePrivate.hClient = NULL;
+#endif
     return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
 }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp	(revision 33713)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp	(revision 33714)
@@ -920,4 +920,24 @@
 }
 
+static void vboxVhwaHlpOverlayListAdd(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay)
+{
+    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId];
+    KIRQL OldIrql;
+    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
+    ASMAtomicIncU32(&pSource->cOverlays);
+    InsertHeadList(&pSource->OverlayList, &pOverlay->ListEntry);
+    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
+}
+
+static void vboxVhwaHlpOverlayListRemove(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay)
+{
+    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId];
+    KIRQL OldIrql;
+    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
+    ASMAtomicDecU32(&pSource->cOverlays);
+    RemoveEntryList(&pOverlay->ListEntry);
+    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
+}
+
 AssertCompile(sizeof (RECT) == sizeof (VBOXVHWA_RECTL));
 AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, left));
@@ -930,5 +950,5 @@
 AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(VBOXVHWA_RECTL, bottom));
 
-int vboxVhwaHlpOverlayUpdate(PVBOXWDDM_OVERLAY pOverlay, const DXGK_OVERLAYINFO *pOverlayInfo)
+int vboxVhwaHlpOverlayUpdate(PVBOXWDDM_OVERLAY pOverlay, const DXGK_OVERLAYINFO *pOverlayInfo, RECT * pDstUpdateRect)
 {
     PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pOverlayInfo->hAllocation;
@@ -982,5 +1002,4 @@
             if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID)
             {
-                pBody->u.in.xUpdatedSrcMemValid = 1;
                 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID)
                     pBody->u.in.xUpdatedSrcMemRect = *(VBOXVHWA_RECTL*)((void*)&pOurInfo->DirtyRegion.Rect);
@@ -993,4 +1012,9 @@
             }
 
+            if (pDstUpdateRect)
+            {
+                pBody->u.in.xUpdatedDstMemRect = *(VBOXVHWA_RECTL*)((void*)pDstUpdateRect);
+            }
+
             /* we're not interested in completion, just send the command */
             vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd);
@@ -1011,7 +1035,15 @@
 }
 
+int vboxVhwaHlpOverlayUpdate(PVBOXWDDM_OVERLAY pOverlay, const DXGK_OVERLAYINFO *pOverlayInfo)
+{
+    return vboxVhwaHlpOverlayUpdate(pOverlay, pOverlayInfo, NULL);
+}
+
 int vboxVhwaHlpOverlayDestroy(PVBOXWDDM_OVERLAY pOverlay)
 {
     int rc = VINF_SUCCESS;
+
+    vboxVhwaHlpOverlayListRemove(pOverlay->pDevExt, pOverlay);
+
     for (uint32_t i = 0; i < pOverlay->pResource->cAllocations; ++i)
     {
@@ -1066,5 +1098,15 @@
             pOverlay->pResource = pRc;
             pOverlay->VidPnSourceId = VidPnSourceId;
-            rc = vboxVhwaHlpOverlayUpdate(pOverlay, pOverlayInfo);
+
+            vboxVhwaHlpOverlayListAdd(pDevExt, pOverlay);
+#ifdef VBOXWDDM_RENDER_FROM_SHADOW
+            RECT DstRect;
+            vboxVhwaHlpOverlayDstRectGet(pDevExt, pOverlay, &DstRect);
+            NTSTATUS Status = vboxVdmaHlpUpdatePrimary(pDevExt, VidPnSourceId, &DstRect);
+            Assert(Status == STATUS_SUCCESS);
+            /* ignore primary update failure */
+            Status = STATUS_SUCCESS;
+#endif
+            rc = vboxVhwaHlpOverlayUpdate(pOverlay, pOverlayInfo, &DstRect);
             if (!RT_SUCCESS(rc))
             {
@@ -1089,24 +1131,4 @@
     PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
     return !ASMAtomicReadU32(&pSource->cOverlays);
-}
-
-void vboxVhwaHlpOverlayListAdd(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay)
-{
-    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId];
-    KIRQL OldIrql;
-    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
-    ASMAtomicIncU32(&pSource->cOverlays);
-    InsertHeadList(&pSource->OverlayList, &pOverlay->ListEntry);
-    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
-}
-
-void vboxVhwaHlpOverlayListRemove(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay)
-{
-    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId];
-    KIRQL OldIrql;
-    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
-    ASMAtomicDecU32(&pSource->cOverlays);
-    RemoveEntryList(&pOverlay->ListEntry);
-    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
 }
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h	(revision 33713)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h	(revision 33714)
@@ -64,6 +64,6 @@
 
 BOOLEAN vboxVhwaHlpOverlayListIsEmpty(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId);
-void vboxVhwaHlpOverlayListAdd(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay);
-void vboxVhwaHlpOverlayListRemove(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay);
+//void vboxVhwaHlpOverlayListAdd(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay);
+//void vboxVhwaHlpOverlayListRemove(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay);
 void vboxVhwaHlpOverlayDstRectUnion(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RECT *pRect);
 void vboxVhwaHlpOverlayDstRectGet(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay, RECT *pRect);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVidPn.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVidPn.cpp	(revision 33713)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVidPn.cpp	(revision 33714)
@@ -533,4 +533,8 @@
     {
         D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
+        /* disable 24 bpp for now */
+        if (pModes[i].BitsPerPlane == 24)
+            continue;
+
         Status = pNewVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
         Assert(Status == STATUS_SUCCESS);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 33713)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 33714)
@@ -4311,13 +4311,4 @@
         if (RT_SUCCESS(rc))
         {
-            vboxVhwaHlpOverlayListAdd(pDevExt, pOverlay);
-#ifdef VBOXWDDM_RENDER_FROM_SHADOW
-            RECT DstRect;
-            vboxVhwaHlpOverlayDstRectGet(pDevExt, pOverlay, &DstRect);
-            Status = vboxVdmaHlpUpdatePrimary(pDevExt, pCreateOverlay->VidPnSourceId, &DstRect);
-            Assert(Status == STATUS_SUCCESS);
-            /* ignore primary update failure */
-            Status = STATUS_SUCCESS;
-#endif
             pCreateOverlay->hOverlay = pOverlay;
         }
@@ -5147,5 +5138,4 @@
     PVBOXWDDM_OVERLAY pOverlay = (PVBOXWDDM_OVERLAY)hOverlay;
     Assert(pOverlay);
-    vboxVhwaHlpOverlayListRemove(pOverlay->pDevExt, pOverlay);
     int rc = vboxVhwaHlpOverlayDestroy(pOverlay);
     AssertRC(rc);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp	(revision 33713)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp	(revision 33714)
@@ -2739,8 +2739,13 @@
 
 #ifdef VBOX_WITH_WDDM
-    if(pCmd->u.in.xUpdatedSrcMemValid)
+    if(pCmd->u.in.xUpdatedSrcMemRect.right)
     {
         QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.xUpdatedSrcMemRect);
         pSrcSurf->updatedMem(&r);
+    }
+    if(pCmd->u.in.xUpdatedDstMemRect.right)
+    {
+        QRect r = VBOXVHWA_CONSTRUCT_QRECT_FROM_RECTL_WH(&pCmd->u.in.xUpdatedDstMemRect);
+        pDstSurf->updatedMem(&r);
     }
 #endif
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_net.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_net.h	(revision 33713)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_net.h	(revision 33714)
@@ -106,4 +106,13 @@
 } CRMultiBuffer;
 
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+typedef struct CRVBOXHGSMI_CLIENT {
+    struct VBOXUHGSMI *pHgsmi;
+    struct VBOXUHGSMI_BUFFER *pCmdBuffer;
+    struct VBOXUHGSMI_BUFFER *pHGBuffer;
+    void *pvHGBuffer;
+    struct CRBufferPool_t *bufpool;
+} CRVBOXHGSMI_CLIENT, *PCRVBOXHGSMI_CLIENT;
+#endif
 /**
  * Chromium network connection (bidirectional).
@@ -224,4 +233,9 @@
 #ifdef IN_GUEST
     uint32_t u32InjectClientID;
+# ifdef VBOX_WITH_CRHGSMI
+#  ifndef VBOX_CRHGSMI_WITH_D3DDEV
+    CRVBOXHGSMI_CLIENT HgsmiClient;
+#  endif
+# endif
 #endif
     /* Used on host side to indicate that we are not allowed to store above pointers for later use
Index: /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c	(revision 33713)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c	(revision 33714)
@@ -16,5 +16,4 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
-
 #ifdef RT_OS_WINDOWS
     #include <windows.h>
@@ -226,11 +225,4 @@
 
 #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
-typedef struct CRVBOXHGSMI_CLIENT {
-    PVBOXUHGSMI pHgsmi;
-    PVBOXUHGSMI_BUFFER pCmdBuffer;
-    PVBOXUHGSMI_BUFFER pHGBuffer;
-    void *pvHGBuffer;
-    CRBufferPool *bufpool;
-} CRVBOXHGSMI_CLIENT, *PCRVBOXHGSMI_CLIENT;
 
 /* add sizeof header + page align */
@@ -243,9 +235,119 @@
 #define CRVBOXHGSMI_BUF_OFFSET(_st2, _st1) ((uint32_t)(((uint8_t*)(_st2)) - ((uint8_t*)(_st1))))
 
+static int _crVBoxHGSMIClientInit(PCRVBOXHGSMI_CLIENT pClient, PVBOXUHGSMI pHgsmi)
+{
+    int rc;
+    pClient->pHgsmi = pHgsmi;
+    rc = pHgsmi->pfnBufferCreate(pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(1),
+                            VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT,
+                            NULL,
+                            &pClient->pCmdBuffer);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        rc = pHgsmi->pfnBufferCreate(pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(1),
+                                        VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT,
+                                        NULL,
+                                        &pClient->pHGBuffer);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+        {
+            pClient->pvHGBuffer = NULL;
+            pClient->bufpool = crBufferPoolInit(16);
+            return VINF_SUCCESS;
+        }
+        pClient->pCmdBuffer->pfnDestroy(pClient->pCmdBuffer);
+    }
+    pClient->pHgsmi = NULL;
+    return rc;
+}
+
+void _crVBoxHGSMIBufferFree(void *data)
+{
+    PVBOXUHGSMI_BUFFER pBuffer = (PVBOXUHGSMI_BUFFER)data;
+    pBuffer->pfnDestroy(pBuffer);
+}
+
+static int _crVBoxHGSMIClientTerm(PCRVBOXHGSMI_CLIENT pClient, PVBOXUHGSMI *ppHgsmi)
+{
+    if (pClient->bufpool)
+        crBufferPoolCallbackFree(pClient->bufpool, _crVBoxHGSMIBufferFree);
+    pClient->bufpool = NULL;
+
+    if (pClient->pHGBuffer)
+    {
+        pClient->pHGBuffer->pfnDestroy(pClient->pHGBuffer);
+        pClient->pHGBuffer = NULL;
+    }
+
+    if (pClient->pCmdBuffer)
+    {
+        pClient->pCmdBuffer->pfnDestroy(pClient->pCmdBuffer);
+        pClient->pCmdBuffer = NULL;
+    }
+
+    if (ppHgsmi)
+    {
+        *ppHgsmi = pClient->pHgsmi;
+    }
+    pClient->pHgsmi = NULL;
+
+    return VINF_SUCCESS;
+}
+
+
+#ifdef VBOX_CRHGSMI_WITH_D3DDEV
+
+DECLCALLBACK(HVBOXCRHGSMI_CLIENT) _crVBoxHGSMIClientCreate(PVBOXUHGSMI pHgsmi)
+{
+    PCRVBOXHGSMI_CLIENT pClient = crAlloc(sizeof (CRVBOXHGSMI_CLIENT));
+
+    if (pClient)
+    {
+        int rc = _crVBoxHGSMIClientInit(pClient, pHgsmi);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+            return (HVBOXCRHGSMI_CLIENT)pClient;
+
+        crFree(pCLient);
+    }
+
+    return NULL;
+}
+
+DECLCALLBACK(void) _crVBoxHGSMIClientDestroy(HVBOXCRHGSMI_CLIENT hClient)
+{
+    PCRVBOXHGSMI_CLIENT pClient = (PCRVBOXHGSMI_CLIENT)hClient;
+    _crVBoxHGSMIClientTerm(pClient, NULL);
+    crFree(pClient);
+}
+#endif
+
 DECLINLINE(PCRVBOXHGSMI_CLIENT) _crVBoxHGSMIClientGet(CRConnection *conn)
 {
+#ifdef VBOX_CRHGSMI_WITH_D3DDEV
     PCRVBOXHGSMI_CLIENT pClient = (PCRVBOXHGSMI_CLIENT)VBoxCrHgsmiQueryClient();
     Assert(pClient);
     return pClient;
+#else
+    if (conn->HgsmiClient.pHgsmi)
+        return &conn->HgsmiClient;
+    {
+        PVBOXUHGSMI pHgsmi = VBoxCrHgsmiCreate();
+        Assert(pHgsmi);
+        if (pHgsmi)
+        {
+            int rc = _crVBoxHGSMIClientInit(&conn->HgsmiClient, pHgsmi);
+            AssertRC(rc);
+            if (RT_SUCCESS(rc))
+            {
+                Assert(conn->HgsmiClient.pHgsmi);
+                return &conn->HgsmiClient;
+            }
+            VBoxCrHgsmiDestroy(pHgsmi);
+        }
+    }
+    return NULL;
+#endif
 }
 
@@ -1369,55 +1471,23 @@
 
 #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
-DECLCALLBACK(HVBOXCRHGSMI_CLIENT) _crVBoxHGSMIClientCreate(PVBOXUHGSMI pHgsmi)
-{
-    PCRVBOXHGSMI_CLIENT pClient = crAlloc(sizeof (CRVBOXHGSMI_CLIENT));
-
-    if (pClient)
+
+bool _crVBoxHGSMIInit()
+{
+#ifndef VBOX_CRHGSMI_WITH_D3DDEV
+    static
+#endif
+    int bHasHGSMI = -1;
+
+    if (bHasHGSMI < 0)
     {
         int rc;
-        pClient->pHgsmi = pHgsmi;
-        rc = pHgsmi->pfnBufferCreate(pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(1),
-                                VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT,
-                                NULL,
-                                &pClient->pCmdBuffer);
-        AssertRC(rc);
-        if (RT_SUCCESS(rc))
-        {
-            rc = pHgsmi->pfnBufferCreate(pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(1),
-                                            VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT,
-                                            NULL,
-                                            &pClient->pHGBuffer);
-            AssertRC(rc);
-            if (RT_SUCCESS(rc))
-            {
-                pClient->pvHGBuffer = NULL;
-                pClient->bufpool = crBufferPoolInit(16);
-                return (HVBOXCRHGSMI_CLIENT) pClient;
-            }
-            pClient->pCmdBuffer->pfnDestroy(pClient->pCmdBuffer);
-        }
-    }
-
-    return NULL;
-}
-
-DECLCALLBACK(void) _crVBoxHGSMIClientDestroy(HVBOXCRHGSMI_CLIENT hClient)
-{
-    Assert(0);
-
-    /* @todo */
-}
-
-bool _crVBoxHGSMIInit()
-{
-    int bHasHGSMI = -1;
-
-    if (bHasHGSMI < 0)
-    {
-        int rc;
+#ifndef VBOX_CRHGSMI_WITH_D3DDEV
+        rc = VBoxCrHgsmiInit();
+#else
         VBOXCRHGSMI_CALLBACKS Callbacks;
         Callbacks.pfnClientCreate = _crVBoxHGSMIClientCreate;
         Callbacks.pfnClientDestroy = _crVBoxHGSMIClientDestroy;
         rc = VBoxCrHgsmiInit(&Callbacks);
+#endif
         AssertRC(rc);
         if (RT_SUCCESS(rc))
@@ -2004,4 +2074,14 @@
 static void crVBoxHGSMIDoDisconnect( CRConnection *conn )
 {
+#ifndef VBOX_CRHGSMI_WITH_D3DDEV
+    if (conn->HgsmiClient.pHgsmi)
+    {
+        PVBOXUHGSMI pHgsmi;
+        _crVBoxHGSMIClientTerm(&conn->HgsmiClient, &pHgsmi);
+        Assert(pHgsmi);
+        VBoxCrHgsmiDestroy(pHgsmi);
+    }
+
+#endif
     crVBoxHGCMDoDisconnect(conn);
 }
