[2/3] ddraw: Don't interpret end padding as dwCaps2 for x64. (try 2)

Dylan Smith dylan.ah.smith at gmail.com
Mon May 23 16:58:46 CDT 2011


4 bytes of padding are at the end of the 64-bit version of
DDSURFACEDESC, because it contains a pointer field followed by an odd
number of DWORD fields. The padding has the same offset as the dwCaps2
field within DDSURFACEDESC2, so was causing the ddraw test
MipMapCreationTest to fail due to not setting this field to 0.
Windows didn't fail the same way even with explicitly setting the padding
before calling CreateSurface.
---
try 2: Refactored DD_STRUCT_COPY_BYSIZE_ to take a modified from_size
  which doesn't include the padding. Also included an inline function
  to abstract the complexity.
---
 dlls/ddraw/ddraw.c         |    3 +--
 dlls/ddraw/ddraw_private.h |   18 ++++++++++++++++--
 dlls/ddraw/surface.c       |    4 +---
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index d95d63a..f8e11d2 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -3120,8 +3120,7 @@ static HRESULT CreateSurface(IDirectDrawImpl *ddraw, DDSURFACEDESC2 *DDSD,
         DDSD->ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
 
     /* Modify some flags */
-    desc2.dwSize = sizeof(desc2);   /* For the struct copy */
-    DD_STRUCT_COPY_BYSIZE(&desc2, DDSD);
+    copy_to_surfacedesc2(&desc2, DDSD);
     desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); /* Just to be sure */
 
     /* Get the video mode from WineD3D - we will need it */
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 78cb3b4..a0f460e 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -588,16 +588,30 @@ typedef struct
 /* Structure copy */
 #define ME(x,f,e) { x, #x, (void (*)(const void *))(f), offsetof(STRUCT, e) }
 
-#define DD_STRUCT_COPY_BYSIZE(to,from)                            \
+#define DD_STRUCT_COPY_BYSIZE_(to,from,from_size)                 \
     do {                                                          \
         DWORD __size = (to)->dwSize;                              \
-        DWORD __copysize = min(__size, (from)->dwSize);           \
+        DWORD __copysize = min(__size, from_size);                \
         assert(to != from);                                       \
         memcpy(to, from, __copysize);                             \
         memset((char*)(to) + __copysize, 0, __size - __copysize); \
         (to)->dwSize = __size; /* restore size */                 \
     } while (0)
 
+#define DD_STRUCT_COPY_BYSIZE(to,from) DD_STRUCT_COPY_BYSIZE_(to,from,(from)->dwSize)
+
+#define SIZEOF_END_PADDING(type, last_field) \
+    (sizeof(type) - offsetof(type, last_field) - sizeof(((type *)0)->last_field))
+
+static inline void copy_to_surfacedesc2(DDSURFACEDESC2 *to, DDSURFACEDESC2 *from)
+{
+    DWORD from_size = from->dwSize;
+    if (from_size == sizeof(DDSURFACEDESC))
+        from_size -= SIZEOF_END_PADDING(DDSURFACEDESC, ddsCaps);
+    to->dwSize = sizeof(DDSURFACEDESC2); /* for struct copy */
+    DD_STRUCT_COPY_BYSIZE_(to, from, from_size);
+}
+
 
 #endif
 
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index f46c200..0b78b03 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -3565,9 +3565,7 @@ HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddr
     surface->version = 7;
     surface->ddraw = ddraw;
 
-    surface->surface_desc.dwSize = sizeof(DDSURFACEDESC2);
-    surface->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
-    DD_STRUCT_COPY_BYSIZE(&surface->surface_desc, desc);
+    copy_to_surfacedesc2(&surface->surface_desc, desc);
 
     surface->first_attached = surface;
     surface->ImplType = surface_type;
-- 
1.7.4.1




More information about the wine-patches mailing list