ddrawex: Create a surface wrapper.
diff --git a/dlls/ddrawex/ddraw.c b/dlls/ddrawex/ddraw.c
index f3c5c41..9645a3d 100644
--- a/dlls/ddrawex/ddraw.c
+++ b/dlls/ddrawex/ddraw.c
@@ -386,6 +386,7 @@
                                IUnknown *UnkOuter)
 {
     IDirectDrawImpl *This = impl_from_dd4(iface);
+    HRESULT hr;
     TRACE("(%p)(%p, %p, %p)\n", This, DDSD, Surf, UnkOuter);
 
     if(UnkOuter != NULL)
@@ -394,10 +395,12 @@
         FIXME("Implement aggregation for ddrawex surfaces\n");
     }
 
-    return IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter);
+    hr = IDirectDraw4_CreateSurface(This->parent, DDSD, Surf, UnkOuter);
+    *Surf = dds_get_outer(*Surf);
+    return hr;
 }
 
-static void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
+void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
 {
     memset(out, 0, sizeof(*out));
     out->dwSize = sizeof(*out);
@@ -410,7 +413,8 @@
     if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
     if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwMipMapCount = in->dwZBufferBitDepth; /* same union */
     if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
-    if(in->dwFlags & DDSD_LPSURFACE) out->lpSurface = in->lpSurface;
+    /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
+    out->lpSurface = in->lpSurface;
     if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->ddckCKDestOverlay;
     if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
     if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
@@ -423,7 +427,7 @@
      */
 }
 
-static void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
+void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out)
 {
     memset(out, 0, sizeof(*out));
     out->dwSize = sizeof(*out);
@@ -436,7 +440,8 @@
     if(in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
     if(in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->dwZBufferBitDepth = in->dwMipMapCount; /* same union */
     if(in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
-    if(in->dwFlags & DDSD_LPSURFACE) out->lpSurface = in->lpSurface;
+    /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
+    out->lpSurface = in->lpSurface;
     if(in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->ddckCKDestOverlay;
     if(in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt;
     if(in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay;
@@ -474,6 +479,7 @@
         return hr;
     }
 
+    TRACE("Got surface %p\n", surf4);
     IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **) Surf);
     IDirectDrawSurface4_Release(surf4);
     return hr;
@@ -507,9 +513,9 @@
                                   IDirectDrawSurface4 **dst)
 {
     IDirectDrawImpl *This = impl_from_dd4(iface);
-    TRACE("(%p)->(%p,%p)\n", This, src, dst);
+    FIXME("(%p)->(%p,%p). Create a wrapper surface\n", This, src, dst);
 
-    return IDirectDraw4_DuplicateSurface(This->parent, src, dst);
+    return IDirectDraw4_DuplicateSurface(This->parent, dds_get_inner(src), dst);
 }
 
 static HRESULT WINAPI
@@ -628,6 +634,23 @@
     return IDirectDraw3_EnumDisplayModes(dd3_from_impl(This), Flags, DDSD, Context, cb);
 }
 
+struct enumsurfaces4_ctx
+{
+    LPDDENUMSURFACESCALLBACK2 orig_cb;
+    void *orig_ctx;
+};
+
+static HRESULT WINAPI
+enum_surfaces_wrapper(IDirectDrawSurface4 *surf4, DDSURFACEDESC2 *ddsd2, void *vctx)
+{
+    struct enumsurfaces4_ctx *ctx = (struct enumsurfaces4_ctx *) vctx;
+    IDirectDrawSurface4 *outer = dds_get_outer(surf4);
+    IDirectDrawSurface4_AddRef(outer);
+    IDirectDrawSurface4_Release(surf4);
+    TRACE("Returning wrapper surface %p for enumerated inner surface %p\n", outer, surf4);
+    return ctx->orig_cb(outer, ddsd2, ctx->orig_ctx);
+}
+
 static HRESULT WINAPI
 IDirectDraw4Impl_EnumSurfaces(IDirectDraw4 *iface,
                               DWORD Flags,
@@ -636,9 +659,12 @@
                               LPDDENUMSURFACESCALLBACK2 Callback)
 {
     IDirectDrawImpl *This = impl_from_dd4(iface);
+    struct enumsurfaces4_ctx *ctx;
     TRACE("(%p)->(0x%08x,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback);
 
-    return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, Context, Callback);
+    ctx->orig_cb = Callback;
+    ctx->orig_ctx = Context;
+    return IDirectDraw4Impl_EnumSurfaces(This->parent, Flags, DDSD, &ctx, enum_surfaces_wrapper);
 }
 
 struct enumsurfaces_ctx
@@ -864,8 +890,22 @@
                                IDirectDrawSurface4 **GDISurface)
 {
     IDirectDrawImpl *This = impl_from_dd4(iface);
+    IDirectDrawSurface4 *inner = NULL;
+    HRESULT hr;
     TRACE("(%p)->(%p)\n", This, GDISurface);
-    return IDirectDraw4_GetGDISurface(This->parent, GDISurface);
+
+    hr = IDirectDraw4_GetGDISurface(This->parent, &inner);
+    if(SUCCEEDED(hr))
+    {
+        *GDISurface = dds_get_outer(inner);
+        IDirectDrawSurface4_AddRef(*GDISurface);
+        IDirectDrawSurface4_Release(inner);
+    }
+    else
+    {
+        *GDISurface = NULL;
+    }
+    return hr;
 }
 
 static HRESULT WINAPI
@@ -1258,8 +1298,22 @@
                                   IDirectDrawSurface4 **Surface)
 {
     IDirectDrawImpl *This = impl_from_dd4(iface);
+    IDirectDrawSurface4 *inner;
+    HRESULT hr;
     TRACE("(%p)->(%p, %p)\n", This, hdc, Surface);
-    return IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, Surface);
+    hr = IDirectDraw4_GetSurfaceFromDC(This->parent,hdc, &inner);
+    if(SUCCEEDED(hr))
+    {
+        *Surface = dds_get_outer(inner);
+        IDirectDrawSurface4_AddRef(*Surface);
+        IDirectDrawSurface4_Release(inner);
+    }
+    else
+    {
+        *Surface = NULL;
+    }
+
+    return hr;
 }
 
 static HRESULT WINAPI
@@ -1482,3 +1536,9 @@
     *ppDirectDraw = NULL;
     return hr;
 }
+
+IDirectDraw4 *dd_get_inner(IDirectDraw4 *outer)
+{
+    IDirectDrawImpl *This = impl_from_dd4(outer);
+    return This->parent;
+}