Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c	(revision 44305)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c	(revision 44306)
@@ -1604,5 +1604,5 @@
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface;
 
-    if (device->focus_window) wined3d_unregister_window(device->focus_window);
+    if (device->focus_window) wined3d_unregister_window(device->focus_window, device);
     device->focus_window = NULL;
 #else
@@ -7667,5 +7667,5 @@
     {
         TRACE("unregister window %p.\n", window);
-        wined3d_unregister_window(window);
+        wined3d_unregister_window(window, NULL);
 
         if (device->focus_window == window) device->focus_window = NULL;
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/glsl_shader.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/glsl_shader.c	(revision 44305)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/glsl_shader.c	(revision 44306)
@@ -3971,4 +3971,7 @@
     unsigned int i;
     char reg_mask[6];
+
+    if (!ps)
+        return;
 
     for (i = 0, map = ps->baseShader.reg_maps.texcoord; map && i < min(8, MAX_REG_TEXCRD); map >>= 1, ++i)
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c	(revision 44305)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c	(revision 44306)
@@ -520,14 +520,7 @@
 
 #ifdef VBOX_WITH_WDDM
-    /* We're directly using wglMakeCurrent calls skipping GDI layer, which causes GDI SwapBuffers to fail trying to
-     * call glFinish, which doesn't have any context set. So we use wglSwapLayerBuffers directly as well.
-     */
-    pwglSwapLayerBuffers(context->currentSwapchain->hDC, WGL_SWAP_MAIN_PLANE);
+    SwapBuffers(context->currentSwapchain->hDC);
 #else
-# ifdef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
-    pwglSwapLayerBuffers(context->hdc, WGL_SWAP_MAIN_PLANE);
-# else
     SwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
-# endif
 #endif
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h	(revision 44305)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h	(revision 44306)
@@ -1381,7 +1381,33 @@
 BOOL (WINAPI *pwglSwapLayerBuffers)(HDC, UINT) DECLSPEC_HIDDEN;
 BOOL (WINAPI *pwglShareLists)(HGLRC, HGLRC) DECLSPEC_HIDDEN;
+BOOL (WINAPI *pwglChoosePixelFormat)(HDC, const PIXELFORMATDESCRIPTOR *) DECLSPEC_HIDDEN;
+int (WINAPI *pwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR) DECLSPEC_HIDDEN;
+int (WINAPI *pwglGetPixelFormat)(HDC) DECLSPEC_HIDDEN;
+BOOL (WINAPI *pwglSetPixelFormat)(HDC, int, const PIXELFORMATDESCRIPTOR *) DECLSPEC_HIDDEN;
 
 HGLRC (WINAPI *pVBoxCreateContext)(HDC, struct VBOXUHGSMI*) DECLSPEC_HIDDEN;
 void (WINAPI *pVBoxFlushToHost)(HGLRC) DECLSPEC_HIDDEN;
+
+#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# define VBOX_WINE_WITH_DIRECT_VBOXOGL
+#endif
+
+#ifdef VBOX_WINE_WITH_DIRECT_VBOXOGL
+/* make sure we used stuff from VBoxOGL
+ * we do it this way to avoid extra modifications to Wine code */
+
+/* We're directly using wglMakeCurrent calls skipping GDI layer, which causes GDI SwapBuffers to fail trying to
+ * call glFinish, which doesn't have any context set. So we use wglSwapLayerBuffers directly as well.
+ */
+# define SwapBuffers(_hdc) pwglSwapLayerBuffers((_hdc), WGL_SWAP_MAIN_PLANE)
+
+/* we avoid using GDI32!*PixelFormat API and use VBoxOGL stuff directly
+ * because SetPixelFormat may eventually lead to opengl32 setting its own window proc via SetWindowLongPtr
+ * thus wined3d_[un]register_window stuff will become screwed up leading to infinite recursion or other misbehave */
+# define ChoosePixelFormat pwglChoosePixelFormat
+# define DescribePixelFormat pwglDescribePixelFormat
+# define GetPixelFormat pwglGetPixelFormat
+# define SetPixelFormat pwglSetPixelFormat
+#endif
 
 #define GL_FUNCS_GEN \
@@ -1729,5 +1755,9 @@
     USE_WGL_FUNC(wglMakeCurrent) \
     USE_WGL_FUNC(wglShareLists) \
-    USE_WGL_FUNC(wglSwapLayerBuffers)
+    USE_WGL_FUNC(wglSwapLayerBuffers) \
+    USE_WGL_FUNC(wglChoosePixelFormat) \
+    USE_WGL_FUNC(wglDescribePixelFormat) \
+    USE_WGL_FUNC(wglGetPixelFormat) \
+    USE_WGL_FUNC(wglSetPixelFormat)
 
 #define VBOX_FUNCS_GEN \
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c	(revision 44305)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c	(revision 44306)
@@ -465,4 +465,13 @@
     wined3d_mutex_lock();
 
+    entry = wined3d_find_wndproc(window);
+    if (entry)
+    {
+        ERR("window is registered already!");
+        entry->device = device;
+        wined3d_mutex_unlock();
+        return TRUE;
+    }
+
     if (wndproc_table.size == wndproc_table.count)
     {
@@ -488,4 +497,5 @@
     entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
     entry->device = device;
+    Assert(entry->proc != wined3d_wndproc);
 
     wined3d_mutex_unlock();
@@ -494,5 +504,5 @@
 }
 
-void wined3d_unregister_window(HWND window)
+void wined3d_unregister_window(HWND window, struct IWineD3DDeviceImpl *device)
 {
     unsigned int i;
@@ -504,9 +514,17 @@
         {
             struct wined3d_wndproc *entry = &wndproc_table.entries[i];
-            struct wined3d_wndproc *last = &wndproc_table.entries[--wndproc_table.count];
-
-            if (GetWindowLongPtrW(window, GWLP_WNDPROC) == (LONG_PTR)wined3d_wndproc)
-                SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
-            if (entry != last) *entry = *last;
+
+            if (!device || device == entry->device)
+            {
+                struct wined3d_wndproc *last = &wndproc_table.entries[--wndproc_table.count];
+
+                if (GetWindowLongPtrW(window, GWLP_WNDPROC) == (LONG_PTR)wined3d_wndproc)
+                    SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
+                if (entry != last) *entry = *last;
+            }
+            else
+            {
+                ERR("request to unregister a window of a not-owning device");
+            }
             wined3d_mutex_unlock();
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h	(revision 44305)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h	(revision 44306)
@@ -1665,5 +1665,5 @@
 #ifndef VBOX_WITH_WDDM
 BOOL wined3d_register_window(HWND window, struct IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
-void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
+void wined3d_unregister_window(HWND window, struct IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
 #endif
 
