[PATCH] ddraw: Return a nullpointer as lpSurface in Lock() if the rect is invalid.

Günther Brammer GBrammer at gmx.de
Wed Dec 26 15:35:16 CST 2007


Baldur's Gate needs this, see bug 8489. Also adds a test.
---
 dlls/ddraw/surface.c        |   32 ++++++++++++++++++--------------
 dlls/ddraw/tests/dsurface.c |    7 +++++++
 2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index c8b3d5d..7e05793 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -577,20 +577,6 @@ IDirectDrawSurfaceImpl_Lock(IDirectDrawSurface7 *iface,
 
     /* This->surface_desc.dwWidth and dwHeight are changeable, thus lock */
     EnterCriticalSection(&ddraw_cs);
-    if (Rect)
-    {
-        if ((Rect->left < 0)
-                || (Rect->top < 0)
-                || (Rect->left > Rect->right)
-                || (Rect->top > Rect->bottom)
-                || (Rect->right > This->surface_desc.dwWidth)
-                || (Rect->bottom > This->surface_desc.dwHeight))
-        {
-            WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n");
-            LeaveCriticalSection(&ddraw_cs);
-            return DDERR_INVALIDPARAMS;
-        }
-    }
 
     /* Should I check for the handle to be NULL?
      *
@@ -605,6 +591,24 @@ IDirectDrawSurfaceImpl_Lock(IDirectDrawSurface7 *iface,
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_INVALIDPARAMS;
     }
+	
+    /* Windows zeroes this if the rect is invalid */
+    DDSD->lpSurface = 0;
+		
+    if (Rect)
+    {
+        if ((Rect->left < 0)
+                || (Rect->top < 0)
+                || (Rect->left > Rect->right)
+                || (Rect->top > Rect->bottom)
+                || (Rect->right > This->surface_desc.dwWidth)
+                || (Rect->bottom > This->surface_desc.dwHeight))
+        {
+            WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n");
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_INVALIDPARAMS;
+        }
+    }
 
     hr = IWineD3DSurface_LockRect(This->WineD3DSurface,
                                   &LockedRect,
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index 0f522db..cfacbfc 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -1648,14 +1648,21 @@ static void test_lockrect_invalid(void)
             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
         }
 
+        memset(&surface_desc, 1, sizeof(surface_desc));
+        surface_desc.dwSize = sizeof(surface_desc);
+        surface_desc.lpSurface = 0;
         for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
         {
             RECT *rect = &invalid[i];
 
+            memset(&locked_desc, 1, sizeof(locked_desc));
+            locked_desc.dwSize = sizeof(locked_desc);
+
             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
             ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
                     ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
                     rect->right, rect->bottom, DDERR_INVALIDPARAMS);
+            ok(!memcmp(&locked_desc, &surface_desc, sizeof(locked_desc)), "IDirectDrawSurface_Lock did not set lpSurface in the surface desc\n");
         }
 
         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
-- 
1.5.3.7
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Dies ist ein digital signierter Nachrichtenteil
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20071226/36cb20c3/attachment-0001.pgp 


More information about the wine-patches mailing list