Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp	(revision 42499)
@@ -24,142 +24,5 @@
 static VBOXDISPKMT_CALLBACKS g_VBoxCrHgsmiKmtCallbacks;
 static int g_bVBoxKmtCallbacksInited = 0;
-static uint32_t g_VBoxCrVersionMajor;
-static uint32_t g_VBoxCrVersionMinor;
 
-#ifdef VBOX_CRHGSMI_WITH_D3DDEV
-static VBOXCRHGSMI_CALLBACKS g_VBoxCrHgsmiCallbacks;
-static HMODULE g_hVBoxCrHgsmiProvider = NULL;
-static uint32_t g_cVBoxCrHgsmiProvider = 0;
-
-
-typedef VBOXWDDMDISP_DECL(int) FNVBOXDISPCRHGSMI_INIT(PVBOXCRHGSMI_CALLBACKS pCallbacks);
-typedef FNVBOXDISPCRHGSMI_INIT *PFNVBOXDISPCRHGSMI_INIT;
-
-typedef VBOXWDDMDISP_DECL(int) FNVBOXDISPCRHGSMI_TERM();
-typedef FNVBOXDISPCRHGSMI_TERM *PFNVBOXDISPCRHGSMI_TERM;
-
-typedef VBOXWDDMDISP_DECL(HVBOXCRHGSMI_CLIENT) FNVBOXDISPCRHGSMI_QUERY_CLIENT();
-typedef FNVBOXDISPCRHGSMI_QUERY_CLIENT *PFNVBOXDISPCRHGSMI_QUERY_CLIENT;
-
-static PFNVBOXDISPCRHGSMI_INIT g_pfnVBoxDispCrHgsmiInit = NULL;
-static PFNVBOXDISPCRHGSMI_TERM g_pfnVBoxDispCrHgsmiTerm = NULL;
-static PFNVBOXDISPCRHGSMI_QUERY_CLIENT g_pfnVBoxDispCrHgsmiQueryClient = NULL;
-
-VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit(PVBOXCRHGSMI_CALLBACKS pCallbacks)
-{
-    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;
-    }
-
-    g_VBoxCrHgsmiCallbacks = *pCallbacks;
-    if (!g_hVBoxCrHgsmiProvider)
-    {
-        g_hVBoxCrHgsmiProvider = GetModuleHandle(L"VBoxDispD3D");
-        if (g_hVBoxCrHgsmiProvider)
-        {
-            g_hVBoxCrHgsmiProvider = LoadLibrary(L"VBoxDispD3D");
-        }
-
-        if (g_hVBoxCrHgsmiProvider)
-        {
-            g_pfnVBoxDispCrHgsmiInit = (PFNVBOXDISPCRHGSMI_INIT)GetProcAddress(g_hVBoxCrHgsmiProvider, "VBoxDispCrHgsmiInit");
-            Assert(g_pfnVBoxDispCrHgsmiInit);
-            if (g_pfnVBoxDispCrHgsmiInit)
-            {
-                g_pfnVBoxDispCrHgsmiInit(pCallbacks);
-            }
-
-            g_pfnVBoxDispCrHgsmiTerm = (PFNVBOXDISPCRHGSMI_TERM)GetProcAddress(g_hVBoxCrHgsmiProvider, "VBoxDispCrHgsmiTerm");
-            Assert(g_pfnVBoxDispCrHgsmiTerm);
-
-            g_pfnVBoxDispCrHgsmiQueryClient = (PFNVBOXDISPCRHGSMI_QUERY_CLIENT)GetProcAddress(g_hVBoxCrHgsmiProvider, "VBoxDispCrHgsmiQueryClient");
-            Assert(g_pfnVBoxDispCrHgsmiQueryClient);
-        }
-#ifdef DEBUG_misha
-        else
-        {
-            DWORD winEr = GetLastError();
-            Assert(0);
-        }
-#endif
-    }
-
-    if (g_hVBoxCrHgsmiProvider)
-    {
-        if (g_pfnVBoxDispCrHgsmiInit)
-        {
-            g_pfnVBoxDispCrHgsmiInit(pCallbacks);
-        }
-        ++g_cVBoxCrHgsmiProvider;
-        return VINF_SUCCESS;
-    }
-
-    /* we're called from ogl ICD driver*/
-    Assert(0);
-
-    return VINF_SUCCESS;
-}
-
-static __declspec(thread) PVBOXUHGSMI_PRIVATE_KMT gt_pHgsmiGL = NULL;
-
-VBOXCRHGSMI_DECL(HVBOXCRHGSMI_CLIENT) VBoxCrHgsmiQueryClient()
-{
-
-    HVBOXCRHGSMI_CLIENT hClient;
-    if (g_pfnVBoxDispCrHgsmiQueryClient)
-    {
-        hClient = g_pfnVBoxDispCrHgsmiQueryClient();
-//#ifdef DEBUG_misha
-//        Assert(hClient);
-//#endif
-        if (hClient)
-            return hClient;
-    }
-    PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = gt_pHgsmiGL;
-    if (pHgsmiGL)
-    {
-        Assert(pHgsmiGL->BasePrivate.hClient);
-        return pHgsmiGL->BasePrivate.hClient;
-    }
-    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)
-        {
-            hClient = g_VBoxCrHgsmiCallbacks.pfnClientCreate(&pHgsmiGL->BasePrivate.Base);
-            Assert(hClient);
-            if (hClient)
-            {
-                pHgsmiGL->BasePrivate.hClient = hClient;
-                gt_pHgsmiGL = pHgsmiGL;
-                return hClient;
-            }
-            vboxUhgsmiKmtDestroy(pHgsmiGL);
-        }
-        RTMemFree(pHgsmiGL);
-    }
-
-    return NULL;
-}
-#else
 static int vboxCrHgsmiInitPerform(VBOXDISPKMT_CALLBACKS *pCallbacks)
 {
@@ -183,5 +46,5 @@
 }
 
-VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit(uint32_t crVersionMajor, uint32_t crVersionMinor)
+VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit()
 {
     if (!g_bVBoxKmtCallbacksInited)
@@ -189,9 +52,4 @@
         g_bVBoxKmtCallbacksInited = vboxCrHgsmiInitPerform(&g_VBoxCrHgsmiKmtCallbacks);
         Assert(g_bVBoxKmtCallbacksInited);
-        if (g_bVBoxKmtCallbacksInited)
-        {
-            g_VBoxCrVersionMajor = crVersionMajor;
-            g_VBoxCrVersionMinor = crVersionMinor;
-        }
     }
 
@@ -205,9 +63,9 @@
     {
 #if 0
-        HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, g_VBoxCrVersionMajor, g_VBoxCrVersionMinor, TRUE /* bD3D tmp for injection thread*/);
+        HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
 #else
-        HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, g_VBoxCrVersionMajor, g_VBoxCrVersionMinor, TRUE /* bD3D tmp for injection thread*/);
+        HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
 #endif
-        Log(("CrHgsmi: faled to create KmtEsc UHGSMI instance, hr (0x%x)\n", hr));
+        Log(("CrHgsmi: faled to create KmtEsc VBOXUHGSMI instance, hr (0x%x)\n", hr));
         if (hr == S_OK)
         {
@@ -230,5 +88,4 @@
     }
 }
-#endif
 
 VBOXCRHGSMI_DECL(int) VBoxCrHgsmiTerm()
@@ -256,5 +113,5 @@
 {
     PVBOXUHGSMI_PRIVATE_BASE pHgsmiPrivate = (PVBOXUHGSMI_PRIVATE_BASE)pHgsmi;
-    int rc = VBoxCrHgsmiPrivateCtlConGetClientID(pHgsmiPrivate, pu32ClientID);
+    int rc = vboxCrHgsmiPrivateCtlConGetClientID(pHgsmiPrivate, pu32ClientID);
     if (!RT_SUCCESS(rc))
     {
@@ -267,5 +124,5 @@
 {
     PVBOXUHGSMI_PRIVATE_BASE pHgsmiPrivate = (PVBOXUHGSMI_PRIVATE_BASE)pHgsmi;
-    int rc = VBoxCrHgsmiPrivateCtlConCall(pHgsmiPrivate, pCallInfo, cbCallInfo);
+    int rc = vboxCrHgsmiPrivateCtlConCall(pHgsmiPrivate, pCallInfo, cbCallInfo);
     if (!RT_SUCCESS(rc))
     {
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp	(revision 42499)
@@ -23,4 +23,5 @@
 #include <iprt/list.h>
 
+#include <cr_protocol.h>
 
 typedef struct VBOXDISPCM_SESSION
@@ -114,7 +115,19 @@
 HRESULT vboxDispCmCtxCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
 {
+    BOOL fIsCrContext;
     VBOXWDDM_CREATECONTEXT_INFO Info = {0};
     Info.u32IfVersion = pDevice->u32IfVersion;
-    Info.enmType = VBOXDISPMODE_IS_3D(pDevice->pAdapter) ? VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D : VBOXWDDM_CONTEXT_TYPE_CUSTOM_2D;
+    if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
+    {
+        Info.enmType = VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D;
+        Info.crVersionMajor = CR_PROTOCOL_VERSION_MAJOR;
+        Info.crVersionMinor = CR_PROTOCOL_VERSION_MINOR;
+        fIsCrContext = TRUE;
+    }
+    else
+    {
+        Info.enmType = VBOXWDDM_CONTEXT_TYPE_CUSTOM_2D;
+        fIsCrContext = FALSE;
+    }
     Info.hUmEvent = (uint64_t)g_pVBoxCmMgr.Session.hEvent;
     Info.u64UmInfo = (uint64_t)pContext;
@@ -151,4 +164,6 @@
         vboxDispCmSessionCtxAdd(&g_pVBoxCmMgr.Session, pContext);
         pContext->pDevice = pDevice;
+        if (fIsCrContext)
+            vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice);
     }
     else
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def	(revision 42499)
@@ -18,5 +18,2 @@
 	OpenAdapter
 	VBoxDispMpGetCallbacks
-    VBoxDispCrHgsmiInit
-    VBoxDispCrHgsmiTerm
-    VBoxDispCrHgsmiQueryClient
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h	(revision 42499)
@@ -207,7 +207,5 @@
     D3DVIEWPORT9 ViewPort;
     VBOXWDDMDISP_CONTEXT DefaultContext;
-#ifdef VBOX_WITH_CRHGSMI
     VBOXUHGSMI_PRIVATE_D3D Uhgsmi;
-#endif
 
     /* no lock is needed for this since we're guaranteed the per-device calls are not reentrant */
@@ -312,9 +310,4 @@
 #define VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, idx) ((D3DCUBEMAP_FACES)(D3DCUBEMAP_FACE_POSITIVE_X+(idx)%VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc)))
 #define VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, idx) ((idx)%VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc))
-
-#ifdef VBOX_WITH_CRHGSMI
-HRESULT vboxUhgsmiGlobalSetCurrent();
-HRESULT vboxUhgsmiGlobalClearCurrent();
-#endif
 
 DECLINLINE(PVBOXWDDMDISP_SWAPCHAIN) vboxWddmSwapchainForAlloc(PVBOXWDDMDISP_ALLOCATION pAlloc)
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp	(revision 42499)
@@ -74,7 +74,4 @@
     g_VBoxDispMp.cbEscapeCmd = 0;
     vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, NULL, 0);
-#ifdef VBOX_WITH_CRHGSMI
-    vboxUhgsmiGlobalSetCurrent();
-#endif
     LeaveCriticalSection(&g_VBoxDispMp.CritSect);
     return S_OK;
@@ -90,7 +87,4 @@
         g_VBoxDispMp.pEscapeCmd = NULL;
     }
-#ifdef VBOX_WITH_CRHGSMI
-    vboxUhgsmiGlobalClearCurrent();
-#endif
     LeaveCriticalSection(&g_VBoxDispMp.CritSect);
     return S_OK;
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp	(revision 42499)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp	(revision 42499)
@@ -0,0 +1,274 @@
+/* $Id$ */
+
+/** @file
+ * VBoxVideo Display D3D User mode dll
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "VBoxDispD3DCmn.h"
+
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock)
+{
+    PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer = VBOXUHGSMIESCBASE_GET_BUFFER(pBuf);
+    *pvLock = (void*)(pBuffer->Alloc.pvData + offLock);
+    return VINF_SUCCESS;
+}
+
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferUnlock(PVBOXUHGSMI_BUFFER pBuf)
+{
+    return VINF_SUCCESS;
+}
+
+int vboxUhgsmiBaseBufferTerm(PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer)
+{
+    PVBOXUHGSMI_PRIVATE_BASE pPrivate = VBOXUHGSMIBASE_GET(pBuffer->PrivateBase.pHgsmi);
+    VBOXDISPIFESCAPE_UHGSMI_DEALLOCATE DeallocInfo = {0};
+    DeallocInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_DEALLOCATE;
+    DeallocInfo.hAlloc = pBuffer->Alloc.hAlloc;
+    return vboxCrHgsmiPrivateEscape(pPrivate, &DeallocInfo, sizeof (DeallocInfo), FALSE);
+}
+
+static int vboxUhgsmiBaseEventChkCreate(VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, HANDLE *phSynch)
+{
+    *phSynch = NULL;
+
+    if (fUhgsmiType.fCommand)
+    {
+        *phSynch = CreateEvent(
+                  NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes */
+                  FALSE, /* BOOL bManualReset */
+                  FALSE, /* BOOL bInitialState */
+                  NULL /* LPCTSTR lpName */
+            );
+        Assert(*phSynch);
+        if (!*phSynch)
+        {
+            DWORD winEr = GetLastError();
+            /* todo: translate winer */
+            return VERR_GENERAL_FAILURE;
+        }
+    }
+    return VINF_SUCCESS;
+}
+
+int vboxUhgsmiKmtEscBufferInit(PVBOXUHGSMI_PRIVATE_BASE pPrivate, PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PFNVBOXUHGSMI_BUFFER_DESTROY pfnDestroy)
+{
+    HANDLE hSynch = NULL;
+    if (!cbBuf)
+        return VERR_INVALID_PARAMETER;
+
+    int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch);
+    if (RT_FAILURE(rc))
+    {
+        WARN(("vboxUhgsmiBaseEventChkCreate failed, rc %d", rc));
+        return rc;
+    }
+
+    cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000);
+    Assert(cbBuf);
+    uint32_t cPages = cbBuf >> 12;
+    Assert(cPages);
+
+    VBOXDISPIFESCAPE_UHGSMI_ALLOCATE AllocInfo = {0};
+    AllocInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_ALLOCATE;
+    AllocInfo.Alloc.cbData = cbBuf;
+    AllocInfo.Alloc.hSynch = (uint64_t)hSynch;
+    AllocInfo.Alloc.fUhgsmiType = fUhgsmiType;
+
+    rc = vboxCrHgsmiPrivateEscape(pPrivate, &AllocInfo, sizeof (AllocInfo), FALSE);
+    if (RT_FAILURE(rc))
+    {
+        if (hSynch)
+            CloseHandle(hSynch);
+        WARN(("vboxCrHgsmiPrivateEscape failed, rc %d", rc));
+        return rc;
+    }
+
+    pBuffer->Alloc = AllocInfo.Alloc;
+    Assert(pBuffer->Alloc.pvData);
+    pBuffer->PrivateBase.pHgsmi = pPrivate;
+    pBuffer->PrivateBase.Base.pfnLock = vboxUhgsmiBaseEscBufferLock;
+    pBuffer->PrivateBase.Base.pfnUnlock = vboxUhgsmiBaseEscBufferUnlock;
+    pBuffer->PrivateBase.Base.pfnDestroy = pfnDestroy;
+    pBuffer->PrivateBase.Base.fType = fUhgsmiType;
+    pBuffer->PrivateBase.Base.cbBuffer = AllocInfo.Alloc.cbData;
+    pBuffer->hSynch = hSynch;
+    return VINF_SUCCESS;
+}
+
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
+{
+    PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer = VBOXUHGSMIESCBASE_GET_BUFFER(pBuf);
+    int rc = vboxUhgsmiBaseBufferTerm(pBuffer);
+    if (RT_FAILURE(rc))
+    {
+        WARN(("vboxUhgsmiBaseBufferTerm failed rc %d", rc));
+        return rc;
+    }
+
+    RTMemFree(pBuffer);
+    return VINF_SUCCESS;
+}
+
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf)
+{
+    *ppBuf = NULL;
+
+    PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer = (PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE)RTMemAllocZ(sizeof (*pBuffer));
+    if (!pBuffer)
+    {
+        WARN(("RTMemAllocZ failed"));
+        return VERR_NO_MEMORY;
+    }
+
+    PVBOXUHGSMI_PRIVATE_BASE pPrivate = VBOXUHGSMIBASE_GET(pHgsmi);
+    int rc = vboxUhgsmiKmtEscBufferInit(pPrivate, pBuffer, cbBuf, fUhgsmiType, vboxUhgsmiBaseEscBufferDestroy);
+    if (RT_SUCCESS(rc))
+    {
+        *ppBuf = &pBuffer->PrivateBase.Base;
+        return VINF_SUCCESS;
+    }
+
+    WARN(("vboxUhgsmiKmtEscBufferInit failed, rc %d", rc));
+    RTMemFree(pBuffer);
+    return rc;
+}
+
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers)
+{
+    /* we no chromium will not submit more than three buffers actually,
+     * for simplicity allocate it statically on the stack  */
+    struct
+    {
+        VBOXDISPIFESCAPE_UHGSMI_SUBMIT SubmitInfo;
+        VBOXWDDM_UHGSMI_BUFFER_UI_INFO_ESCAPE aBufInfos[3];
+    } Buf;
+
+    if (!cBuffers || cBuffers > RT_ELEMENTS(Buf.aBufInfos) + 1)
+    {
+        WARN(("invalid cBuffers!"));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    HANDLE hSynch = VBOXUHGSMIESCBASE_GET_BUFFER(aBuffers[0].pBuf)->hSynch;
+    if (!hSynch)
+    {
+        WARN(("the fist buffer is not command!"));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    PVBOXUHGSMI_PRIVATE_BASE pPrivate = VBOXUHGSMIBASE_GET(pHgsmi);
+    Buf.SubmitInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_SUBMIT;
+    Buf.SubmitInfo.EscapeHdr.u32CmdSpecific = cBuffers;
+    for (UINT i = 0; i < cBuffers; ++i)
+    {
+        VBOXWDDM_UHGSMI_BUFFER_UI_INFO_ESCAPE *pSubmInfo = &Buf.SubmitInfo.aBuffers[i];
+        PVBOXUHGSMI_BUFFER_SUBMIT pBufInfo = &aBuffers[i];
+        PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuf = VBOXUHGSMIESCBASE_GET_BUFFER(pBufInfo->pBuf);
+        pSubmInfo->hAlloc = pBuf->Alloc.hAlloc;
+        pSubmInfo->Info.bDoNotSignalCompletion = 0;
+        if (pBufInfo->fFlags.bEntireBuffer)
+        {
+            pSubmInfo->Info.offData = 0;
+            pSubmInfo->Info.cbData = pBuf->PrivateBase.Base.cbBuffer;
+        }
+        else
+        {
+            pSubmInfo->Info.offData = pBufInfo->offData;
+            pSubmInfo->Info.cbData = pBufInfo->cbData;
+        }
+    }
+
+    int rc = vboxCrHgsmiPrivateEscape(pPrivate, &Buf.SubmitInfo, RT_OFFSETOF(VBOXDISPIFESCAPE_UHGSMI_SUBMIT, aBuffers[cBuffers]), FALSE);
+    if (RT_SUCCESS(rc))
+    {
+        DWORD dwResult = WaitForSingleObject(hSynch, INFINITE);
+        if (dwResult == WAIT_OBJECT_0)
+            return VINF_SUCCESS;
+        WARN(("wait failed, (0x%x)", dwResult));
+        return VERR_GENERAL_FAILURE;
+    }
+    else
+    {
+        WARN(("vboxCrHgsmiPrivateEscape failed, rc (%d)", rc));
+    }
+
+    return VERR_GENERAL_FAILURE;
+}
+
+/* Cr calls have <= 3args, we try to allocate it on stack first */
+typedef struct VBOXCRHGSMI_CALLDATA
+{
+    VBOXDISPIFESCAPE_CRHGSMICTLCON_CALL CallHdr;
+    HGCMFunctionParameter aArgs[3];
+} VBOXCRHGSMI_CALLDATA, *PVBOXCRHGSMI_CALLDATA;
+
+int vboxCrHgsmiPrivateCtlConCall(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, struct VBoxGuestHGCMCallInfo *pCallInfo, int cbCallInfo)
+{
+    VBOXCRHGSMI_CALLDATA Buf;
+    PVBOXCRHGSMI_CALLDATA pBuf;
+    int cbBuffer = cbCallInfo + RT_OFFSETOF(VBOXCRHGSMI_CALLDATA, CallHdr.CallInfo);
+
+    if (cbBuffer <= sizeof (Buf))
+        pBuf = &Buf;
+    else
+    {
+        pBuf = (PVBOXCRHGSMI_CALLDATA)RTMemAlloc(cbBuffer);
+        if (!pBuf)
+        {
+            WARN(("RTMemAlloc failed!"));
+            return VERR_NO_MEMORY;
+        }
+    }
+
+    pBuf->CallHdr.EscapeHdr.escapeCode = VBOXESC_CRHGSMICTLCON_CALL;
+    pBuf->CallHdr.EscapeHdr.u32CmdSpecific = 0;
+    memcpy(&pBuf->CallHdr.CallInfo, pCallInfo, cbCallInfo);
+
+    int rc = vboxCrHgsmiPrivateEscape(pHgsmi, pBuf, cbBuffer, FALSE);
+    if (RT_SUCCESS(rc))
+    {
+        memcpy(pCallInfo, &pBuf->CallHdr.CallInfo, cbCallInfo);
+        rc = VINF_SUCCESS;
+    }
+    else
+    {
+        WARN(("vboxCrHgsmiPrivateEscape failed, rc (%d)", rc));
+   }
+    /* cleanup */
+    if (pBuf != &Buf)
+        RTMemFree(pBuf);
+
+    return rc;
+}
+
+int vboxCrHgsmiPrivateCtlConGetClientID(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, uint32_t *pu32ClientID)
+{
+    VBOXDISPIFESCAPE GetId = {0};
+    GetId.escapeCode = VBOXESC_CRHGSMICTLCON_GETCLIENTID;
+
+    int rc = vboxCrHgsmiPrivateEscape(pHgsmi, &GetId, sizeof (GetId), FALSE);
+    if (RT_SUCCESS(rc))
+    {
+        Assert(GetId.u32CmdSpecific);
+        *pu32ClientID = GetId.u32CmdSpecific;
+        return VINF_SUCCESS;
+    }
+    else
+    {
+        *pu32ClientID = 0;
+        WARN(("vboxCrHgsmiPrivateEscape failed, rc (%d)", rc));
+    }
+    return rc;
+}
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h	(revision 42499)
@@ -33,8 +33,9 @@
 #endif
 
+#if 0
 typedef DECLCALLBACK(int) FNVBOXCRHGSMI_CTLCON_CALL(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, struct VBoxGuestHGCMCallInfo *pCallInfo, int cbCallInfo);
 typedef FNVBOXCRHGSMI_CTLCON_CALL *PFNVBOXCRHGSMI_CTLCON_CALL;
 
-#define VBoxCrHgsmiPrivateCtlConCall(_pHgsmi, _pCallInfo, _cbCallInfo) (_pHgsmi->pfnCtlConCall((_pHgsmi), (_pCallInfo), (_cbCallInfo)))
+#define vboxCrHgsmiPrivateCtlConCall(_pHgsmi, _pCallInfo, _cbCallInfo) (_pHgsmi->pfnCtlConCall((_pHgsmi), (_pCallInfo), (_cbCallInfo)))
 
 
@@ -42,15 +43,19 @@
 typedef FNVBOXCRHGSMI_CTLCON_GETCLIENTID *PFNVBOXCRHGSMI_CTLCON_GETCLIENTID;
 
-#define VBoxCrHgsmiPrivateCtlConGetClientID(_pHgsmi, _pu32ClientID) (_pHgsmi->pfnCtlConGetClientID((_pHgsmi), (_pu32ClientID)))
-
+#define vboxCrHgsmiPrivateCtlConGetClientID(_pHgsmi, _pu32ClientID) (_pHgsmi->pfnCtlConGetClientID((_pHgsmi), (_pu32ClientID)))
+#else
+int vboxCrHgsmiPrivateCtlConCall(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, struct VBoxGuestHGCMCallInfo *pCallInfo, int cbCallInfo);
+int vboxCrHgsmiPrivateCtlConGetClientID(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, uint32_t *pu32ClientID);
+#endif
+
+typedef DECLCALLBACK(int) FNVBOXCRHGSMI_ESCAPE(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, void *pvData, uint32_t cbData, BOOL fHwAccess);
+typedef FNVBOXCRHGSMI_ESCAPE *PFNVBOXCRHGSMI_ESCAPE;
+
+#define vboxCrHgsmiPrivateEscape(_pHgsmi, _pvData, _cbData, _fHwAccess) (_pHgsmi->pfnEscape((_pHgsmi), (_pvData), (_cbData), (_fHwAccess)))
 
 typedef struct VBOXUHGSMI_PRIVATE_BASE
 {
     VBOXUHGSMI Base;
-    PFNVBOXCRHGSMI_CTLCON_CALL pfnCtlConCall;
-    PFNVBOXCRHGSMI_CTLCON_GETCLIENTID pfnCtlConGetClientID;
-#ifdef VBOX_CRHGSMI_WITH_D3DDEV
-    HVBOXCRHGSMI_CLIENT hClient;
-#endif
+    PFNVBOXCRHGSMI_ESCAPE pfnEscape;
 } VBOXUHGSMI_PRIVATE_BASE, *PVBOXUHGSMI_PRIVATE_BASE;
 
@@ -58,7 +63,20 @@
 {
     VBOXUHGSMI_BUFFER Base;
+    PVBOXUHGSMI_PRIVATE_BASE pHgsmi;
+} VBOXUHGSMI_BUFFER_PRIVATE_BASE, *PVBOXUHGSMI_BUFFER_PRIVATE_BASE;
+
+typedef struct VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE
+{
+    VBOXUHGSMI_BUFFER_PRIVATE_BASE PrivateBase;
+    VBOXVIDEOCM_UM_ALLOC Alloc;
     HANDLE hSynch;
+} VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE, *PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE;
+
+typedef struct VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE
+{
+    VBOXUHGSMI_BUFFER_PRIVATE_BASE PrivateBase;
     D3DKMT_HANDLE hAllocation;
-} VBOXUHGSMI_BUFFER_PRIVATE_BASE, *PVBOXUHGSMI_BUFFER_PRIVATE_BASE;
+    UINT aLockPageIndices[1];
+} VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, *PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE;
 
 #define VBOXUHGSMIBASE_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, Base)))
@@ -66,4 +84,7 @@
 #define VBOXUHGSMIBASE_GET_BUFFER(_p) VBOXUHGSMIBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_BASE)
 
+#define VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, PrivateBase.Base)))
+#define VBOXUHGSMIESCBASE_GET_BUFFER(_p) VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE)
+#define VBOXUHGSMDXALLOCBASE_GET_BUFFER(_p) VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE)
 
 DECLINLINE(int) vboxUhgsmiBaseLockData(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags,
@@ -120,27 +141,5 @@
 }
 
-DECLINLINE(int) vboxUhgsmiBaseEventChkCreate(VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, HANDLE *phSynch)
-{
-    *phSynch = NULL;
-
-    if (fUhgsmiType.fCommand)
-    {
-        *phSynch = CreateEvent(
-                  NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes */
-                  FALSE, /* BOOL bManualReset */
-                  FALSE, /* BOOL bInitialState */
-                  NULL /* LPCTSTR lpName */
-            );
-        Assert(*phSynch);
-        if (!*phSynch)
-        {
-            DWORD winEr = GetLastError();
-            /* todo: translate winer */
-            return VERR_GENERAL_FAILURE;
-        }
-    }
-    return VINF_SUCCESS;
-}
-
+#if 0
 DECLINLINE(int) vboxUhgsmiBaseDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers,
         VOID* pCommandBuffer, UINT *pCommandBufferSize,
@@ -196,4 +195,20 @@
     return VINF_SUCCESS;
 }
+#endif
+
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock);
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferUnlock(PVBOXUHGSMI_BUFFER pBuf);
+int vboxUhgsmiBaseBufferTerm(PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer);
+static int vboxUhgsmiBaseEventChkCreate(VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, HANDLE *phSynch);
+int vboxUhgsmiKmtEscBufferInit(PVBOXUHGSMI_PRIVATE_BASE pPrivate, PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PFNVBOXUHGSMI_BUFFER_DESTROY pfnDestroy);
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers);
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferDestroy(PVBOXUHGSMI_BUFFER pBuf);
+DECLCALLBACK(int) vboxUhgsmiBaseEscBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf);
+DECLINLINE(void) vboxUhgsmiBaseInit(PVBOXUHGSMI_PRIVATE_BASE pHgsmi, PFNVBOXCRHGSMI_ESCAPE pfnEscape)
+{
+    pHgsmi->Base.pfnBufferCreate = vboxUhgsmiBaseEscBufferCreate;
+    pHgsmi->Base.pfnBufferSubmit = vboxUhgsmiBaseEscBufferSubmit;
+    pHgsmi->pfnEscape = pfnEscape;
+}
 
 #endif /* #ifndef ___VBoxUhgsmiBase_h__ */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp	(revision 42499)
@@ -19,4 +19,10 @@
 #include "VBoxDispD3DCmn.h"
 
+#define VBOXUHGSMID3D_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, BasePrivate.Base)))
+#define VBOXUHGSMID3D_GET(_p) VBOXUHGSMID3D_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_D3D)
+
+#if 0
+#define VBOXUHGSMID3D_GET_BUFFER(_p) VBOXUHGSMID3D_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_D3D)
+
 #include <iprt/mem.h>
 #include <iprt/err.h>
@@ -29,7 +35,5 @@
 } VBOXUHGSMI_BUFFER_PRIVATE_D3D, *PVBOXUHGSMI_BUFFER_PRIVATE_D3D;
 
-#define VBOXUHGSMID3D_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, BasePrivate.Base)))
-#define VBOXUHGSMID3D_GET(_p) VBOXUHGSMID3D_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_D3D)
-#define VBOXUHGSMID3D_GET_BUFFER(_p) VBOXUHGSMID3D_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_D3D)
+
 
 DECLCALLBACK(int) vboxUhgsmiD3DBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
@@ -210,7 +214,33 @@
     pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiD3DBufferCreate;
     pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiD3DBufferSubmit;
-    pHgsmi->BasePrivate.hClient = NULL;
     pHgsmi->pDevice = pDevice;
     return S_OK;
 }
-
+#endif
+
+static DECLCALLBACK(int) vboxCrHhgsmiDispEscape(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, void *pvData, uint32_t cbData, BOOL fHwAccess)
+{
+    PVBOXUHGSMI_PRIVATE_D3D pPrivate = VBOXUHGSMID3D_GET(pHgsmi);
+    PVBOXWDDMDISP_DEVICE pDevice = pPrivate->pDevice;
+    D3DDDICB_ESCAPE DdiEscape = {0};
+    DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
+    DdiEscape.hDevice = pDevice->hDevice;
+    DdiEscape.Flags.HardwareAccess = !!fHwAccess;
+    DdiEscape.pPrivateDriverData = pvData;
+    DdiEscape.PrivateDriverDataSize = cbData;
+    HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
+    if (SUCCEEDED(hr))
+    {
+        return VINF_SUCCESS;
+    }
+
+    WARN(("pfnEscapeCb failed, hr 0x%x", hr));
+    return VERR_GENERAL_FAILURE;
+}
+
+
+void vboxUhgsmiD3DEscInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, struct VBOXWDDMDISP_DEVICE *pDevice)
+{
+    vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiDispEscape);
+    pHgsmi->pDevice = pDevice;
+}
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp	(revision 42499)
@@ -22,27 +22,19 @@
 #include <iprt/err.h>
 
+#include <cr_protocol.h>
+
 #ifndef NT_SUCCESS
 # define NT_SUCCESS(_Status) (((NTSTATUS)(_Status)) >= 0)
 #endif
 
+#if 0
 typedef struct VBOXUHGSMI_BUFFER_PRIVATE_KMT
 {
     VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate;
-    PVBOXUHGSMI_PRIVATE_KMT pHgsmi;
     CRITICAL_SECTION CritSect;
-    UINT aLockPageIndices[1];
 } VBOXUHGSMI_BUFFER_PRIVATE_KMT, *PVBOXUHGSMI_BUFFER_PRIVATE_KMT;
 
-typedef struct VBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC
-{
-    VBOXUHGSMI_BUFFER Base;
-    PVBOXUHGSMI_PRIVATE_KMT pHgsmi;
-    VBOXVIDEOCM_UM_ALLOC Alloc;
-    HANDLE hSynch;
-} VBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC, *PVBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC;
 
 #define VBOXUHGSMIKMT_GET_BUFFER(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_KMT)
-#define VBOXUHGSMIKMTESC_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, Base)))
-#define VBOXUHGSMIKMTESC_GET_BUFFER(_p) VBOXUHGSMIKMTESC_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC)
 
 DECLCALLBACK(int) vboxUhgsmiKmtBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
@@ -236,200 +228,7 @@
     return VERR_GENERAL_FAILURE;
 }
-
-
-DECLCALLBACK(int) vboxUhgsmiKmtEscBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock)
-{
-    PVBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC pBuffer = VBOXUHGSMIKMTESC_GET_BUFFER(pBuf);
-    *pvLock = (void*)(pBuffer->Alloc.pvData + offLock);
-    return VINF_SUCCESS;
-}
-
-DECLCALLBACK(int) vboxUhgsmiKmtEscBufferUnlock(PVBOXUHGSMI_BUFFER pBuf)
-{
-    return VINF_SUCCESS;
-}
-
-DECLCALLBACK(int) vboxUhgsmiKmtEscBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
-{
-    PVBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC pBuffer = VBOXUHGSMIKMTESC_GET_BUFFER(pBuf);
-    PVBOXUHGSMI_PRIVATE_KMT pPrivate = pBuffer->pHgsmi;
-    D3DKMT_ESCAPE DdiEscape = {0};
-    VBOXDISPIFESCAPE_UHGSMI_DEALLOCATE DeallocInfo = {0};
-    DdiEscape.hAdapter = pPrivate->Adapter.hAdapter;
-    DdiEscape.hDevice = pPrivate->Device.hDevice;
-    DdiEscape.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
-    //Buf.DdiEscape.Flags.HardwareAccess = 1;
-    DdiEscape.pPrivateDriverData = &DeallocInfo;
-    DdiEscape.PrivateDriverDataSize = sizeof (DeallocInfo);
-    DdiEscape.hContext = pPrivate->Context.hContext;
-
-    DeallocInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_DEALLOCATE;
-    DeallocInfo.hAlloc = pBuffer->Alloc.hAlloc;
-
-    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTEscape(&DdiEscape);
-    if (NT_SUCCESS(Status))
-    {
-        if (pBuffer->hSynch)
-            CloseHandle(pBuffer->hSynch);
-        RTMemFree(pBuffer);
-        return VINF_SUCCESS;
-    }
-    else
-    {
-        WARN(("pfnD3DKMTEscape failed, Status (0x%x)", Status));
-    }
-
-    return VERR_GENERAL_FAILURE;
-}
-
-DECLCALLBACK(int) vboxUhgsmiKmtEscBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf)
-{
-    HANDLE hSynch = NULL;
-    if (!cbBuf)
-        return VERR_INVALID_PARAMETER;
-
-    int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch);
-    AssertRC(rc);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000);
-    Assert(cbBuf);
-    uint32_t cPages = cbBuf >> 12;
-    Assert(cPages);
-
-    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi);
-    PVBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC)RTMemAllocZ(sizeof (VBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC));
-    Assert(pBuf);
-    if (pBuf)
-    {
-        struct
-        {
-            D3DKMT_ESCAPE DdiEscape;
-            VBOXDISPIFESCAPE_UHGSMI_ALLOCATE AllocInfo;
-        } Buf;
-        memset(&Buf, 0, sizeof (Buf));
-        Buf.DdiEscape.hAdapter = pPrivate->Adapter.hAdapter;
-        Buf.DdiEscape.hDevice = pPrivate->Device.hDevice;
-        Buf.DdiEscape.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
-        //Buf.DdiEscape.Flags.HardwareAccess = 1;
-        Buf.DdiEscape.pPrivateDriverData = &Buf.AllocInfo;
-        Buf.DdiEscape.PrivateDriverDataSize = sizeof (Buf.AllocInfo);
-        Buf.DdiEscape.hContext = pPrivate->Context.hContext;
-
-        Buf.AllocInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_ALLOCATE;
-        Buf.AllocInfo.Alloc.cbData = cbBuf;
-        Buf.AllocInfo.Alloc.hSynch = (uint64_t)hSynch;
-        Buf.AllocInfo.Alloc.fUhgsmiType = fUhgsmiType;
-
-        NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTEscape(&Buf.DdiEscape);
-        if (NT_SUCCESS(Status))
-        {
-            pBuf->Alloc = Buf.AllocInfo.Alloc;
-            Assert(pBuf->Alloc.pvData);
-            pBuf->pHgsmi = pPrivate;
-            pBuf->Base.pfnLock = vboxUhgsmiKmtEscBufferLock;
-            pBuf->Base.pfnUnlock = vboxUhgsmiKmtEscBufferUnlock;
-            pBuf->Base.pfnDestroy = vboxUhgsmiKmtEscBufferDestroy;
-
-            pBuf->Base.fType = fUhgsmiType;
-            pBuf->Base.cbBuffer = Buf.AllocInfo.Alloc.cbData;
-
-            pBuf->hSynch = hSynch;
-
-            *ppBuf = &pBuf->Base;
-
-            return VINF_SUCCESS;
-        }
-        else
-        {
-            WARN(("pfnD3DKMTEscape failed, Status (0x%x)", Status));
-            rc = VERR_OUT_OF_RESOURCES;
-        }
-
-        RTMemFree(pBuf);
-    }
-    else
-        rc = VERR_NO_MEMORY;
-
-    if (hSynch)
-        CloseHandle(hSynch);
-
-    return rc;
-}
-
-DECLCALLBACK(int) vboxUhgsmiKmtEscBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers)
-{
-    /* we no chromium will not submit more than three buffers actually,
-     * for simplicity allocate it statically on the stack  */
-    struct
-    {
-        VBOXDISPIFESCAPE_UHGSMI_SUBMIT SubmitInfo;
-        VBOXWDDM_UHGSMI_BUFFER_UI_INFO_ESCAPE aBufInfos[3];
-    } Buf;
-
-    if (!cBuffers || cBuffers > RT_ELEMENTS(Buf.aBufInfos) + 1)
-    {
-        WARN(("invalid cBuffers!"));
-        return VERR_INVALID_PARAMETER;
-    }
-
-    HANDLE hSynch = VBOXUHGSMIKMTESC_GET_BUFFER(aBuffers[0].pBuf)->hSynch;
-    if (!hSynch)
-    {
-        WARN(("the fist buffer is not command!"));
-        return VERR_INVALID_PARAMETER;
-    }
-    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi);
-    D3DKMT_ESCAPE DdiEscape = {0};
-
-    DdiEscape.hAdapter = pPrivate->Adapter.hAdapter;
-    DdiEscape.hDevice = pPrivate->Device.hDevice;
-    DdiEscape.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
-    //Buf.DdiEscape.Flags.HardwareAccess = 1;
-    DdiEscape.pPrivateDriverData = &Buf.SubmitInfo;
-    DdiEscape.PrivateDriverDataSize = RT_OFFSETOF(VBOXDISPIFESCAPE_UHGSMI_SUBMIT, aBuffers[cBuffers]);
-    DdiEscape.hContext = pPrivate->Context.hContext;
-
-    Buf.SubmitInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_SUBMIT;
-    Buf.SubmitInfo.EscapeHdr.u32CmdSpecific = cBuffers;
-    for (UINT i = 0; i < cBuffers; ++i)
-    {
-        VBOXWDDM_UHGSMI_BUFFER_UI_INFO_ESCAPE *pSubmInfo = &Buf.SubmitInfo.aBuffers[i];
-        PVBOXUHGSMI_BUFFER_SUBMIT pBufInfo = &aBuffers[i];
-        PVBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC pBuf = VBOXUHGSMIKMTESC_GET_BUFFER(pBufInfo->pBuf);
-        pSubmInfo->hAlloc = pBuf->Alloc.hAlloc;
-        pSubmInfo->Info.bDoNotSignalCompletion = 0;
-        if (pBufInfo->fFlags.bEntireBuffer)
-        {
-            pSubmInfo->Info.offData = 0;
-            pSubmInfo->Info.cbData = pBuf->Base.cbBuffer;
-        }
-        else
-        {
-            pSubmInfo->Info.offData = pBufInfo->offData;
-            pSubmInfo->Info.cbData = pBufInfo->cbData;
-        }
-    }
-
-    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTEscape(&DdiEscape);
-    if (NT_SUCCESS(Status))
-    {
-        DWORD dwResult = WaitForSingleObject(hSynch, INFINITE);
-        if (dwResult == WAIT_OBJECT_0)
-            return VINF_SUCCESS;
-        WARN(("wait failed, (0x%x)", dwResult));
-        return VERR_GENERAL_FAILURE;
-    }
-    else
-    {
-        WARN(("pfnD3DKMTEscape failed, Status (0x%x)", Status));
-    }
-
-    return VERR_GENERAL_FAILURE;
-}
-
-static HRESULT vboxUhgsmiKmtEngineCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi,
-        uint32_t crVersionMajor, uint32_t crVersionMinor, BOOL bD3D)
+#endif
+
+static HRESULT vboxUhgsmiKmtEngineCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
 {
     HRESULT hr = vboxDispKmtCallbacksInit(&pHgsmi->Callbacks);
@@ -444,5 +243,5 @@
                 hr = vboxDispKmtCreateContext(&pHgsmi->Device, &pHgsmi->Context,
                         bD3D ? VBOXWDDM_CONTEXT_TYPE_CUSTOM_UHGSMI_3D : VBOXWDDM_CONTEXT_TYPE_CUSTOM_UHGSMI_GL,
-                                crVersionMajor, crVersionMinor,
+                                CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR,
                                 NULL, 0);
                 if (hr == S_OK)
@@ -476,116 +275,39 @@
 }
 
-/* Cr calls have <= 3args, we try to allocate it on stack first */
-typedef struct VBOXCRHGSMI_CALLDATA
-{
-    VBOXDISPIFESCAPE_CRHGSMICTLCON_CALL CallHdr;
-    HGCMFunctionParameter aArgs[3];
-} VBOXCRHGSMI_CALLDATA, *PVBOXCRHGSMI_CALLDATA;
-
-static DECLCALLBACK(int) vboxCrHhgsmiKmtEscCtlConCall(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, struct VBoxGuestHGCMCallInfo *pCallInfo, int cbCallInfo)
-{
-    VBOXCRHGSMI_CALLDATA Buf;
-    PVBOXCRHGSMI_CALLDATA pBuf;
-    int cbBuffer = cbCallInfo + RT_OFFSETOF(VBOXCRHGSMI_CALLDATA, CallHdr.CallInfo);
-
-    if (cbBuffer <= sizeof (Buf))
-        pBuf = &Buf;
-    else
-    {
-        pBuf = (PVBOXCRHGSMI_CALLDATA)RTMemAlloc(cbBuffer);
-        if (!pBuf)
-        {
-            WARN(("RTMemAlloc failed!"));
-            return VERR_NO_MEMORY;
-        }
-    }
-
+static DECLCALLBACK(int) vboxCrHhgsmiKmtEscape(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, void *pvData, uint32_t cbData, BOOL fHwAccess)
+{
     PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi);
     D3DKMT_ESCAPE DdiEscape = {0};
-
     DdiEscape.hAdapter = pPrivate->Adapter.hAdapter;
     DdiEscape.hDevice = pPrivate->Device.hDevice;
     DdiEscape.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
-    //Buf.DdiEscape.Flags.HardwareAccess = 1;
-    DdiEscape.pPrivateDriverData = pBuf;
-    DdiEscape.PrivateDriverDataSize = cbBuffer;
+    DdiEscape.Flags.HardwareAccess = !!fHwAccess;
+    DdiEscape.pPrivateDriverData = pvData;
+    DdiEscape.PrivateDriverDataSize = cbData;
     DdiEscape.hContext = pPrivate->Context.hContext;
 
-    pBuf->CallHdr.EscapeHdr.escapeCode = VBOXESC_CRHGSMICTLCON_CALL;
-    pBuf->CallHdr.EscapeHdr.u32CmdSpecific = 0;
-    memcpy(&pBuf->CallHdr.CallInfo, pCallInfo, cbCallInfo);
-
-    int rc;
     NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTEscape(&DdiEscape);
     if (NT_SUCCESS(Status))
     {
-        memcpy(pCallInfo, &pBuf->CallHdr.CallInfo, cbCallInfo);
-        rc = VINF_SUCCESS;
-    }
-    else
-    {
-        WARN(("pfnD3DKMTEscape failed, Status (0x%x)", Status));
-        rc = VERR_GENERAL_FAILURE;
-    }
-    /* cleanup */
-    if (pBuf != &Buf)
-        RTMemFree(pBuf);
-
-    return rc;
-}
-
-static DECLCALLBACK(int) vboxCrHhgsmiKmtEscCtlConGetClientID(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, uint32_t *pu32ClientID)
-{
-    VBOXDISPIFESCAPE GetId = {0};
-    PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi);
-    D3DKMT_ESCAPE DdiEscape = {0};
-
-    DdiEscape.hAdapter = pPrivate->Adapter.hAdapter;
-    DdiEscape.hDevice = pPrivate->Device.hDevice;
-    DdiEscape.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
-    //Buf.DdiEscape.Flags.HardwareAccess = 1;
-    DdiEscape.pPrivateDriverData = &GetId;
-    DdiEscape.PrivateDriverDataSize = sizeof (GetId);
-    DdiEscape.hContext = pPrivate->Context.hContext;
-
-    GetId.escapeCode = VBOXESC_CRHGSMICTLCON_GETCLIENTID;
-
-    NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTEscape(&DdiEscape);
-    if (NT_SUCCESS(Status))
-    {
-        Assert(GetId.u32CmdSpecific);
-        *pu32ClientID = GetId.u32CmdSpecific;
-        return VINF_SUCCESS;
-    }
-    else
-    {
-        *pu32ClientID = 0;
-        WARN(("pfnD3DKMTEscape failed, Status (0x%x)", Status));
-    }
-    return VERR_GENERAL_FAILURE;
-}
-
-HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, uint32_t crVersionMajor, uint32_t crVersionMinor, BOOL bD3D)
-{
-    pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiKmtBufferCreate;
-    pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiKmtBufferSubmit;
-    pHgsmi->BasePrivate.pfnCtlConCall = vboxCrHhgsmiKmtEscCtlConCall;
-    pHgsmi->BasePrivate.pfnCtlConGetClientID = vboxCrHhgsmiKmtEscCtlConGetClientID;
-#ifdef VBOX_CRHGSMI_WITH_D3DDEV
-    pHgsmi->BasePrivate.hClient = NULL;
+        return VINF_SUCCESS;
+    }
+
+    WARN(("pfnD3DKMTEscape failed, Status (0x%x)", Status));
+    return VERR_GENERAL_FAILURE;
+}
+
+#if 0
+HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
+{
+    vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
+#error "port me!"
+    return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
+}
 #endif
-    return vboxUhgsmiKmtEngineCreate(pHgsmi, crVersionMajor, crVersionMinor, bD3D);
-}
-
-HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, uint32_t crVersionMajor, uint32_t crVersionMinor, BOOL bD3D)
-{
-    pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiKmtEscBufferCreate;
-    pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiKmtEscBufferSubmit;
-    pHgsmi->BasePrivate.pfnCtlConCall = vboxCrHhgsmiKmtEscCtlConCall;
-    pHgsmi->BasePrivate.pfnCtlConGetClientID = vboxCrHhgsmiKmtEscCtlConGetClientID;
-#ifdef VBOX_CRHGSMI_WITH_D3DDEV
-    pHgsmi->BasePrivate.hClient = NULL;
-#endif
-    return vboxUhgsmiKmtEngineCreate(pHgsmi, crVersionMajor, crVersionMinor, bD3D);
+
+HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
+{
+    vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
+    return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
 }
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h	(revision 42499)
@@ -36,8 +36,10 @@
 #define VBOXUHGSMIKMT_GET(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_KMT)
 
-HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, uint32_t crVersionMajor, uint32_t crVersionMinor, BOOL bD3D);
+#if 0
+HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
+#endif
 HRESULT vboxUhgsmiKmtDestroy(PVBOXUHGSMI_PRIVATE_KMT pHgsmi);
 
-HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, uint32_t crVersionMajor, uint32_t crVersionMinor, BOOL bD3D);
+HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
 
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/d3d9_private.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/d3d9_private.h	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/d3d9_private.h	(revision 42499)
@@ -192,5 +192,11 @@
 
 HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type,
-        HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) DECLSPEC_HIDDEN;
+        HWND focus_window, DWORD flags
+#ifdef VBOX_WITH_WDDM
+        , VBOXWINEEX_D3DPRESENT_PARAMETERS *parameters
+#else
+        , D3DPRESENT_PARAMETERS *parameters
+#endif
+        ) DECLSPEC_HIDDEN;
 
 /* IDirect3DDevice9: */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c	(revision 42499)
@@ -3153,6 +3153,17 @@
 };
 
+#ifdef VBOX_WITH_WDDM
+# define PP_BASE(_p) (&(_p)->Base)
+#else
+# define PP_BASE(_p) (_p)
+#endif
 HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type,
-        HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
+        HWND focus_window, DWORD flags
+#ifdef VBOX_WITH_WDDM
+        , VBOXWINEEX_D3DPRESENT_PARAMETERS *parameters
+#else
+        , D3DPRESENT_PARAMETERS *parameters
+#endif
+        )
 {
     WINED3DPRESENT_PARAMETERS *wined3d_parameters;
@@ -3209,20 +3220,23 @@
     for (i = 0; i < count; ++i)
     {
-        wined3d_parameters[i].BackBufferWidth = parameters[i].BackBufferWidth;
-        wined3d_parameters[i].BackBufferHeight = parameters[i].BackBufferHeight;
-        wined3d_parameters[i].BackBufferFormat = wined3dformat_from_d3dformat(parameters[i].BackBufferFormat);
-        wined3d_parameters[i].BackBufferCount = parameters[i].BackBufferCount;
-        wined3d_parameters[i].MultiSampleType = parameters[i].MultiSampleType;
-        wined3d_parameters[i].MultiSampleQuality = parameters[i].MultiSampleQuality;
-        wined3d_parameters[i].SwapEffect = parameters[i].SwapEffect;
-        wined3d_parameters[i].hDeviceWindow = parameters[i].hDeviceWindow;
-        wined3d_parameters[i].Windowed = parameters[i].Windowed;
-        wined3d_parameters[i].EnableAutoDepthStencil = parameters[i].EnableAutoDepthStencil;
+        wined3d_parameters[i].BackBufferWidth = PP_BASE(&parameters[i])->BackBufferWidth;
+        wined3d_parameters[i].BackBufferHeight =PP_BASE(&parameters[i])->BackBufferHeight;
+        wined3d_parameters[i].BackBufferFormat = wined3dformat_from_d3dformat(PP_BASE(&parameters[i])->BackBufferFormat);
+        wined3d_parameters[i].BackBufferCount = PP_BASE(&parameters[i])->BackBufferCount;
+        wined3d_parameters[i].MultiSampleType =PP_BASE(&parameters[i])->MultiSampleType;
+        wined3d_parameters[i].MultiSampleQuality =PP_BASE(&parameters[i])->MultiSampleQuality;
+        wined3d_parameters[i].SwapEffect =PP_BASE(&parameters[i])->SwapEffect;
+        wined3d_parameters[i].hDeviceWindow =PP_BASE(&parameters[i])->hDeviceWindow;
+        wined3d_parameters[i].Windowed =PP_BASE(&parameters[i])->Windowed;
+        wined3d_parameters[i].EnableAutoDepthStencil =PP_BASE(&parameters[i])->EnableAutoDepthStencil;
         wined3d_parameters[i].AutoDepthStencilFormat =
-                wined3dformat_from_d3dformat(parameters[i].AutoDepthStencilFormat);
-        wined3d_parameters[i].Flags = parameters[i].Flags;
-        wined3d_parameters[i].FullScreen_RefreshRateInHz = parameters[i].FullScreen_RefreshRateInHz;
-        wined3d_parameters[i].PresentationInterval = parameters[i].PresentationInterval;
+                wined3dformat_from_d3dformat(PP_BASE(&parameters[i])->AutoDepthStencilFormat);
+        wined3d_parameters[i].Flags =PP_BASE(&parameters[i])->Flags;
+        wined3d_parameters[i].FullScreen_RefreshRateInHz =PP_BASE(&parameters[i])->FullScreen_RefreshRateInHz;
+        wined3d_parameters[i].PresentationInterval =PP_BASE(&parameters[i])->PresentationInterval;
         wined3d_parameters[i].AutoRestoreDisplayMode = TRUE;
+#ifdef VBOX_WITH_WDDM
+        wined3d_parameters[i].pHgsmi = parameters[i].pHgsmi;
+#endif
     }
 
@@ -3244,19 +3258,19 @@
     for (i = 0; i < count; ++i)
     {
-        parameters[i].BackBufferWidth = wined3d_parameters[i].BackBufferWidth;
-        parameters[i].BackBufferHeight = wined3d_parameters[i].BackBufferHeight;
-        parameters[i].BackBufferFormat = d3dformat_from_wined3dformat(wined3d_parameters[i].BackBufferFormat);
-        parameters[i].BackBufferCount = wined3d_parameters[i].BackBufferCount;
-        parameters[i].MultiSampleType = wined3d_parameters[i].MultiSampleType;
-        parameters[i].MultiSampleQuality = wined3d_parameters[i].MultiSampleQuality;
-        parameters[i].SwapEffect = wined3d_parameters[i].SwapEffect;
-        parameters[i].hDeviceWindow = wined3d_parameters[i].hDeviceWindow;
-        parameters[i].Windowed = wined3d_parameters[i].Windowed;
-        parameters[i].EnableAutoDepthStencil = wined3d_parameters[i].EnableAutoDepthStencil;
-        parameters[i].AutoDepthStencilFormat =
+        PP_BASE(&parameters[i])->BackBufferWidth = wined3d_parameters[i].BackBufferWidth;
+        PP_BASE(&parameters[i])->BackBufferHeight = wined3d_parameters[i].BackBufferHeight;
+        PP_BASE(&parameters[i])->BackBufferFormat = d3dformat_from_wined3dformat(wined3d_parameters[i].BackBufferFormat);
+        PP_BASE(&parameters[i])->BackBufferCount = wined3d_parameters[i].BackBufferCount;
+        PP_BASE(&parameters[i])->MultiSampleType = wined3d_parameters[i].MultiSampleType;
+        PP_BASE(&parameters[i])->MultiSampleQuality = wined3d_parameters[i].MultiSampleQuality;
+        PP_BASE(&parameters[i])->SwapEffect = wined3d_parameters[i].SwapEffect;
+        PP_BASE(&parameters[i])->hDeviceWindow = wined3d_parameters[i].hDeviceWindow;
+        PP_BASE(&parameters[i])->Windowed = wined3d_parameters[i].Windowed;
+        PP_BASE(&parameters[i])->EnableAutoDepthStencil = wined3d_parameters[i].EnableAutoDepthStencil;
+        PP_BASE(&parameters[i])->AutoDepthStencilFormat =
                 d3dformat_from_wined3dformat(wined3d_parameters[i].AutoDepthStencilFormat);
-        parameters[i].Flags = wined3d_parameters[i].Flags;
-        parameters[i].FullScreen_RefreshRateInHz = wined3d_parameters[i].FullScreen_RefreshRateInHz;
-        parameters[i].PresentationInterval = wined3d_parameters[i].PresentationInterval;
+        PP_BASE(&parameters[i])->Flags = wined3d_parameters[i].Flags;
+        PP_BASE(&parameters[i])->FullScreen_RefreshRateInHz = wined3d_parameters[i].FullScreen_RefreshRateInHz;
+        PP_BASE(&parameters[i])->PresentationInterval = wined3d_parameters[i].PresentationInterval;
     }
     HeapFree(GetProcessHeap(), 0, wined3d_parameters);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/directx.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/directx.c	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/directx.c	(revision 42499)
@@ -523,5 +523,9 @@
     }
 
-    hr = device_init(object, This->WineD3D, adapter, device_type, focus_window, flags, parameters);
+    hr = device_init(object, This->WineD3D, adapter, device_type, focus_window, flags,
+#ifdef VBOX_WITH_WDDM
+        (VBOXWINEEX_D3DPRESENT_PARAMETERS *)
+#endif
+                    parameters);
     if (FAILED(hr))
     {
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxWineEx.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxWineEx.h	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxWineEx.h	(revision 42499)
@@ -84,4 +84,10 @@
 VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSwapchain9Present(IDirect3DSwapChain9 *iface,
                                 IDirect3DSurface9 *surf); /* use the given surface as a frontbuffer content source */
+
+typedef struct VBOXWINEEX_D3DPRESENT_PARAMETERS
+{
+    D3DPRESENT_PARAMETERS Base;
+    struct VBOXUHGSMI *pHgsmi;
+} VBOXWINEEX_D3DPRESENT_PARAMETERS, *PVBOXWINEEX_D3DPRESENT_PARAMETERS;
 #ifdef __cplusplus
 }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h	(revision 42499)
@@ -2262,4 +2262,7 @@
     UINT PresentationInterval;
     BOOL AutoRestoreDisplayMode;
+#ifdef VBOX_WITH_WDDM
+    struct VBOXUHGSMI *pHgsmi;
+#endif
 } WINED3DPRESENT_PARAMETERS;
 typedef struct _WINED3DSURFACE_DESC {
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c	(revision 42499)
@@ -1532,5 +1532,9 @@
  *****************************************************************************/
 struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target,
-        const struct wined3d_format_desc *ds_format_desc)
+        const struct wined3d_format_desc *ds_format_desc
+#ifdef VBOX_WITH_WDDM
+        , struct VBOXUHGSMI *pHgsmi
+#endif
+        )
 {
     IWineD3DDeviceImpl *device = swapchain->device;
@@ -1549,4 +1553,12 @@
     TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle);
 
+#ifdef VBOX_WITH_WDDM
+    if (!pHgsmi)
+    {
+        ERR("HGSMI should be specified!");
+        return NULL;
+    }
+#endif
+
     ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
     if (!ret)
@@ -1644,5 +1656,11 @@
     }
 
-    ctx = pwglCreateContext(hdc);
+    ctx = pVBoxCreateContext(hdc
+#ifdef VBOX_WITH_WDDM
+            , pHgsmi
+#else
+            , NULL
+#endif
+            );
     if (device->numContexts)
     {
@@ -1955,5 +1973,9 @@
     {
         Assert(!device->NumberOfSwapChains);
-        context = context_create(swapchain, target, ds_format_desc);
+        context = context_create(swapchain, target, ds_format_desc
+#ifdef VBOX_WITH_WDDM
+                , device->pHgsmi
+#endif
+                );
     }
     else
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c	(revision 42499)
@@ -1605,4 +1605,12 @@
     if(!This->adapter->opengl) return WINED3DERR_INVALIDCALL;
 
+#ifdef VBOX_WITH_WDDM
+    if (!pPresentationParameters->pHgsmi)
+    {
+        ERR("hgsmi not specified!");
+        return WINED3DERR_INVALIDCALL;
+    }
+    This->pHgsmi = pPresentationParameters->pHgsmi;
+#endif
     TRACE("(%p) : Creating stateblock\n", This);
     /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
@@ -6456,4 +6464,8 @@
     IWineD3DSurfaceImpl *target;
 
+#ifdef VBOX_WITH_WDDM
+    ERR("Should not be here!");
+#endif
+
 #ifndef VBOX_WITH_WDDM
     /* Recreate the primary swapchain's context */
@@ -6467,5 +6479,9 @@
 
     target = (IWineD3DSurfaceImpl *)(swapchain->backBuffer ? swapchain->backBuffer[0] : swapchain->frontBuffer);
-    if (!(context = context_create(swapchain, target, swapchain->ds_format)))
+    if (!(context = context_create(swapchain, target, swapchain->ds_format
+#ifdef VBOX_WITH_WDDM
+                , This->pHgsmi
+#endif
+            )))
     {
         WARN("Failed to create context.\n");
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c	(revision 42499)
@@ -36,4 +36,8 @@
 #include <stdio.h>
 #include "wined3d_private.h"
+
+#ifdef VBOX_WITH_WDDM
+# include <VBox/VBoxCrHgsmi.h>
+#endif
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -254,5 +258,5 @@
 }
 
-static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
+static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx, struct VBOXUHGSMI *pHgsmi)
 {
     PIXELFORMATDESCRIPTOR pfd;
@@ -300,5 +304,5 @@
 
     /* Create a GL context. */
-    ctx->gl_ctx = pwglCreateContext(ctx->dc);
+    ctx->gl_ctx = pVBoxCreateContext(ctx->dc, pHgsmi);
     if (!ctx->gl_ctx)
     {
@@ -5309,4 +5313,5 @@
     BOOL ret;
     int ps_selected_mode, vs_selected_mode;
+    struct VBOXUHGSMI *pHgsmi = NULL;
 
     /* No need to hold any lock. The calling library makes sure only one thread calls
@@ -5355,4 +5360,5 @@
 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
     WGL_FUNCS_GEN;
+    VBOX_FUNCS_GEN;
 #undef USE_WGL_FUNC
 
@@ -5380,4 +5386,13 @@
     glDisableWINE = glDisable;
 
+#ifdef VBOX_WITH_WDDM
+    pHgsmi = VBoxCrHgsmiCreate();
+    if (!pHgsmi)
+    {
+        ERR("VBoxCrHgsmiCreate failed");
+        goto nogl_adapter;
+    }
+#endif
+
     /* For now only one default adapter */
     {
@@ -5406,5 +5421,5 @@
                 adapter->luid.HighPart, adapter->luid.LowPart);
 
-        if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
+        if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx, pHgsmi))
         {
             ERR("Failed to get a gl context for default adapter\n");
@@ -5595,4 +5610,9 @@
     TRACE("%u adapters successfully initialized\n", This->adapter_count);
 
+#ifdef VBOX_WITH_WDDM
+    VBoxCrHgsmiDestroy(pHgsmi);
+    pHgsmi = NULL;
+#endif
+
     return TRUE;
 
@@ -5615,4 +5635,12 @@
 #endif
     initPixelFormatsNoGL(&This->adapters[0].gl_info);
+
+#ifdef VBOX_WITH_WDDM
+    if (pHgsmi)
+    {
+        VBoxCrHgsmiDestroy(pHgsmi);
+        pHgsmi = NULL;
+    }
+#endif
 
     This->adapter_count = 1;
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c	(revision 42499)
@@ -1233,5 +1233,13 @@
     TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId());
 
-    if (!(ctx = context_create(This, (IWineD3DSurfaceImpl *)This->frontBuffer, This->ds_format)))
+#ifdef VBOX_WITH_WDDM
+     ERR("Should not be here");
+#endif
+
+    if (!(ctx = context_create(This, (IWineD3DSurfaceImpl *)This->frontBuffer, This->ds_format
+#ifdef VBOX_WITH_WDDM
+                , This->device->pHgsmi
+#endif
+            )))
     {
         ERR("Failed to create a new context for the swapchain\n");
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c	(revision 42499)
@@ -18,4 +18,8 @@
 #include "wined3d_private.h"
 #include "vboxext.h"
+#ifdef VBOX_WITH_WDDM
+#include <VBox/VBoxCrHgsmi.h>
+#include <iprt/err.h>
+#endif
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_vbox);
@@ -282,6 +286,21 @@
 {
     HRESULT hr = S_OK;
+#ifdef VBOX_WITH_WDDM
+    int rc = VBoxCrHgsmiInit();
+    if (!RT_SUCCESS(rc))
+    {
+        ERR("VBoxCrHgsmiInit failed rc %d", rc);
+        return E_FAIL;
+    }
+#endif
     memset(&g_VBoxExtGlobal, 0, sizeof (g_VBoxExtGlobal));
     hr = VBoxExtWorkerCreate(&g_VBoxExtGlobal.Worker);
+    if (SUCCEEDED(hr))
+        return S_OK;
+
+    /* failure branch */
+#ifdef VBOX_WITH_WDDM
+    VBoxCrHgsmiTerm();
+#endif
     return hr;
 }
@@ -305,4 +324,9 @@
         return hr;
     }
+
+#ifdef VBOX_WITH_WDDM
+    VBoxCrHgsmiTerm();
+#endif
+
     return S_OK;
 }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h	(revision 42499)
@@ -1374,5 +1374,4 @@
 
 /* WGL functions */
-HGLRC (WINAPI *pwglCreateContext)(HDC) DECLSPEC_HIDDEN;
 BOOL (WINAPI *pwglDeleteContext)(HGLRC) DECLSPEC_HIDDEN;
 HGLRC (WINAPI *pwglGetCurrentContext)(void) DECLSPEC_HIDDEN;
@@ -1382,4 +1381,6 @@
 BOOL (WINAPI *pwglSwapLayerBuffers)(HDC, UINT) DECLSPEC_HIDDEN;
 BOOL (WINAPI *pwglShareLists)(HGLRC, HGLRC) DECLSPEC_HIDDEN;
+
+HGLRC (WINAPI *pVBoxCreateContext)(HDC, struct VBOXUHGSMI*) DECLSPEC_HIDDEN;
 
 #define GL_FUNCS_GEN \
@@ -1721,5 +1722,4 @@
 
 #define WGL_FUNCS_GEN \
-    USE_WGL_FUNC(wglCreateContext) \
     USE_WGL_FUNC(wglDeleteContext) \
     USE_WGL_FUNC(wglGetCurrentContext) \
@@ -1729,4 +1729,7 @@
     USE_WGL_FUNC(wglShareLists) \
     USE_WGL_FUNC(wglSwapLayerBuffers)
+
+#define VBOX_FUNCS_GEN \
+    USE_WGL_FUNC(VBoxCreateContext)
 
 /* OpenGL extensions. */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h	(revision 42498)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h	(revision 42499)
@@ -1283,5 +1283,9 @@
         GLenum fbo_target, DWORD idx, IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN;
 struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target,
-        const struct wined3d_format_desc *ds_format_desc) DECLSPEC_HIDDEN;
+        const struct wined3d_format_desc *ds_format_desc
+#ifdef VBOX_WITH_WDDM
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+        ) DECLSPEC_HIDDEN;
 struct IWineD3DDeviceImpl *context_get_device(const struct wined3d_context *context); DECLSPEC_HIDDEN;
 #ifdef VBOX_WITH_WDDM
@@ -1800,4 +1804,8 @@
     struct wined3d_context **contexts;
     UINT                    numContexts;
+
+#ifdef VBOX_WITH_WDDM
+    struct VBOXUHGSMI *pHgsmi;
+#endif
 
 #ifdef VBOX_WINE_WITH_SHADER_CACHE
Index: /trunk/src/VBox/Additions/common/crOpenGL/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/Makefile.kmk	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/Makefile.kmk	(revision 42499)
@@ -212,4 +212,10 @@
  endif
 endif
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGL_DEFS.win   += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGL_DEFS.win   += VBOX_WITH_WDDM
+endif
 
 ifdef VBOX_WITH_WDDM
@@ -402,4 +408,10 @@
 	$(PATH_STAGE_LIB)/additions/VBoxOGLspuload$(VBOX_SUFF_LIB) \
 	$(PATH_STAGE_LIB)/additions/VBoxOGLcrstate$(VBOX_SUFF_LIB)
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLarrayspu_DEFS.win   += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLarrayspu_DEFS.win   += VBOX_WITH_WDDM
+endif
 
 ifdef VBOX_WITH_WDDM
@@ -440,4 +452,10 @@
 VBoxOGLpassthroughspu_LIBS        = \
 	$(VBOX_LIB_OGL_CRUTIL)
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLpassthroughspu_DEFS.win   += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLpassthroughspu_DEFS.win   += VBOX_WITH_WDDM
+endif
 
 ifdef VBOX_WITH_WDDM
@@ -510,4 +528,10 @@
 	$(PATH_STAGE_LIB)/additions/VBoxOGLcrstate$(VBOX_SUFF_LIB) \
 	$(PATH_STAGE_LIB)/additions/VBoxOGLcrpacker$(VBOX_SUFF_LIB)
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLpackspu_DEFS.win   += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLpackspu_DEFS.win   += VBOX_WITH_WDDM
+endif
 
 ifdef VBOX_WITH_WDDM
@@ -581,4 +605,10 @@
 	$(PATH_STAGE_LIB)/additions/VBoxOGLspuload$(VBOX_SUFF_LIB) \
 	$(PATH_STAGE_LIB)/additions/VBoxOGLcrstate$(VBOX_SUFF_LIB)
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLfeedbackspu_DEFS.win   += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLfeedbackspu_DEFS.win   += VBOX_WITH_WDDM
+endif
 
 ifdef VBOX_WITH_WDDM
Index: /trunk/src/VBox/Additions/common/crOpenGL/context.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/context.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/context.c	(revision 42499)
@@ -123,5 +123,8 @@
 #ifdef VBOX_WITH_WDDM
     if (stub.bRunningUnderWDDM)
+    {
+        crError("Should not be here: WindowCreate/Destroy & VBoxPackGetInjectID recuire connection id!");
         winInfo->mapped = 0;
+    }
     else
 #endif
@@ -148,5 +151,5 @@
 #endif
 #ifdef CR_NEWWINTRACK
-    winInfo->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID();
+    winInfo->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(0);
 #endif
     winInfo->spuWindow = spuWin;
@@ -347,4 +350,11 @@
         stub.spu->dispatch_table.DestroyContext( context->spuContext );
         crHashtableWalk(stub.windowTable, stubWindowCheckOwnerCB, context);
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        if (context->spuConnection)
+        {
+            stub.spu->dispatch_table.VBoxConDestroy(context->spuConnection);
+            context->spuConnection = 0;
+        }
+#endif
     }
 
@@ -379,7 +389,11 @@
     ContextInfo *
 stubNewContext( const char *dpyName, GLint visBits, ContextType type,
-    unsigned long shareCtx )
-{
-    GLint spuContext = -1, spuShareCtx = 0;
+    unsigned long shareCtx
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        , struct VBOXUHGSMI *pHgsmi
+#endif
+    )
+{
+    GLint spuContext = -1, spuShareCtx = 0, spuConnection = 0;
     ContextInfo *context;
 
@@ -393,8 +407,26 @@
 
     if (type == CHROMIUM) {
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        if (pHgsmi)
+        {
+            spuConnection = stub.spu->dispatch_table.VBoxConCreate(pHgsmi);
+            if (!spuConnection)
+            {
+                crWarning("VBoxConCreate failed");
+                return NULL;
+            }
+        }
+#endif
         spuContext
-            = stub.spu->dispatch_table.CreateContext(dpyName, visBits, spuShareCtx);
+            = stub.spu->dispatch_table.VBoxCreateContext(spuConnection, dpyName, visBits, spuShareCtx);
         if (spuContext < 0)
+        {
+            crWarning("VBoxCreateContext failed");
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+            if (spuConnection)
+                stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
+#endif
             return NULL;
+        }
     }
 
@@ -402,4 +434,8 @@
     if (!context) {
         stub.spu->dispatch_table.DestroyContext(spuContext);
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        if (spuConnection)
+            stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
+#endif
         return NULL;
     }
@@ -415,4 +451,9 @@
     crStrncpy(context->dpyName, dpyName, MAX_DPY_NAME);
     context->dpyName[MAX_DPY_NAME-1] = 0;
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    context->spuConnection = spuConnection;
+    context->pHgsmi = pHgsmi;
+#endif
 
 #ifdef CHROMIUM_THREADSAFE
@@ -1019,19 +1060,34 @@
             GLint spuShareCtx = 0;
 #endif
-
+            GLint spuConnection = 0;
             CRASSERT(stub.spu);
             CRASSERT(stub.spu->dispatch_table.CreateContext);
             context->type = CHROMIUM;
 
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+            if (context->pHgsmi)
+            {
+                spuConnection = stub.spu->dispatch_table.VBoxConCreate(context->pHgsmi);
+                if (!spuConnection)
+                {
+                    crWarning("VBoxConCreate failed");
+                    return GL_FALSE;
+                }
+                context->spuConnection = spuConnection;
+            }
+#endif
+
             context->spuContext
-                = stub.spu->dispatch_table.CreateContext( context->dpyName,
-                                                          context->visBits,
-                                                          spuShareCtx );
+                = stub.spu->dispatch_table.VBoxCreateContext(spuConnection, context->dpyName,
+                                                    context->visBits,
+                                                    spuShareCtx);
             if (window->spuWindow == -1)
             {
                 /*crDebug("(1)stubMakeCurrent ctx=%p(%i) window=%p(%i)", context, context->spuContext, window, window->spuWindow);*/
-                window->spuWindow = stub.spu->dispatch_table.WindowCreate( window->dpyName, context->visBits );
+                window->spuWindow = stub.spu->dispatch_table.VBoxWindowCreate(
+                        spuConnection,
+                        window->dpyName, context->visBits );
 #ifdef CR_NEWWINTRACK
-                window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID();
+                window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(spuConnection);
 #endif
             }
@@ -1089,7 +1145,19 @@
             {
                 /*crDebug("(2)stubMakeCurrent ctx=%p(%i) window=%p(%i)", context, context->spuContext, window, window->spuWindow);*/
-                window->spuWindow = stub.spu->dispatch_table.WindowCreate( window->dpyName, context->visBits );
+                window->spuWindow = stub.spu->dispatch_table.VBoxWindowCreate(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                        context->spuConnection,
+#else
+                        0,
+#endif
+                        window->dpyName, context->visBits );
 #ifdef CR_NEWWINTRACK
-                window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID();
+                window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(
+# if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                        context->spuConnection
+# else
+                        0
+# endif
+                        );
 #endif
                 if (context->currentDrawable && context->currentDrawable->type==CHROMIUM 
@@ -1128,4 +1196,7 @@
     window->type = context->type;
     window->pOwner = context;
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    window->spuConnection = context->spuConnection;
+#endif
     context->currentDrawable = window;
     stubSetCurrentContext(context);
Index: /trunk/src/VBox/Additions/common/crOpenGL/defs.py
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/defs.py	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/defs.py	(revision 42499)
@@ -495,4 +495,5 @@
 crMakeCurrent
 crSwapBuffers
-crGetProcAddress"""
+crGetProcAddress
+VBoxCreateContext"""
 #print "DllMain"
Index: /trunk/src/VBox/Additions/common/crOpenGL/defs64.py
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/defs64.py	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/defs64.py	(revision 42499)
@@ -476,4 +476,5 @@
 crMakeCurrent
 crSwapBuffers
-crGetProcAddress"""
+crGetProcAddress
+VBoxCreateContext"""
 #print "DllMain"
Index: /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c	(revision 42499)
@@ -24,5 +24,5 @@
 
 GLint FEEDBACKSPU_APIENTRY
-feedbackspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+feedbackspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx )
 {
     GLint ctx, slot;
@@ -32,5 +32,5 @@
 #endif
 
-    ctx = feedback_spu.child.CreateContext(dpyName, visual, shareCtx);
+    ctx = feedback_spu.child.VBoxCreateContext(con, dpyName, visual, shareCtx);
 
     /* find an empty context slot */
@@ -53,4 +53,10 @@
 
     return ctx;
+}
+
+GLint FEEDBACKSPU_APIENTRY
+feedbackspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+{
+    return feedbackspu_VBoxCreateContext( 0, dpyName, visual, shareCtx );
 }
 
Index: /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py	(revision 42499)
@@ -16,5 +16,5 @@
 #include "feedbackspu_proto.h"
 """
-custom = ["CreateContext", "MakeCurrent", "DestroyContext"]
+custom = ["CreateContext", "VBoxCreateContext", "MakeCurrent", "DestroyContext"]
 
 keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
Index: /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special	(revision 42499)
@@ -64,2 +64,3 @@
 VBoxAttachThread
 VBoxDetachThread
+VBoxCreateContext
Index: /trunk/src/VBox/Additions/common/crOpenGL/icd_drv.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/icd_drv.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/icd_drv.c	(revision 42499)
@@ -164,5 +164,9 @@
 #endif
 
-    context = stubNewContext(dpyName, desiredVisual, UNDECIDED, 0);
+    context = stubNewContext(dpyName, desiredVisual, UNDECIDED, 0
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        , NULL
+#endif
+            );
     if (!context)
         return 0;
Index: /trunk/src/VBox/Additions/common/crOpenGL/load.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/load.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/load.c	(revision 42499)
@@ -1015,4 +1015,5 @@
     VBOXCR_UPDATEWNDCB RegionsData;
     HRESULT hr;
+    GLint spuConnection = 0;
 # endif
 #endif
@@ -1061,9 +1062,18 @@
         }
     }
-# endif
-#endif
+# endif /* VBOX_WITH_WDDM */
+#endif /* WINDOWS */
 
     crLockMutex(&stub.mutex);
-    stub.spu->dispatch_table.VBoxPackSetInjectThread();
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+    spuConnection =
+#endif
+            stub.spu->dispatch_table.VBoxPackSetInjectThread(NULL);
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+    if (!spuConnection)
+    {
+        crError("VBoxPackSetInjectThread failed!");
+    }
+#endif
     crUnlockMutex(&stub.mutex);
 
@@ -1142,4 +1152,8 @@
         VBoxDispMpTstCallbacks.pfnDisableEvents();
     }
+    if (spuConnection)
+    {
+        stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
+    }
     if (hVBoxD3D)
     {
@@ -1203,5 +1217,9 @@
         ns.name = "vboxhgcm://host:0";
         ns.buffer_size = 1024;
-        crNetServerConnect(&ns);
+        crNetServerConnect(&ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , NULL
+#endif
+                );
         if (!ns.conn)
         {
@@ -1414,5 +1432,9 @@
         ns.name = "vboxhgcm://host:0";
         ns.buffer_size = 1024;
-        crNetServerConnect(&ns);
+        crNetServerConnect(&ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , NULL
+#endif
+);
         if (!ns.conn)
         {
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu.h
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu.h	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu.h	(revision 42499)
@@ -67,4 +67,8 @@
     int idxThreadInUse; /*index of any used thread*/
 
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+    bool bRunningUnderWDDM;
+#endif
+
     int numContexts;
     ContextInfo context[CR_MAX_CONTEXTS];
@@ -73,11 +77,18 @@
 extern PackSPU pack_spu;
 
+#define THREAD_OFFSET_MAGIC 2000
+
 #ifdef CHROMIUM_THREADSAFE
 extern CRmutex _PackMutex;
 extern CRtsd _PackTSD;
-#define GET_THREAD(T)  ThreadInfo *T = crGetTSD(&_PackTSD)
+#define GET_THREAD_VAL()  (crGetTSD(&_PackTSD))
+#define GET_THREAD_VAL_ID(_id) (&(pack_spu.thread[(_id) - THREAD_OFFSET_MAGIC]))
 #else
-#define GET_THREAD(T)  ThreadInfo *T = &(pack_spu.thread[0])
+#define GET_THREAD_VAL()  (&(pack_spu.thread[0]))
 #endif
+#define GET_THREAD(T)  ThreadInfo *T = GET_THREAD_VAL()
+#define GET_THREAD_ID(T, _id) ThreadInfo *T = GET_THREAD_VAL_ID(_id)
+
+
 
 #define GET_CONTEXT(C)                      \
@@ -85,7 +96,18 @@
   ContextInfo *C = thread->currentContext
 
+#define CRPACKSPU_WRITEBACK_WAIT(_thread, _writeback)  CR_WRITEBACK_WAIT((_thread)->netServer.conn, _writeback)
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM) && defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+# define CRPACKSPU_IS_WDDM_CRHGSMI() (pack_spu.bRunningUnderWDDM)
+#else
+# define CRPACKSPU_IS_WDDM_CRHGSMI() (GL_FALSE)
+#endif
+
 extern void packspuCreateFunctions( void );
 extern void packspuSetVBoxConfiguration( const SPU *child_spu );
-extern void packspuConnectToServer( CRNetServer *server );
+extern void packspuConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+        );
 extern void packspuFlush( void *arg );
 extern void packspuHuge( CROpcode opcode, void *buf );
@@ -93,6 +115,11 @@
 extern GLboolean packspuSyncOnFlushes();
 
-extern ThreadInfo *packspuNewThread( unsigned long id );
+extern ThreadInfo *packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                struct VBOXUHGSMI *pHgsmi
+#endif
+        );
 
+extern ThreadInfo *packspuNewCtxThread( struct VBOXUHGSMI *pHgsmi );
 
 #endif /* CR_PACKSPU_H */
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c	(revision 42499)
@@ -20,6 +20,5 @@
     packspuFlush((void *) thread);
 
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 }
 
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c	(revision 42499)
@@ -560,6 +560,5 @@
         crPackIsEnabled(cap, &return_val, &writeback);
 	    packspuFlush( (void *) thread );
-	    while (writeback)
-		  crNetRecv();
+	    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
         CRASSERT(return_val==res);
     }
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c	(revision 42499)
@@ -12,5 +12,4 @@
 
 #define MAGIC_OFFSET 3000
-
 
 /*
@@ -21,5 +20,9 @@
  * using threads.
  */
-ThreadInfo *packspuNewThread( unsigned long id )
+ThreadInfo *packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                struct VBOXUHGSMI *pHgsmi
+#endif
+)
 {
     ThreadInfo *thread=NULL;
@@ -32,4 +35,8 @@
 #endif
 
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    CRASSERT(!CRPACKSPU_IS_WDDM_CRHGSMI() == !pHgsmi);
+#endif
+
     CRASSERT(pack_spu.numThreads < MAX_THREADS);
     for (i=0; i<MAX_THREADS; ++i)
@@ -44,5 +51,8 @@
 
     thread->inUse = GL_TRUE;
-    thread->id = id;
+    if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+        thread->id = crThreadID();
+    else
+        thread->id = THREAD_OFFSET_MAGIC + i;
     thread->currentContext = NULL;
     thread->bInjectThread = GL_FALSE;
@@ -52,5 +62,9 @@
     thread->netServer.buffer_size = pack_spu.buffer_size;
     if (pack_spu.numThreads == 0) {
-        packspuConnectToServer( &(thread->netServer) );
+        packspuConnectToServer( &(thread->netServer)
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , pHgsmi
+#endif
+                );
         if (!thread->netServer.conn) {
             return NULL;
@@ -60,5 +74,9 @@
     else {
         /* a new pthread */
-        crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer));
+        crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer)
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , pHgsmi
+#endif
+        );
         CRASSERT(thread->netServer.conn);
     }
@@ -75,8 +93,16 @@
     crPackFlushArg( thread->packer, (void *) thread );
     crPackSendHugeFunc( thread->packer, packspuHuge );
-    crPackSetContext( thread->packer );
-
-#ifdef CHROMIUM_THREADSAFE
-    crSetTSD(&_PackTSD, thread);
+
+    if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        crPackSetContext( thread->packer );
+    }
+
+
+#ifdef CHROMIUM_THREADSAFE
+    if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        crSetTSD(&_PackTSD, thread);
+    }
 #endif
 
@@ -89,19 +115,119 @@
 }
 
-
 GLint PACKSPU_APIENTRY
-packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+packspu_VBoxConCreate(struct VBOXUHGSMI *pHgsmi)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    ThreadInfo * thread;
+    CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+    CRASSERT(pHgsmi);
+
+    thread = packspuNewThread(pHgsmi);
+
+    if (thread)
+    {
+        CRASSERT(thread->id);
+        CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
+                && GET_THREAD_VAL_ID(thread->id) == thread);
+        return thread->id;
+    }
+    crError("packspuNewThread failed");
+#endif
+    return 0;
+}
+
+void PACKSPU_APIENTRY
+packspu_VBoxConFlush(GLint con)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    GET_THREAD_ID(thread, con);
+    CRASSERT(con);
+    CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+    CRASSERT(thread->packer);
+    packspuFlush((void *) thread);
+#endif
+}
+
+void PACKSPU_APIENTRY
+packspu_VBoxConDestroy(GLint con)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    GET_THREAD_ID(thread, con);
+    CRASSERT(con);
+    CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+    CRASSERT(pack_spu.numThreads>0);
+    CRASSERT(thread->packer);
+    packspuFlush((void *) thread);
+
+    crLockMutex(&_PackMutex);
+
+    crPackDeleteContext(thread->packer);
+
+    crNetFreeConnection(thread->netServer.conn);
+
+    pack_spu.numThreads--;
+    /*note can't shift the array here, because other threads have TLS references to array elements*/
+    crMemZero(thread, sizeof(ThreadInfo));
+
+#if 0
+    if (&pack_spu.thread[pack_spu.idxThreadInUse]==thread)
+    {
+        int i;
+        crError("Should not be here since idxThreadInUse should be always 0 for the dummy connection created in packSPUInit!");
+        for (i=0; i<MAX_THREADS; ++i)
+        {
+            if (pack_spu.thread[i].inUse)
+            {
+                pack_spu.idxThreadInUse=i;
+                break;
+            }
+        }
+    }
+#endif
+    crUnlockMutex(&_PackMutex);
+#endif
+}
+
+
+GLint PACKSPU_APIENTRY
+packspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx )
 {
     GET_THREAD(thread);
+    CRPackContext * curPacker = crPackGetContext();
+    ThreadInfo *curThread = thread;
     int writeback = 1;
     GLint serverCtx = (GLint) -1;
     int slot;
 
+    CRASSERT(!curThread == !curPacker);
+    CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
 #ifdef CHROMIUM_THREADSAFE
     crLockMutex(&_PackMutex);
 #endif
 
-    if (!thread) {
-        thread = packspuNewThread(crThreadID());
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
+#endif
+
+    if (CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        if (!con)
+        {
+            crError("connection should be specified!");
+            return -1;
+        }
+        thread = GET_THREAD_VAL_ID(con);
+    }
+    else
+    {
+        CRASSERT(!con);
+        if (!thread)
+        {
+            thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                NULL
+#endif
+                );
+        }
     }
     CRASSERT(thread);
@@ -145,6 +271,5 @@
     }
     else {
-        while (writeback)
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
         if (pack_spu.swap) {
@@ -156,4 +281,10 @@
 #endif
             crWarning("Failure in packspu_CreateContext");
+
+            if (CRPACKSPU_IS_WDDM_CRHGSMI())
+            {
+                /* restore the packer context to the tls */
+                crPackSetContext(curPacker);
+            }
             return -1;  /* failed */
         }
@@ -171,4 +302,10 @@
     }
 
+    if (CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        thread->currentContext = &pack_spu.context[slot];
+        pack_spu.context[slot].currentThread = thread;
+    }
+
     /* Fill in the new context info */
     /* XXX fix-up sharedCtx param here */
@@ -181,19 +318,41 @@
 #endif
 
+    if (CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        /* restore the packer context to the tls */
+        crPackSetContext(curPacker);
+    }
+
     return MAGIC_OFFSET + slot;
 }
 
+GLint PACKSPU_APIENTRY
+packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+{
+    return packspu_VBoxCreateContext( 0, dpyName, visual, shareCtx );
+}
+
 
 void PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx )
 {
+    GET_THREAD(thread);
+    ThreadInfo *curThread = thread;
     const int slot = ctx - MAGIC_OFFSET;
-    ContextInfo *context;
-    GET_THREAD(thread);
+    ContextInfo *context, *curContext;
+    CRPackContext * curPacker = crPackGetContext();
 
     CRASSERT(slot >= 0);
     CRASSERT(slot < pack_spu.numContexts);
+
+    context = &(pack_spu.context[slot]);
+
+    if (CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        thread = context->currentThread;
+        crPackSetContext(thread->packer);
+        CRASSERT(!(thread->packer == curPacker) == !(thread == curThread));
+    }
     CRASSERT(thread);
-
-    context = &(pack_spu.context[slot]);
+    curContext = curThread ? curThread->currentContext : NULL;
 
     if (pack_spu.swap)
@@ -206,22 +365,48 @@
     context->clientState = NULL;
     context->serverCtx = 0;
-
-    if (thread->currentContext == context) {
-        thread->currentContext = NULL;
+    context->currentThread = NULL;
+
+    if (curContext == context)
+    {
+        if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+        {
+            curThread->currentContext = NULL;
+        }
+        else
+        {
+            CRASSERT(thread == curThread);
+            crSetTSD(&_PackTSD, NULL);
+            crPackSetContext(NULL);
+        }
         crStateMakeCurrent( NULL );
     }
+    else
+    {
+        if (CRPACKSPU_IS_WDDM_CRHGSMI())
+        {
+            crPackSetContext(curPacker);
+        }
+    }
 }
 
 void PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
 {
-    GET_THREAD(thread);
+    ThreadInfo *thread;
     GLint serverCtx;
     ContextInfo *newCtx;
 
-    if (!thread) {
-        thread = packspuNewThread( crThreadID() );
-    }
-    CRASSERT(thread);
-    CRASSERT(thread->packer);
+    if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        thread = GET_THREAD_VAL();
+        if (!thread) {
+            thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                    NULL
+#endif
+                    );
+        }
+        CRASSERT(thread);
+        CRASSERT(thread->packer);
+    }
 
     if (ctx) {
@@ -234,26 +419,36 @@
         CRASSERT(newCtx->clientState);  /* verify valid */
 
-        if (newCtx->fAutoFlush)
-        {
-            if (newCtx->currentThread && newCtx->currentThread != thread)
+        if (CRPACKSPU_IS_WDDM_CRHGSMI())
+        {
+            thread = newCtx->currentThread;
+            CRASSERT(thread);
+            crSetTSD(&_PackTSD, thread);
+            crPackSetContext( thread->packer );
+        }
+        else
+        {
+            if (!newCtx->fAutoFlush)
             {
-                crLockMutex(&_PackMutex);
-                /* do a flush for the previously assigned thread
-                 * to ensure all commands issued there are submitted */
-                if (newCtx->currentThread
-                    && newCtx->currentThread->inUse
-                    && newCtx->currentThread->netServer.conn
-                    && newCtx->currentThread->packer && newCtx->currentThread->packer->currentBuffer)
+                if (newCtx->currentThread && newCtx->currentThread != thread)
                 {
-                    packspuFlush((void *) newCtx->currentThread);
+                    crLockMutex(&_PackMutex);
+                    /* do a flush for the previously assigned thread
+                     * to ensure all commands issued there are submitted */
+                    if (newCtx->currentThread
+                        && newCtx->currentThread->inUse
+                        && newCtx->currentThread->netServer.conn
+                        && newCtx->currentThread->packer && newCtx->currentThread->packer->currentBuffer)
+                    {
+                        packspuFlush((void *) newCtx->currentThread);
+                    }
+                    crUnlockMutex(&_PackMutex);
                 }
-                crUnlockMutex(&_PackMutex);
+                newCtx->currentThread = thread;
             }
-            newCtx->currentThread = thread;
-        }
-
-        thread->currentContext = newCtx;
-
-        crPackSetContext( thread->packer );
+
+            thread->currentContext = newCtx;
+            crPackSetContext( thread->packer );
+        }
+
         crStateMakeCurrent( newCtx->clientState );
         //crStateSetCurrentPointers(newCtx->clientState, &thread->packer->current);
@@ -261,6 +456,20 @@
     }
     else {
-        thread->currentContext = NULL;
         crStateMakeCurrent( NULL );
+        if (CRPACKSPU_IS_WDDM_CRHGSMI())
+        {
+            thread = GET_THREAD_VAL();
+            if (!thread)
+            {
+                CRASSERT(crPackGetContext() == NULL);
+                return;
+            }
+            CRASSERT(thread->currentContext);
+            CRASSERT(thread->packer == crPackGetContext());
+        }
+        else
+        {
+            thread->currentContext = NULL;
+        }
         newCtx = NULL;
         serverCtx = 0;
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c	(revision 42499)
@@ -93,6 +93,5 @@
 
 	packspuFlush((void *) thread);
-	while (writeback)
-		crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     crStateSetFramebufferStatus(target, status);
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py	(revision 42499)
@@ -132,6 +132,5 @@
                 crPack%s(%s, &writeback);
                 packspuFlush( (void *) thread );
-                while (writeback)
-                    crNetRecv();
+                CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
                 for (i=0; i<__numValues(pname); ++i)
                 {
@@ -164,6 +163,5 @@
         print '\t}'
         print '\tpackspuFlush( (void *) thread );'
-        print '\twhile (writeback)'
-        print '\t\tcrNetRecv();'
+        print '\tCRPACKSPU_WRITEBACK_WAIT(thread, writeback);'
 
 
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c	(revision 42499)
@@ -46,6 +46,5 @@
 
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     if (length) *length = pLocal->length;
@@ -70,6 +69,5 @@
 
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     if (length) *length = pLocal->length;
@@ -94,6 +92,5 @@
 
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     if (count) *count=*pLocal;
@@ -116,6 +113,5 @@
 
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     if (count) *count=*pLocal;
@@ -140,6 +136,5 @@
 
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     CRASSERT((pLocal[0]) <= maxLength);
@@ -164,6 +159,5 @@
 
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     if (length) *length=*pLocal;
@@ -186,6 +180,5 @@
 
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     if (length) *length=*pLocal;
@@ -208,6 +201,5 @@
 
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     if (length) *length=*pLocal;
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c	(revision 42499)
@@ -29,6 +29,5 @@
     packspuFlush( (void *) thread );
 
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 }
 
@@ -66,6 +65,5 @@
     packspuFlush( (void *) thread );
 
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     CRASSERT(crStrlen((char *)return_value) < 10*1000);
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c	(revision 42499)
@@ -42,6 +42,5 @@
     }
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     if (pack_spu.swap)
     {
@@ -72,6 +71,5 @@
     }
     packspuFlush((void *) thread);
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     if (pack_spu.swap)
     {
@@ -104,6 +102,5 @@
 
         packspuFlush((void *) thread);
-        while (writeback)
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
         crStateGLSLProgramCacheUniforms(program, pData[0], &pData[1]);
@@ -137,4 +134,6 @@
     GLuint hwid = crStateGetProgramHWID(obj);
 
+    CRASSERT(obj);
+
     if (hwid)
     {
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c	(revision 42499)
@@ -47,6 +47,14 @@
     packspuSetVBoxConfiguration( child );
 
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+    pack_spu.bRunningUnderWDDM = !!GetModuleHandle("VBoxDispD3D");
+#endif
+
     /* This connects to the server, sets up the packer, etc. */
-    thread = packspuNewThread( crThreadID() );
+    thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+            NULL
+#endif
+             );
 
     if (!thread) {
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c	(revision 42499)
@@ -98,6 +98,5 @@
             packspuFlush( (void *) thread );
 
-            while (writeback)
-                crNetRecv();
+            CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
         }
     }
@@ -117,6 +116,5 @@
             crPackWriteback(&writeback);
             packspuFlush( (void *) thread );
-            while (writeback)
-                crNetRecv();
+            CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
         }
     }
@@ -158,5 +156,26 @@
 }
 
-GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
+void PACKSPU_APIENTRY packspu_VBoxWindowDestroy( GLint con, GLint window )
+{
+    if (CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        ThreadInfo *thread;
+        CRPackContext * curPacker = crPackGetContext();
+        if (!con)
+        {
+            crError("connection expected!!");
+            return;
+        }
+        thread = GET_THREAD_VAL_ID(con);
+        crPackSetContext(thread->packer);
+        crPackWindowDestroy(window);
+        if (curPacker != thread->packer)
+            crPackSetContext(curPacker);
+        return;
+    }
+    crPackWindowDestroy(window);
+}
+
+GLint PACKSPU_APIENTRY packspu_VBoxWindowCreate( GLint con, const char *dpyName, GLint visBits )
 {
     GET_THREAD(thread);
@@ -164,10 +183,30 @@
     int writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
     GLint return_val = (GLint) 0;
-
-    if (!thread) {
-        thread = packspuNewThread( crThreadID() );
+    ThreadInfo *curThread = thread;
+    GLint retVal;
+
+    if (CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        if (!con)
+        {
+            crError("connection expected!");
+            return 0;
+        }
+        thread = GET_THREAD_VAL_ID(con);
+    }
+    else
+    {
+        CRASSERT(!con);
+        if (!thread) {
+            thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                NULL
+#endif
+                );
+        }
     }
     CRASSERT(thread);
     CRASSERT(thread->packer);
+    CRASSERT(crPackGetContext() == (curThread ? curThread->packer : NULL));
 
     crPackSetContext(thread->packer);
@@ -184,19 +223,34 @@
     if (!(thread->netServer.conn->actual_network))
     {
-        return num_calls++;
-    }
-    else
-    {
-        while (writeback)
-            crNetRecv();
+        retVal = num_calls++;
+    }
+    else
+    {
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
         if (pack_spu.swap)
         {
             return_val = (GLint) SWAP32(return_val);
         }
-        return return_val;
-    }
-}
-
-
+        retVal = return_val;
+    }
+
+    if (CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        if (thread != curThread)
+        {
+            if (curThread)
+                crPackSetContext(curThread->packer);
+            else
+                crPackSetContext(NULL);
+        }
+    }
+
+    return retVal;
+}
+
+GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
+{
+    return packspu_VBoxWindowCreate( 0, dpyName, visBits );
+}
 
 GLboolean PACKSPU_APIENTRY
@@ -224,6 +278,5 @@
     packspuFlush( (void *) thread );
 
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     /* Since the Chromium packer/unpacker can't return both 'residences'
@@ -264,6 +317,5 @@
     packspuFlush( (void *) thread );
 
-    while (writeback)
-        crNetRecv();
+    CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
 
     /* Since the Chromium packer/unpacker can't return both 'residences'
@@ -299,6 +351,5 @@
     {
         packspuFlush( (void *) thread );
-        while (writeback)
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     }
 }
@@ -323,6 +374,5 @@
     {
         packspuFlush( (void *) thread );
-        while (writeback)
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     }
 }
@@ -347,6 +397,5 @@
     {
         packspuFlush( (void *) thread );
-        while (writeback)
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     }
 }
@@ -371,6 +420,5 @@
     {
         packspuFlush( (void *) thread );
-        while (writeback)
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     }
 }
@@ -410,11 +458,12 @@
 
 #ifdef CHROMIUM_THREADSAFE
-void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void)
-{
+GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
+{
+    GLint con = 0;
+    int i;
+    GET_THREAD(thread);
+    CRASSERT(!thread);
     crLockMutex(&_PackMutex);
     {
-        int i;
-        GET_THREAD(thread);
-        CRASSERT(!thread);
         CRASSERT((pack_spu.numThreads>0) && (pack_spu.numThreads<MAX_THREADS));
 
@@ -430,5 +479,8 @@
 
         thread->inUse = GL_TRUE;
-        thread->id = crThreadID();
+        if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+            thread->id = crThreadID();
+        else
+            thread->id = THREAD_OFFSET_MAGIC + i;
         thread->currentContext = NULL;
         thread->bInjectThread = GL_TRUE;
@@ -437,5 +489,9 @@
         thread->netServer.buffer_size = 64 * 1024;
 
-        crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer));
+        crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer)
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , pHgsmi
+#endif
+        );
         CRASSERT(thread->netServer.conn);
 
@@ -458,7 +514,15 @@
     }
     crUnlockMutex(&_PackMutex);
-}
-
-GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(void)
+
+    if (CRPACKSPU_IS_WDDM_CRHGSMI())
+    {
+        CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
+                && GET_THREAD_VAL_ID(thread->id) == thread);
+        con = thread->id;
+    }
+    return con;
+}
+
+GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con)
 {
     GLuint ret;
@@ -466,5 +530,19 @@
     crLockMutex(&_PackMutex);
     {
-        GET_THREAD(thread);
+        ThreadInfo *thread = NULL;
+        if (CRPACKSPU_IS_WDDM_CRHGSMI())
+        {
+            if (!con)
+            {
+                crError("connection expected!");
+                return 0;
+            }
+            thread = GET_THREAD_VAL_ID(con);
+        }
+        else
+        {
+            CRASSERT(!con);
+            thread = GET_THREAD_VAL();
+        }
         CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM);
         ret = thread->netServer.conn->u32ClientID;
@@ -514,57 +592,65 @@
     if (thread)
     {
-        crLockMutex(&_PackMutex);
-
-        for (i=0; i<MAX_THREADS; ++i)
-        {
-            if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
-                && thread->id==crThreadID() && thread->netServer.conn)
+        if (CRPACKSPU_IS_WDDM_CRHGSMI())
+        {
+            crPackSetContext(NULL);
+            crSetTSD(&_PackTSD, NULL);
+        }
+        else
+        {
+            crLockMutex(&_PackMutex);
+
+            for (i=0; i<MAX_THREADS; ++i)
             {
-                CRASSERT(pack_spu.numThreads>0);
-
-                packspuFlush((void *) thread);
-
-                if (pack_spu.thread[i].packer)
+                if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
+                    && thread->id==crThreadID() && thread->netServer.conn)
                 {
-                    CR_LOCK_PACKER_CONTEXT(thread->packer);
-                    crPackSetContext(NULL);
-                    CR_UNLOCK_PACKER_CONTEXT(thread->packer);
-                    crPackDeleteContext(pack_spu.thread[i].packer);
-                }
-                crNetFreeConnection(pack_spu.thread[i].netServer.conn);
-
-                pack_spu.numThreads--;
-                /*note can't shift the array here, because other threads have TLS references to array elements*/
-                crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));
-
-                crSetTSD(&_PackTSD, NULL);
-
-                if (i==pack_spu.idxThreadInUse)
-                {
-                    for (i=0; i<MAX_THREADS; ++i)
+                    CRASSERT(pack_spu.numThreads>0);
+
+                    packspuFlush((void *) thread);
+
+                    if (pack_spu.thread[i].packer)
                     {
-                        if (pack_spu.thread[i].inUse)
+                        CR_LOCK_PACKER_CONTEXT(thread->packer);
+                        crPackSetContext(NULL);
+                        CR_UNLOCK_PACKER_CONTEXT(thread->packer);
+                        crPackDeleteContext(pack_spu.thread[i].packer);
+                    }
+                    crNetFreeConnection(pack_spu.thread[i].netServer.conn);
+
+                    pack_spu.numThreads--;
+                    /*note can't shift the array here, because other threads have TLS references to array elements*/
+                    crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));
+
+                    crSetTSD(&_PackTSD, NULL);
+
+                    if (i==pack_spu.idxThreadInUse)
+                    {
+                        for (i=0; i<MAX_THREADS; ++i)
                         {
-                            pack_spu.idxThreadInUse=i;
-                            break;
+                            if (pack_spu.thread[i].inUse)
+                            {
+                                pack_spu.idxThreadInUse=i;
+                                break;
+                            }
                         }
                     }
+
+                    break;
                 }
-
-                break;
             }
-        }
-
-        for (i=0; i<CR_MAX_CONTEXTS; ++i)
-        {
-            ContextInfo *ctx = &pack_spu.context[i];
-            if (ctx->currentThread == thread)
+
+            for (i=0; i<CR_MAX_CONTEXTS; ++i)
             {
-                CRASSERT(ctx->fAutoFlush);
-                ctx->currentThread = NULL;
+                ContextInfo *ctx = &pack_spu.context[i];
+                if (ctx->currentThread == thread)
+                {
+                    CRASSERT(ctx->fAutoFlush);
+                    ctx->currentThread = NULL;
+                }
             }
-        }
-
-        crUnlockMutex(&_PackMutex);
+
+            crUnlockMutex(&_PackMutex);
+        }
     }
 
@@ -605,9 +691,9 @@
 
 #else  /*ifdef CHROMIUM_THREADSAFE*/
-void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void)
-{
-}
-
-GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(void)
+GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
+{
+}
+
+GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con)
 {
     return 0;
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c	(revision 42499)
@@ -230,7 +230,15 @@
 }
 
-void packspuConnectToServer( CRNetServer *server )
+void packspuConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+        )
 {
     crNetInit( packspuReceiveData, NULL );
-    crNetServerConnect( server );
-}
+    crNetServerConnect( server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , pHgsmi
+#endif
+            );
+}
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c	(revision 42499)
@@ -322,6 +322,5 @@
 
         packspuFlush((void *) thread);
-        while (pack_spu.ReadPixels) 
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     }
 }
@@ -588,6 +587,5 @@
     {
         packspuFlush( (void *) thread );
-        while (writeback) 
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     }
 }
@@ -622,6 +620,5 @@
     {
         packspuFlush( (void *) thread );
-        while (writeback)
-            crNetRecv();
+        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
     }
 }
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_special
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_special	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_special	(revision 42499)
@@ -107,4 +107,10 @@
 VBoxAttachThread
 VBoxDetachThread
+VBoxCreateContext
+VBoxWindowCreate
+VBoxWindowDestroy
+VBoxConCreate
+VBoxConDestroy
+VBoxConFlush
 ChromiumParameteriCR
 CompressedTexImage1DARB
Index: /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c	(revision 42499)
@@ -85,8 +85,5 @@
             /* Make sure writeback from previous frame has been received.
              */
-            while (thread->writeback)
-            {
-                crNetRecv();
-            }
+            CRPACKSPU_WRITEBACK_WAIT(thread, thread->writeback);
             break;
         }
Index: /trunk/src/VBox/Additions/common/crOpenGL/stub.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/stub.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/stub.c	(revision 42499)
@@ -11,5 +11,9 @@
 #include <iprt/thread.h>
 
-static void crForcedFlush()
+static void crForcedFlush(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        GLint con
+#endif
+        )
 {
 #if 0
@@ -20,5 +24,14 @@
     stub.spu->dispatch_table.DrawBuffer(buffer);
 #else
-    stub.spu->dispatch_table.Flush();
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    if (con)
+    {
+        stub.spu->dispatch_table.VBoxConFlush(con);
+    }
+    else
+#endif
+    {
+        stub.spu->dispatch_table.Flush();
+    }
 #endif
 }
@@ -63,5 +76,9 @@
      * That didn't seem right so it was changed to CHROMIUM. (Brian)
      */
-    context = stubNewContext(dpyName, visBits, CHROMIUM, 0);
+    context = stubNewContext(dpyName, visBits, CHROMIUM, 0
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        , NULL
+#endif
+            );
     return context ? (int) context->id : -1;
 }
@@ -143,5 +160,11 @@
         crHashtableLock(stub.windowTable);
 
-        stub.spu->dispatch_table.WindowDestroy( winInfo->spuWindow );
+        stub.spu->dispatch_table.VBoxWindowDestroy(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                winInfo->spuConnection,
+#else
+                0
+#endif
+                winInfo->spuWindow );
 
 #ifdef WINDOWS
@@ -162,6 +185,13 @@
 # endif
 #endif
-        crForcedFlush();
-
+        crForcedFlush(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                winInfo->spuConnection
+#endif
+                );
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        winInfo->spuConnection = 0;
+#endif
         crHashtableWalk(stub.contextTable, stubWindowCleanupForContextsCB, winInfo);
 
Index: /trunk/src/VBox/Additions/common/crOpenGL/stub.h
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/stub.h	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/stub.h	(revision 42499)
@@ -115,4 +115,9 @@
     WindowInfo *currentDrawable;
 
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    GLint spuConnection;
+    struct VBOXUHGSMI *pHgsmi;
+#endif
+
 #ifdef CHROMIUM_THREADSAFE
     VBOXTLSREFDATA
@@ -165,4 +170,7 @@
     ContextInfo *pOwner;     /* ctx which created this window */
     GLboolean mapped;
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    GLint spuConnection;
+#endif
 #ifdef WINDOWS
     HDC      drawable;
@@ -329,5 +337,9 @@
 
 
-extern ContextInfo *stubNewContext( const char *dpyName, GLint visBits, ContextType type, unsigned long shareCtx );
+extern ContextInfo *stubNewContext( const char *dpyName, GLint visBits, ContextType type, unsigned long shareCtx
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        , struct VBOXUHGSMI *pHgsmi
+#endif
+        );
 extern void stubDestroyContext( unsigned long contextId );
 extern GLboolean stubMakeCurrent( WindowInfo *window, ContextInfo *context );
Index: /trunk/src/VBox/Additions/common/crOpenGL/wgl.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/wgl.c	(revision 42498)
+++ /trunk/src/VBox/Additions/common/crOpenGL/wgl.c	(revision 42499)
@@ -295,5 +295,5 @@
 
 
-HGLRC WINAPI wglCreateContext_prox( HDC hdc )
+HGLRC WINAPI VBoxCreateContext( HDC hdc, struct VBOXUHGSMI *pHgsmi )
 {
     char dpyName[MAX_DPY_NAME];
@@ -312,9 +312,20 @@
 #endif
 
-    context = stubNewContext(dpyName, desiredVisual, UNDECIDED, 0);
+    context = stubNewContext(dpyName, desiredVisual, UNDECIDED, 0
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        , pHgsmi
+#else
+        , NULL
+#endif
+            );
     if (!context)
         return 0;
 
     return (HGLRC) context->id;
+}
+
+HGLRC WINAPI wglCreateContext_prox( HDC hdc )
+{
+    return VBoxCreateContext(hdc, NULL);
 }
 
Index: /trunk/src/VBox/GuestHost/OpenGL/Makefile.kmk
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/Makefile.kmk	(revision 42498)
+++ /trunk/src/VBox/GuestHost/OpenGL/Makefile.kmk	(revision 42499)
@@ -93,4 +93,5 @@
 endif
 ifdef VBOX_WITH_WDDM
+VBoxOGLcrutil_DEFS.win   += VBOX_WITH_WDDM
 VBoxOGLcrutil_DEFS.win    += CR_DEBUG_BACKDOOR_ENABLE
 VBoxOGLcrutil_INCS.win    += $(PATH_ROOT)/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm
@@ -252,4 +253,10 @@
 	$(VBOX_PATH_CROGL_GENFILES)/cr_opcodes.h \
 	$(VBOX_PATH_CROGL_GENFILES)/state/cr_currentpointers.h
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLcrpacker_DEFS.win    += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLcrpacker_DEFS.win   += VBOX_WITH_WDDM
+endif
 
 if defined(VBOX_WITH_WDDM) && defined(VBOX_WITH_ADDITIONS)
@@ -330,5 +337,10 @@
 	$(VBOX_PATH_CROGL_GENFILES)/glloader.c \
 	$(VBOX_PATH_CROGL_GENFILES)/spu_dispatch_table.h
-
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLspuload_DEFS.win    += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLspuload_DEFS.win   += VBOX_WITH_WDDM
+endif
 
 if defined(VBOX_WITH_WDDM) && defined(VBOX_WITH_ADDITIONS)
@@ -459,5 +471,10 @@
 VBoxOGLcrstate_CFLAGS +=
 endif
-
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLcrstate_DEFS.win    += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLcrstate_DEFS.win   += VBOX_WITH_WDDM
+endif
 
 if defined(VBOX_WITH_WDDM) && defined(VBOX_WITH_ADDITIONS)
@@ -582,4 +599,11 @@
 VBoxOGLerrorspu_LIBS = \
 	$(VBOX_LIB_OGL_CRUTIL)
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLerrorspu_DEFS.win    += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLerrorspu_DEFS.win   += VBOX_WITH_WDDM
+endif
+
 
 if defined(VBOX_WITH_WDDM) && defined(VBOX_WITH_ADDITIONS)
Index: /trunk/src/VBox/GuestHost/OpenGL/glapi_parser/APIspec.txt
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/glapi_parser/APIspec.txt	(revision 42498)
+++ /trunk/src/VBox/GuestHost/OpenGL/glapi_parser/APIspec.txt	(revision 42499)
@@ -8501,5 +8501,6 @@
 
 name        VBoxPackSetInjectThread
-return      void
+return      GLint
+param       pHgsmi      struct VBOXUHGSMI *
 category    VBox
 chromium    nopack
@@ -8507,4 +8508,5 @@
 name        VBoxPackGetInjectID
 return      GLuint
+param       con         GLint
 category    VBox
 chromium    nopack
@@ -8523,4 +8525,46 @@
 name        VBoxDetachThread
 return      void
+category    VBox
+chromium    nopack
+
+name        VBoxCreateContext
+return      GLint
+param       con         GLint
+param       dpyName     const char *
+param       visual      GLint
+param       shareCtx    GLint
+category    VBox
+chromium    nopack
+
+name        VBoxWindowCreate
+return      GLint
+param       con         GLint
+param       dpyName     const char *
+param       visBits     GLint
+category    VBox
+chromium    nopack
+
+name        VBoxWindowDestroy
+return      void
+param       con         GLint
+param       window      GLint
+category    VBox
+chromium    nopack
+
+name        VBoxConCreate
+return      GLint
+param       pHgsmi      struct VBOXUHGSMI *
+category    VBox
+chromium    nopack
+
+name        VBoxConDestroy
+return      void
+param       con         GLint
+category    VBox
+chromium    nopack
+
+name        VBoxConFlush
+return      void
+param       con         GLint
 category    VBox
 chromium    nopack
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_net.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_net.h	(revision 42498)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_net.h	(revision 42499)
@@ -35,4 +35,5 @@
 
 #include <iprt/types.h>
+#include <iprt/thread.h>
     
 #ifdef __cplusplus
@@ -236,7 +237,6 @@
     uint32_t u32InjectClientID;
 # ifdef VBOX_WITH_CRHGSMI
-#  ifndef VBOX_CRHGSMI_WITH_D3DDEV
     CRVBOXHGSMI_CLIENT HgsmiClient;
-#  endif
+    struct VBOXUHGSMI *pExternalHgsmi;
 # endif
 #else
@@ -283,14 +283,33 @@
 extern DECLEXPORT(int) crNetNumMessages(CRConnection *conn);
 extern DECLEXPORT(void) crNetReadline( CRConnection *conn, void *buf );
-extern DECLEXPORT(int) crNetRecv( void );
-#define CR_WRITEBACK_WAIT() do { \
-        while (writeback) { \
-            crNetRecv();    \
-        }                   \
+extern DECLEXPORT(int) crNetRecv(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                CRConnection *conn
+#endif
+        );
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+#define CR_WRITEBACK_WAIT(_conn, _writeback) do { \
+        while (_writeback) {     \
+            RTThreadYield();     \
+            crNetRecv(_conn);    \
+        }                        \
     } while (0)
+#else
+#define CR_WRITEBACK_WAIT(_conn, _writeback) do { \
+        while (_writeback) { \
+            RTThreadYield(); \
+            crNetRecv();     \
+        }                    \
+    } while (0)
+
+#endif
 extern DECLEXPORT(void) crNetDefaultRecv( CRConnection *conn, CRMessage *msg, unsigned int len );
 extern DECLEXPORT(void) crNetDispatchMessage( CRNetReceiveFuncList *rfl, CRConnection *conn, CRMessage *msg, unsigned int len );
 
-extern DECLEXPORT(CRConnection *) crNetConnectToServer( const char *server, unsigned short default_port, int mtu, int broker );
+extern DECLEXPORT(CRConnection *) crNetConnectToServer( const char *server, unsigned short default_port, int mtu, int broker
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+);
 extern DECLEXPORT(CRConnection *) crNetAcceptClient( const char *protocol, const char *hostname, unsigned short port, unsigned int mtu, int broker );
 
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_netserver.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_netserver.h	(revision 42498)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_netserver.h	(revision 42499)
@@ -22,6 +22,14 @@
 } CRNetServer;
 
-DECLEXPORT(void) crNetServerConnect( CRNetServer *ns );
-DECLEXPORT(void) crNetNewClient( CRConnection *conn, CRNetServer *ns );
+DECLEXPORT(void) crNetServerConnect( CRNetServer *ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+                );
+DECLEXPORT(void) crNetNewClient( CRConnection *conn, CRNetServer *ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+);
 
 #ifdef __cplusplus
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c	(revision 42498)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c	(revision 42499)
@@ -664,2 +664,29 @@
 {
 }
+
+GLint crStateVBoxCreateContext( GLint con, const char * dpyName, GLint visual, GLint shareCtx )
+{
+    return 0;
+}
+
+GLint crStateVBoxWindowCreate( GLint con, const char *dpyName, GLint visBits  )
+{
+    return 0;
+}
+
+void crStateVBoxWindowDestroy( GLint con, GLint window )
+{
+}
+
+GLint crStateVBoxConCreate(struct VBOXUHGSMI *pHgsmi)
+{
+    return 0;
+}
+
+void crStateVBoxConDestroy(GLint con)
+{
+}
+
+void crStateVBoxConFlush(GLint con)
+{
+}
Index: /trunk/src/VBox/GuestHost/OpenGL/util/net.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/net.c	(revision 42498)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/net.c	(revision 42499)
@@ -73,5 +73,9 @@
  */
 static void
-InitConnection(CRConnection *conn, const char *protocol, unsigned int mtu)
+InitConnection(CRConnection *conn, const char *protocol, unsigned int mtu
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+        )
 {
     if (!crStrcmp(protocol, "devnull"))
@@ -111,5 +115,9 @@
         cr_net.use_hgcm++;
         crVBoxHGCMInit(cr_net.recv_list, cr_net.close_list, mtu);
-        crVBoxHGCMConnection(conn);
+        crVBoxHGCMConnection(conn
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                    , pHgsmi
+#endif
+                );
     }
 #endif
@@ -184,7 +192,9 @@
  *                the mothership
  */
-CRConnection *
-crNetConnectToServer( const char *server, unsigned short default_port,
-                      int mtu, int broker )
+CRConnection * crNetConnectToServer( const char *server, unsigned short default_port, int mtu, int broker
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+)
 {
     char hostname[4096], protocol[4096];
@@ -270,5 +280,9 @@
 
     /* now, just dispatch to the appropriate protocol's initialization functions. */
-    InitConnection(conn, protocol, mtu);
+    InitConnection(conn, protocol, mtu
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , pHgsmi
+#endif
+            );
 
     if (!crNetConnect( conn ))
@@ -287,10 +301,13 @@
 }
 
-
 /**
  * Send a message to the receiver that another connection is needed.
  * We send a CR_MESSAGE_NEWCLIENT packet, then call crNetServerConnect.
  */
-void crNetNewClient( CRConnection *conn, CRNetServer *ns )
+void crNetNewClient( CRConnection *conn, CRNetServer *ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+)
 {
     /*
@@ -308,5 +325,9 @@
     */
 
-    crNetServerConnect( ns );
+    crNetServerConnect( ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , pHgsmi
+#endif
+);
 }
 
@@ -368,9 +389,17 @@
 
     /* call the protocol-specific init routines */  // ktd (add)
-    InitConnection(conn, protocol_only, mtu);       // ktd (add)
+    InitConnection(conn, protocol_only, mtu
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , NULL
+#endif
+            );       // ktd (add)
     }
     else {
     /* call the protocol-specific init routines */
-      InitConnection(conn, protocol, mtu);
+      InitConnection(conn, protocol, mtu
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , NULL
+#endif
+              );
     }
 
@@ -834,10 +863,17 @@
  * When done, the CrNetServer's conn field will be initialized.
  */
-void crNetServerConnect( CRNetServer *ns )
+void crNetServerConnect( CRNetServer *ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , struct VBOXUHGSMI *pHgsmi
+#endif
+)
 {
     ns->conn = crNetConnectToServer( ns->name, DEFAULT_SERVER_PORT,
-                                     ns->buffer_size, 0 );
-}
-
+                                     ns->buffer_size, 0
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                , pHgsmi
+#endif
+            );
+}
 
 /**
@@ -1186,5 +1222,9 @@
         if (len)
             return len;
-        crNetRecv();
+        crNetRecv(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                conn
+#endif
+                );
     }
 
@@ -1234,5 +1274,9 @@
  * is assumed to be placed on queues for processing by the handler.
  */
-int crNetRecv( void )
+int crNetRecv(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        CRConnection *conn
+#endif
+        )
 {
     int found_work = 0;
@@ -1242,5 +1286,9 @@
 #ifdef VBOX_WITH_HGCM
     if ( cr_net.use_hgcm )
-        found_work += crVBoxHGCMRecv();
+        found_work += crVBoxHGCMRecv(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+                    conn
+#endif
+                );
 #endif
 #ifdef SDP_SUPPORT
Index: /trunk/src/VBox/GuestHost/OpenGL/util/net_internals.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/net_internals.h	(revision 42498)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/net_internals.h	(revision 42499)
@@ -92,6 +92,14 @@
 #ifdef VBOX_WITH_HGCM
 extern void crVBoxHGCMInit( CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu );
-extern void crVBoxHGCMConnection( CRConnection *conn );
-extern int crVBoxHGCMRecv( void );
+extern void crVBoxHGCMConnection( CRConnection *conn
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        , struct VBOXUHGSMI *pHgsmi
+#endif
+        );
+extern int crVBoxHGCMRecv(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        CRConnection *conn
+#endif
+        );
 extern CRConnection** crVBoxHGCMDump( int *num );
 extern void crVBoxHGCMTearDown(void);
Index: /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c	(revision 42498)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c	(revision 42499)
@@ -345,5 +345,5 @@
         return &conn->HgsmiClient;
     {
-        PVBOXUHGSMI pHgsmi = VBoxCrHgsmiCreate();
+        PVBOXUHGSMI pHgsmi = conn->pExternalHgsmi ? conn->pExternalHgsmi : VBoxCrHgsmiCreate();
         if (pHgsmi)
         {
@@ -356,5 +356,6 @@
             else
                 crWarning("_crVBoxHGSMIClientGet: _crVBoxHGSMIClientInit failed rc %d", rc);
-            VBoxCrHgsmiDestroy(pHgsmi);
+            if (!conn->pExternalHgsmi)
+                VBoxCrHgsmiDestroy(pHgsmi);
         }
         else
@@ -2333,5 +2334,6 @@
         _crVBoxHGSMIClientTerm(&conn->HgsmiClient, &pHgsmi);
         CRASSERT(pHgsmi);
-        VBoxCrHgsmiDestroy(pHgsmi);
+        if (!conn->pExternalHgsmi)
+            VBoxCrHgsmiDestroy(pHgsmi);
     }
 #else
@@ -2498,5 +2500,9 @@
 }
 
-void crVBoxHGCMConnection(CRConnection *conn)
+void crVBoxHGCMConnection(CRConnection *conn
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        , struct VBOXUHGSMI *pHgsmi
+#endif
+        )
 {
     int i, found = 0;
@@ -2520,4 +2526,5 @@
         conn->InstantReclaim = crVBoxHGSMIInstantReclaim;
         conn->HandleNewMessage = crVBoxHGSMIHandleNewMessage;
+        conn->pExternalHgsmi = pHgsmi;
     }
     else
@@ -2577,5 +2584,43 @@
 }
 
-int crVBoxHGCMRecv(void)
+#if defined(IN_GUEST)
+void _crVBoxHGCMPerformPollHost(CRConnection *conn)
+{
+    if (conn->type == CR_NO_CONNECTION )
+        return;
+
+    if (!conn->pBuffer)
+    {
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        PCRVBOXHGSMI_CLIENT pClient;
+        if (g_crvboxhgcm.bHgsmiOn && !!(pClient = _crVBoxHGSMIClientGet(conn)))
+        {
+            _crVBoxHGSMIPollHost(conn, pClient);
+        }
+        else
+#endif
+        {
+            crVBoxHGCMPollHost(conn);
+        }
+    }
+}
+#endif
+
+void _crVBoxHGCMPerformReceiveMessage(CRConnection *conn)
+{
+    if ( conn->type == CR_NO_CONNECTION )
+        return;
+
+    if (conn->cbBuffer>0)
+    {
+        _crVBoxHGCMReceiveMessage(conn);
+    }
+}
+
+int crVBoxHGCMRecv(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+        CRConnection *conn
+#endif
+        )
 {
     int32_t i;
@@ -2588,4 +2633,14 @@
 
 #ifdef IN_GUEST
+# if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+    CRASSERT(!g_crvboxhgcm.bHgsmiOn == !conn);
+    if (conn && g_crvboxhgcm.bHgsmiOn)
+    {
+        _crVBoxHGCMPerformPollHost(conn);
+        _crVBoxHGCMPerformReceiveMessage(conn);
+        VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
+        return 0;
+    }
+# endif
     /* we're on guest side, poll host if it got something for us */
     for (i=0; i<g_crvboxhgcm.num_conns; i++)
@@ -2593,21 +2648,8 @@
         CRConnection *conn = g_crvboxhgcm.conns[i];
 
-        if ( !conn || conn->type == CR_NO_CONNECTION )
+        if ( !conn  )
             continue;
 
-        if (!conn->pBuffer)
-        {
-#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
-            PCRVBOXHGSMI_CLIENT pClient;
-            if (g_crvboxhgcm.bHgsmiOn && !!(pClient = _crVBoxHGSMIClientGet(conn)))
-            {
-                _crVBoxHGSMIPollHost(conn, pClient);
-            }
-            else
-#endif
-            {
-                crVBoxHGCMPollHost(conn);
-            }
-        }
+        _crVBoxHGCMPerformPollHost(conn);
     }
 #endif
@@ -2617,11 +2659,8 @@
         CRConnection *conn = g_crvboxhgcm.conns[i];
 
-        if ( !conn || conn->type == CR_NO_CONNECTION )
+        if ( !conn )
             continue;
 
-        if (conn->cbBuffer>0)
-        {
-            _crVBoxHGCMReceiveMessage(conn);
-        }
+        _crVBoxHGCMPerformReceiveMessage(conn);
     }
 
