kernel32: FindExSearchLimitToDirectories has no effect on FindFirstFileEx.
[wine] / dlls / ddraw / tests / dsurface.c
1 /*
2  * Unit tests for (a few) ddraw surface functions
3  *
4  * Copyright (C) 2005 Antoine Chavasse (a.chavasse@gmail.com)
5  * Copyright (C) 2005 Christian Costa
6  * Copyright 2005 Ivan Leo Puoti
7  * Copyright (C) 2007 Stefan Dösinger
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 #define COBJMACROS
24
25 #include <assert.h>
26 #include "wine/test.h"
27 #include "ddraw.h"
28 #include "unknwn.h"
29
30 static LPDIRECTDRAW lpDD = NULL;
31
32 static BOOL CreateDirectDraw(void)
33 {
34     HRESULT rc;
35
36     rc = DirectDrawCreate(NULL, &lpDD, NULL);
37     ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
38     if (!lpDD) {
39         trace("DirectDrawCreateEx() failed with an error %x\n", rc);
40         return FALSE;
41     }
42
43     rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
44     ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
45
46     return TRUE;
47 }
48
49
50 static void ReleaseDirectDraw(void)
51 {
52     if( lpDD != NULL )
53     {
54         IDirectDraw_Release(lpDD);
55         lpDD = NULL;
56     }
57 }
58
59 static void MipMapCreationTest(void)
60 {
61     LPDIRECTDRAWSURFACE lpDDSMipMapTest;
62     DDSURFACEDESC ddsd;
63     HRESULT rc;
64
65     /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
66        DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
67         requested mipmap levels. */
68     ddsd.dwSize = sizeof(ddsd);
69     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
70     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
71     U2(ddsd).dwMipMapCount = 3;
72     ddsd.dwWidth = 128;
73     ddsd.dwHeight = 32;
74     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
75     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
76     if (FAILED(rc)) {
77         skip("failed to create surface\n");
78         return;
79     }
80
81     /* Check the number of created mipmaps */
82     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
83     ddsd.dwSize = sizeof(ddsd);
84     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
85     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
86     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
87         "GetSurfaceDesc returned no mipmapcount.\n");
88     ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
89         U2(ddsd).dwMipMapCount);
90
91     /* Destroy the surface. */
92     IDirectDrawSurface_Release(lpDDSMipMapTest);
93
94
95     /* Second mipmap creation test: create a surface without a mipmap
96        count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
97        This creates a single mipmap level. */
98     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
99     ddsd.dwSize = sizeof(ddsd);
100     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
101     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
102     ddsd.dwWidth = 128;
103     ddsd.dwHeight = 32;
104     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
105     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
106     if (FAILED(rc)) {
107         skip("failed to create surface\n");
108         return;
109     }
110     /* Check the number of created mipmaps */
111     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
112     ddsd.dwSize = sizeof(ddsd);
113     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
114     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
115     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
116         "GetSurfaceDesc returned no mipmapcount.\n");
117     ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
118         U2(ddsd).dwMipMapCount);
119
120     /* Destroy the surface. */
121     IDirectDrawSurface_Release(lpDDSMipMapTest);
122
123
124     /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
125         DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
126        It's an undocumented features where a chain of mipmaps, starting from
127        he specified size and down to the smallest size, is automatically
128        created.
129        Anarchy Online needs this feature to work. */
130     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
131     ddsd.dwSize = sizeof(ddsd);
132     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
133     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
134     ddsd.dwWidth = 128;
135     ddsd.dwHeight = 32;
136     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
137     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
138     if (FAILED(rc)) {
139         skip("failed to create surface\n");
140         return;
141     }
142
143     /* Check the number of created mipmaps */
144     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
145     ddsd.dwSize = sizeof(ddsd);
146     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
147     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
148     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
149         "GetSurfaceDesc returned no mipmapcount.\n");
150     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
151         U2(ddsd).dwMipMapCount);
152
153     /* Destroy the surface. */
154     IDirectDrawSurface_Release(lpDDSMipMapTest);
155
156
157     /* Fourth mipmap creation test: same as above with a different texture
158        size.
159        The purpose is to verify that the number of generated mipmaps is
160        dependent on the smallest dimension. */
161     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
162     ddsd.dwSize = sizeof(ddsd);
163     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
164     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
165     ddsd.dwWidth = 32;
166     ddsd.dwHeight = 64;
167     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
168     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
169     if (FAILED(rc)) {
170         skip("failed to create surface\n");
171         return;
172     }
173
174     /* Check the number of created mipmaps */
175     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
176     ddsd.dwSize = sizeof(ddsd);
177     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
178     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
179     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
180         "GetSurfaceDesc returned no mipmapcount.\n");
181     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
182         U2(ddsd).dwMipMapCount);
183
184     /* Destroy the surface. */
185     IDirectDrawSurface_Release(lpDDSMipMapTest);
186
187
188     /* Fifth mipmap creation test: try to create a surface with
189        DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT,
190        where dwMipMapCount = 0. This should fail. */
191
192     ddsd.dwSize = sizeof(ddsd);
193     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
194     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
195     U2(ddsd).dwMipMapCount = 0;
196     ddsd.dwWidth = 128;
197     ddsd.dwHeight = 32;
198     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
199     ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc);
200
201     /* Destroy the surface. */
202     if( rc == DD_OK )
203         IDirectDrawSurface_Release(lpDDSMipMapTest);
204
205 }
206
207 static void SrcColorKey32BlitTest(void)
208 {
209     LPDIRECTDRAWSURFACE lpSrc;
210     LPDIRECTDRAWSURFACE lpDst;
211     DDSURFACEDESC ddsd, ddsd2, ddsd3;
212     DDCOLORKEY DDColorKey;
213     LPDWORD lpData;
214     HRESULT rc;
215     DDBLTFX fx;
216
217     ddsd2.dwSize = sizeof(ddsd2);
218     ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
219
220     ddsd.dwSize = sizeof(ddsd);
221     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
222     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
223     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
224     ddsd.dwWidth = 800;
225     ddsd.dwHeight = 600;
226     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
227     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
228     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
229     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
230     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
231     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
232     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
233     if (FAILED(rc)) {
234         skip("failed to create surface\n");
235         return;
236     }
237
238     ddsd.dwFlags |= DDSD_CKSRCBLT;
239     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
240     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
241     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
242     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
243     if (FAILED(rc)) {
244         skip("failed to create surface\n");
245         return;
246     }
247
248     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
249     ok(rc==DD_OK,"Lock returned: %x\n",rc);
250     lpData = (LPDWORD)ddsd2.lpSurface;
251     lpData[0] = 0xCCCCCCCC;
252     lpData[1] = 0xCCCCCCCC;
253     lpData[2] = 0xCCCCCCCC;
254     lpData[3] = 0xCCCCCCCC;
255
256     memset(&ddsd3, 0, sizeof(ddsd3));
257     ddsd3.dwSize = sizeof(ddsd3);
258     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
259     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
260     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
261     ok(ddsd3.lpSurface == ddsd3.lpSurface, "lpSurface from GetSurfaceDesc(%p) differs from the one returned by Lock(%p)\n", ddsd3.lpSurface, ddsd2.lpSurface);
262
263     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
264     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
265
266     memset(&ddsd3, 0, sizeof(ddsd3));
267     ddsd3.dwSize = sizeof(ddsd3);
268     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
269     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
270     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
271     ok(ddsd3.lpSurface == NULL, "lpSurface from GetSurfaceDesc(%p) is not NULL after unlock\n", ddsd3.lpSurface);
272
273     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
274     ok(rc==DD_OK,"Lock returned: %x\n",rc);
275     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
276     lpData = (LPDWORD)ddsd2.lpSurface;
277     lpData[0] = 0x77010203;
278     lpData[1] = 0x00010203;
279     lpData[2] = 0x77FF00FF;
280     lpData[3] = 0x00FF00FF;
281     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
282     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
283
284     IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
285
286     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
287     ok(rc==DD_OK,"Lock returned: %x\n",rc);
288     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
289     lpData = (LPDWORD)ddsd2.lpSurface;
290     ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
291        "Destination data after blitting is not correct\n");
292     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
293     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
294
295     /* Also test SetColorKey */
296     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
297     ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
298        "GetColorKey does not return the colorkey used at surface creation\n");
299
300     DDColorKey.dwColorSpaceLowValue = 0x00FF00;
301     DDColorKey.dwColorSpaceHighValue = 0x00FF00;
302     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
303
304     DDColorKey.dwColorSpaceLowValue = 0;
305     DDColorKey.dwColorSpaceHighValue = 0;
306     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
307     ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
308        "GetColorKey does not return the colorkey set with SetColorKey\n");
309
310     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
311     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
312     IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
313     ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
314        "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
315
316     IDirectDrawSurface_Release(lpSrc);
317     IDirectDrawSurface_Release(lpDst);
318
319     /* start with a new set of surfaces to test the color keying parameters to blit */
320     memset(&ddsd, 0, sizeof(ddsd));
321     ddsd.dwSize = sizeof(ddsd);
322     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
323     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
324     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
325     ddsd.dwWidth = 800;
326     ddsd.dwHeight = 600;
327     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
328     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
329     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
330     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
331     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
332     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
333     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
334     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
335     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
336     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
337     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
338     if(FAILED(rc))
339     {
340         skip("Failed to create surface\n");
341         return;
342     }
343
344     /* start with a new set of surfaces to test the color keying parameters to blit */
345     memset(&ddsd, 0, sizeof(ddsd));
346     ddsd.dwSize = sizeof(ddsd);
347     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
348     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
349     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
350     ddsd.dwWidth = 800;
351     ddsd.dwHeight = 600;
352     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
353     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
354     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
355     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
356     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
357     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
358     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
359     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
360     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
361     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
362     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
363     if(FAILED(rc))
364     {
365         skip("Failed to create surface\n");
366         IDirectDrawSurface_Release(lpDst);
367         return;
368     }
369
370     memset(&fx, 0, sizeof(fx));
371     fx.dwSize = sizeof(fx);
372     fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
373     fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
374     fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
375     fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
376
377     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
378     ok(rc==DD_OK,"Lock returned: %x\n",rc);
379     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
380     lpData = (LPDWORD)ddsd2.lpSurface;
381     lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
382     lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
383     lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
384     lpData[3] = 0x0000FF00; /* Src color key in dst surface */
385     lpData[4] = 0x00001100; /* Src color key in ddbltfx */
386     lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
387     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
388     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
389
390     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
391     ok(rc==DD_OK,"Lock returned: %x\n",rc);
392     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
393     lpData = (LPDWORD)ddsd2.lpSurface;
394     lpData[0] = 0x55555555;
395     lpData[1] = 0x55555555;
396     lpData[2] = 0x55555555;
397     lpData[3] = 0x55555555;
398     lpData[4] = 0x55555555;
399     lpData[5] = 0x55555555;
400     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
401     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
402
403     /* Test a blit without keying */
404     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
405     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
406
407     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
408     ok(rc==DD_OK,"Lock returned: %x\n",rc);
409     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
410     lpData = (LPDWORD)ddsd2.lpSurface;
411     /* Should have copied src data unmodified to dst */
412     ok(lpData[0] == 0x000000FF &&
413        lpData[1] == 0x00000000 &&
414        lpData[2] == 0x00FF0000 &&
415        lpData[3] == 0x0000FF00 &&
416        lpData[4] == 0x00001100 &&
417        lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
418
419     lpData[0] = 0x55555555;
420     lpData[1] = 0x55555555;
421     lpData[2] = 0x55555555;
422     lpData[3] = 0x55555555;
423     lpData[4] = 0x55555555;
424     lpData[5] = 0x55555555;
425     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
426     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
427
428     /* Src key */
429     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
430     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
431
432     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
433     ok(rc==DD_OK,"Lock returned: %x\n",rc);
434     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
435     lpData = (LPDWORD)ddsd2.lpSurface;
436
437     ok(lpData[0] == 0x55555555 && /* Here the src key applied */
438        lpData[1] == 0x00000000 &&
439        lpData[2] == 0x00FF0000 &&
440        lpData[3] == 0x0000FF00 &&
441        lpData[4] == 0x00001100 &&
442        lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
443
444     lpData[0] = 0x55555555;
445     lpData[1] = 0x55555555;
446     lpData[2] = 0x55555555;
447     lpData[3] = 0x55555555;
448     lpData[4] = 0x55555555;
449     lpData[5] = 0x55555555;
450     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
451     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
452
453     /* Src override */
454     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
455     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
456
457     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
458     ok(rc==DD_OK,"Lock returned: %x\n",rc);
459     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
460     lpData = (LPDWORD)ddsd2.lpSurface;
461
462     ok(lpData[0] == 0x000000FF &&
463        lpData[1] == 0x00000000 &&
464        lpData[2] == 0x00FF0000 &&
465        lpData[3] == 0x0000FF00 &&
466        lpData[4] == 0x00001100 &&
467        lpData[5] == 0x55555555, /* Override key applies here */
468        "Surface data after src override key blit does not match\n");
469
470     lpData[0] = 0x55555555;
471     lpData[1] = 0x55555555;
472     lpData[2] = 0x55555555;
473     lpData[3] = 0x55555555;
474     lpData[4] = 0x55555555;
475     lpData[5] = 0x55555555;
476     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
477     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
478
479     /* Src override AND src key. That is not supposed to work */
480     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
481     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
482
483     /* Verify that the destination is unchanged */
484     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
485     ok(rc==DD_OK,"Lock returned: %x\n",rc);
486     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
487     lpData = (LPDWORD)ddsd2.lpSurface;
488
489     ok(lpData[0] == 0x55555555 &&
490        lpData[1] == 0x55555555 &&
491        lpData[2] == 0x55555555 &&
492        lpData[3] == 0x55555555 &&
493        lpData[4] == 0x55555555 &&
494        lpData[5] == 0x55555555, /* Override key applies here */
495        "Surface data after src key blit with override does not match\n");
496
497     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
498     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
499     lpData[2] = 0x00001100; /* Dest key in override */
500     lpData[3] = 0x00001100; /* Dest key in override */
501     lpData[4] = 0x00000000; /* Dest key in src surface */
502     lpData[5] = 0x00000000; /* Dest key in src surface */
503     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
504     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
505
506     /* Dest key blit */
507     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
508     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
509
510     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
511     ok(rc==DD_OK,"Lock returned: %x\n",rc);
512     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
513     lpData = (LPDWORD)ddsd2.lpSurface;
514
515     /* DirectDraw uses the dest blit key from the SOURCE surface ! */
516     ok(lpData[0] == 0x00ff0000 &&
517        lpData[1] == 0x00ff0000 &&
518        lpData[2] == 0x00001100 &&
519        lpData[3] == 0x00001100 &&
520        lpData[4] == 0x00001100 && /* Key applies here */
521        lpData[5] == 0x00110000,   /* Key applies here */
522        "Surface data after dest key blit does not match\n");
523
524     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
525     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
526     lpData[2] = 0x00001100; /* Dest key in override */
527     lpData[3] = 0x00001100; /* Dest key in override */
528     lpData[4] = 0x00000000; /* Dest key in src surface */
529     lpData[5] = 0x00000000; /* Dest key in src surface */
530     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
531     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
532
533     /* Dest override key blit */
534     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
535     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
536
537     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
538     ok(rc==DD_OK,"Lock returned: %x\n",rc);
539     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
540     lpData = (LPDWORD)ddsd2.lpSurface;
541
542     ok(lpData[0] == 0x00FF0000 &&
543        lpData[1] == 0x00FF0000 &&
544        lpData[2] == 0x00FF0000 && /* Key applies here */
545        lpData[3] == 0x0000FF00 && /* Key applies here */
546        lpData[4] == 0x00000000 &&
547        lpData[5] == 0x00000000,
548        "Surface data after dest key override blit does not match\n");
549
550     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
551     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
552     lpData[2] = 0x00001100; /* Dest key in override */
553     lpData[3] = 0x00001100; /* Dest key in override */
554     lpData[4] = 0x00000000; /* Dest key in src surface */
555     lpData[5] = 0x00000000; /* Dest key in src surface */
556     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
557     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
558
559     /* Dest override key blit. Supposed to fail too */
560     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
561     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
562
563     /* Check for unchanged data */
564     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
565     ok(rc==DD_OK,"Lock returned: %x\n",rc);
566     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
567     lpData = (LPDWORD)ddsd2.lpSurface;
568
569     ok(lpData[0] == 0x00FF0000 &&
570        lpData[1] == 0x00FF0000 &&
571        lpData[2] == 0x00001100 && /* Key applies here */
572        lpData[3] == 0x00001100 && /* Key applies here */
573        lpData[4] == 0x00000000 &&
574        lpData[5] == 0x00000000,
575        "Surface data with dest key and dest override does not match\n");
576
577     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
578     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
579     lpData[2] = 0x00001100; /* Dest key in override */
580     lpData[3] = 0x00001100; /* Dest key in override */
581     lpData[4] = 0x00000000; /* Dest key in src surface */
582     lpData[5] = 0x00000000; /* Dest key in src surface */
583     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
584     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
585
586     /* Modify the source data a bit to give some more conclusive results */
587     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
588     ok(rc==DD_OK,"Lock returned: %x\n",rc);
589     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
590     lpData = (LPDWORD)ddsd2.lpSurface;
591     lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
592     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
593     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
594
595     /* Source and destination key */
596     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
597     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
598
599     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
600     ok(rc==DD_OK,"Lock returned: %x\n",rc);
601     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
602     lpData = (LPDWORD)ddsd2.lpSurface;
603
604     ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
605        lpData[1] == 0x00FF0000 && /* Masked by Destination key */
606        lpData[2] == 0x00001100 && /* Masked by Destination key */
607        lpData[3] == 0x00001100 && /* Masked by Destination key */
608        lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
609        lpData[5] == 0x00000000,   /* Allowed by dst key, but masked by source key */
610        "Surface data with src key and dest key blit does not match\n");
611
612     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
613     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
614     lpData[2] = 0x00001100; /* Dest key in override */
615     lpData[3] = 0x00001100; /* Dest key in override */
616     lpData[4] = 0x00000000; /* Dest key in src surface */
617     lpData[5] = 0x00000000; /* Dest key in src surface */
618     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
619     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
620
621     /* Override keys without ddbltfx parameter fail */
622     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
623     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
624     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
625     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
626
627     /* Try blitting without keys in the source surface*/
628     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
629     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
630     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
631     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
632
633     /* That fails now. Do not bother to check that the data is unmodified */
634     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
635     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
636
637     /* Dest key blit still works. Which key is used this time??? */
638     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
639     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
640
641     /* With korrectly passed override keys no key in the surface is needed.
642      * Again, the result was checked before, no need to do that again
643      */
644     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
645     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
646     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
647     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
648
649     IDirectDrawSurface_Release(lpSrc);
650     IDirectDrawSurface_Release(lpDst);
651 }
652
653 static void QueryInterface(void)
654 {
655     LPDIRECTDRAWSURFACE dsurface;
656     DDSURFACEDESC surface;
657     LPVOID object;
658     HRESULT ret;
659
660     /* Create a surface */
661     ZeroMemory(&surface, sizeof(surface));
662     surface.dwSize = sizeof(surface);
663     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
664     surface.dwHeight = 10;
665     surface.dwWidth = 10;
666     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
667     if(ret != DD_OK)
668     {
669         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
670         return;
671     }
672
673     /* Call IUnknown::QueryInterface */
674     ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
675     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
676
677     IDirectDrawSurface_Release(dsurface);
678 }
679
680 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
681  * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
682  * partially in the refcount test
683  */
684
685 static unsigned long getref(IUnknown *iface)
686 {
687     IUnknown_AddRef(iface);
688     return IUnknown_Release(iface);
689 }
690
691 static void GetDDInterface_1(void)
692 {
693     LPDIRECTDRAWSURFACE dsurface;
694     LPDIRECTDRAWSURFACE2 dsurface2;
695     DDSURFACEDESC surface;
696     HRESULT ret;
697     IDirectDraw2 *dd2;
698     IDirectDraw4 *dd4;
699     IDirectDraw7 *dd7;
700     unsigned long ref1, ref2, ref4, ref7;
701     void *dd;
702
703     /* Create a surface */
704     ZeroMemory(&surface, sizeof(surface));
705     surface.dwSize = sizeof(surface);
706     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
707     surface.dwHeight = 10;
708     surface.dwWidth = 10;
709     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
710     if(ret != DD_OK)
711     {
712         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
713         return;
714     }
715     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
716     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
717     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
718     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
719     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
720     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
721     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
722     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
723
724     ref1 = getref((IUnknown *) lpDD);
725     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
726     ref2 = getref((IUnknown *) dd2);
727     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
728     ref4 = getref((IUnknown *) dd4);
729     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
730     ref7 = getref((IUnknown *) dd7);
731     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
732
733
734     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
735     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
736     ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
737     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
738     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
739     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
740
741     ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
742     IUnknown_Release((IUnknown *) dd);
743
744     /* try a NULL pointer */
745     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
746     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
747
748     IDirectDraw_Release(dd2);
749     IDirectDraw_Release(dd4);
750     IDirectDraw_Release(dd7);
751     IDirectDrawSurface2_Release(dsurface2);
752     IDirectDrawSurface_Release(dsurface);
753 }
754
755 static void GetDDInterface_2(void)
756 {
757     LPDIRECTDRAWSURFACE dsurface;
758     LPDIRECTDRAWSURFACE2 dsurface2;
759     DDSURFACEDESC surface;
760     HRESULT ret;
761     IDirectDraw2 *dd2;
762     IDirectDraw4 *dd4;
763     IDirectDraw7 *dd7;
764     unsigned long ref1, ref2, ref4, ref7;
765     void *dd;
766
767     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
768     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
769     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
770     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
771     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
772     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
773
774     /* Create a surface */
775     ZeroMemory(&surface, sizeof(surface));
776     surface.dwSize = sizeof(surface);
777     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
778     surface.dwHeight = 10;
779     surface.dwWidth = 10;
780     ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
781     if(ret != DD_OK)
782     {
783         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
784         return;
785     }
786     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
787     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
788
789     ref1 = getref((IUnknown *) lpDD);
790     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
791     ref2 = getref((IUnknown *) dd2);
792     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
793     ref4 = getref((IUnknown *) dd4);
794     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
795     ref7 = getref((IUnknown *) dd7);
796     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
797
798
799     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
800     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
801     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
802     ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
803     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
804     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
805
806     ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
807     IUnknown_Release((IUnknown *) dd);
808
809     IDirectDraw_Release(dd2);
810     IDirectDraw_Release(dd4);
811     IDirectDraw_Release(dd7);
812     IDirectDrawSurface2_Release(dsurface2);
813     IDirectDrawSurface_Release(dsurface);
814 }
815
816 static void GetDDInterface_4(void)
817 {
818     LPDIRECTDRAWSURFACE2 dsurface2;
819     LPDIRECTDRAWSURFACE4 dsurface4;
820     DDSURFACEDESC2 surface;
821     HRESULT ret;
822     IDirectDraw2 *dd2;
823     IDirectDraw4 *dd4;
824     IDirectDraw7 *dd7;
825     unsigned long ref1, ref2, ref4, ref7;
826     void *dd;
827
828     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
829     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
830     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
831     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
832     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
833     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
834
835     /* Create a surface */
836     ZeroMemory(&surface, sizeof(surface));
837     surface.dwSize = sizeof(surface);
838     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
839     surface.dwHeight = 10;
840     surface.dwWidth = 10;
841     ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
842     if(ret != DD_OK)
843     {
844         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
845         return;
846     }
847     ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
848     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
849
850     ref1 = getref((IUnknown *) lpDD);
851     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
852     ref2 = getref((IUnknown *) dd2);
853     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
854     ref4 = getref((IUnknown *) dd4);
855     ok(ref4 == 2, "IDirectDraw4 refcount is %ld\n", ref4);
856     ref7 = getref((IUnknown *) dd7);
857     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
858
859     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
860     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
861     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
862     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
863     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
864     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
865
866     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
867     IUnknown_Release((IUnknown *) dd);
868
869     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
870     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
871     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
872     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
873     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
874     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
875     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
876
877     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
878     IUnknown_Release((IUnknown *) dd);
879
880     IDirectDraw_Release(dd2);
881     IDirectDraw_Release(dd4);
882     IDirectDraw_Release(dd7);
883     IDirectDrawSurface4_Release(dsurface4);
884     IDirectDrawSurface2_Release(dsurface2);
885 }
886
887 static void GetDDInterface_7(void)
888 {
889     LPDIRECTDRAWSURFACE4 dsurface4;
890     LPDIRECTDRAWSURFACE7 dsurface7;
891     DDSURFACEDESC2 surface;
892     HRESULT ret;
893     IDirectDraw2 *dd2;
894     IDirectDraw4 *dd4;
895     IDirectDraw7 *dd7;
896     unsigned long ref1, ref2, ref4, ref7;
897     void *dd;
898
899     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
900     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
901     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
902     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
903     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
904     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
905
906     /* Create a surface */
907     ZeroMemory(&surface, sizeof(surface));
908     surface.dwSize = sizeof(surface);
909     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
910     surface.dwHeight = 10;
911     surface.dwWidth = 10;
912     ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
913     if(ret != DD_OK)
914     {
915         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
916         return;
917     }
918     ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
919     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
920
921     ref1 = getref((IUnknown *) lpDD);
922     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
923     ref2 = getref((IUnknown *) dd2);
924     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
925     ref4 = getref((IUnknown *) dd4);
926     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
927     ref7 = getref((IUnknown *) dd7);
928     ok(ref7 == 2, "IDirectDraw7 refcount is %ld\n", ref7);
929
930     ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
931     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
932     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
933     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
934     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
935     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
936
937     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
938     IUnknown_Release((IUnknown *) dd);
939
940     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
941     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
942     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
943     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
944     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
945     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
946     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
947
948     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
949     IUnknown_Release((IUnknown *) dd);
950
951     IDirectDraw_Release(dd2);
952     IDirectDraw_Release(dd4);
953     IDirectDraw_Release(dd7);
954     IDirectDrawSurface4_Release(dsurface4);
955     IDirectDrawSurface7_Release(dsurface7);
956 }
957
958 #define MAXEXPECTED 8  /* Can match up to 8 expected surfaces */
959 struct enumstruct
960 {
961     IDirectDrawSurface *expected[MAXEXPECTED];
962     UINT count;
963 };
964
965 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
966 {
967     int i;
968     BOOL found = FALSE;
969
970     for(i = 0; i < MAXEXPECTED; i++)
971     {
972         if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
973     }
974
975     ok(found, "Unexpected surface %p enumerated\n", surf);
976     ((struct enumstruct *)ctx)->count++;
977     IDirectDrawSurface_Release(surf);
978     return DDENUMRET_OK;
979 }
980
981 static void EnumTest(void)
982 {
983     HRESULT rc;
984     DDSURFACEDESC ddsd;
985     IDirectDrawSurface *surface;
986     struct enumstruct ctx;
987
988     ddsd.dwSize = sizeof(ddsd);
989     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
990     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
991     U2(ddsd).dwMipMapCount = 3;
992     ddsd.dwWidth = 32;
993     ddsd.dwHeight = 32;
994     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
995     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
996
997     memset(&ctx, 0, sizeof(ctx));
998     ctx.expected[0] = surface;
999     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1000     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1001     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1002     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1003     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1004     ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1005     ctx.count = 0;
1006
1007     rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, (void *) &ctx, enumCB);
1008     ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1009     ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1010
1011     IDirectDrawSurface_Release(ctx.expected[2]);
1012     IDirectDrawSurface_Release(ctx.expected[1]);
1013     IDirectDrawSurface_Release(surface);
1014 }
1015
1016 HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1017 {
1018     UINT *num = context;
1019     (*num)++;
1020     IDirectDrawSurface_Release(surface);
1021     return DDENUMRET_OK;
1022 }
1023
1024 static void AttachmentTest7(void)
1025 {
1026     HRESULT hr;
1027     IDirectDraw7 *dd7;
1028     IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1029     DDSURFACEDESC2 ddsd;
1030     UINT num;
1031     DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0};
1032     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1033
1034     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1035     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1036
1037     memset(&ddsd, 0, sizeof(ddsd));
1038     ddsd.dwSize = sizeof(ddsd);
1039     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1040     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1041     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1042     ddsd.dwWidth = 128;
1043     ddsd.dwHeight = 128;
1044     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1045     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1046
1047     /* ROOT */
1048     num = 0;
1049     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1050     ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1051     /* DONE ROOT */
1052
1053     /* LEVEL 1 */
1054     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1055     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1056     num = 0;
1057     IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1058     ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1059     /* DONE LEVEL 1 */
1060
1061     /* LEVEL 2 */
1062     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1063     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1064     IDirectDrawSurface7_Release(surface2);
1065     num = 0;
1066     IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1067     ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1068     /* Done level 2 */
1069     /* Mip level 3 is still needed */
1070
1071     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1072     memset(&ddsd, 0, sizeof(ddsd));
1073     ddsd.dwSize = sizeof(ddsd);
1074     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1075     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1076     ddsd.dwWidth = 16;
1077     ddsd.dwHeight = 16;
1078     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1079     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1080
1081     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1082     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1083     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1084     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1085     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1086     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1087     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1088     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1089
1090     IDirectDrawSurface7_Release(surface2);
1091
1092     memset(&ddsd, 0, sizeof(ddsd));
1093     ddsd.dwSize = sizeof(ddsd);
1094     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1095     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1096     ddsd.dwWidth = 16;
1097     ddsd.dwHeight = 16;
1098     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1099     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1100
1101     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1102     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1103     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1104     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1105     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1106     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1107     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1108     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1109
1110     IDirectDrawSurface7_Release(surface3);
1111     IDirectDrawSurface7_Release(surface2);
1112     IDirectDrawSurface7_Release(surface1);
1113
1114     hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1115     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1116
1117     memset(&ddsd, 0, sizeof(ddsd));
1118     ddsd.dwSize = sizeof(ddsd);
1119     ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1120     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1121     ddsd.dwBackBufferCount = 2;
1122     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1123     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1124
1125     num = 0;
1126     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1127     ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1128     IDirectDrawSurface7_Release(surface1);
1129
1130     /* Those are some invalid descriptions, no need to test attachments with them */
1131     memset(&ddsd, 0, sizeof(ddsd));
1132     ddsd.dwSize = sizeof(ddsd);
1133     ddsd.dwFlags = DDSD_CAPS;
1134     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1135     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1136     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1137     memset(&ddsd, 0, sizeof(ddsd));
1138     ddsd.dwSize = sizeof(ddsd);
1139     ddsd.dwFlags = DDSD_CAPS;
1140     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1141     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1142     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1143
1144     /* Try a single primary and two offscreen plain surfaces */
1145     memset(&ddsd, 0, sizeof(ddsd));
1146     ddsd.dwSize = sizeof(ddsd);
1147     ddsd.dwFlags = DDSD_CAPS;
1148     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1149     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1150     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1151
1152     memset(&ddsd, 0, sizeof(ddsd));
1153     ddsd.dwSize = sizeof(ddsd);
1154     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1155     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1156     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1157     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1158     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1159     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1160
1161     memset(&ddsd, 0, sizeof(ddsd));
1162     ddsd.dwSize = sizeof(ddsd);
1163     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1164     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1165     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1166     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1167     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1168     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1169
1170     /* This one has a different size */
1171     memset(&ddsd, 0, sizeof(ddsd));
1172     ddsd.dwSize = sizeof(ddsd);
1173     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1174     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1175     ddsd.dwWidth = 128;
1176     ddsd.dwHeight = 128;
1177     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1178     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1179
1180     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1181     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1182     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1183     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1184     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1185     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1186     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1187     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1188     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1189     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1190
1191     IDirectDrawSurface7_Release(surface4);
1192     IDirectDrawSurface7_Release(surface3);
1193     IDirectDrawSurface7_Release(surface2);
1194     IDirectDrawSurface7_Release(surface1);
1195
1196     hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1197     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1198     IDirectDraw7_Release(dd7);
1199 }
1200
1201 static void AttachmentTest(void)
1202 {
1203     HRESULT hr;
1204     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1205     DDSURFACEDESC ddsd;
1206     DDSCAPS caps = {DDSCAPS_TEXTURE};
1207     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1208
1209     memset(&ddsd, 0, sizeof(ddsd));
1210     ddsd.dwSize = sizeof(ddsd);
1211     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1212     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1213     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1214     ddsd.dwWidth = 128;
1215     ddsd.dwHeight = 128;
1216     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1217     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1218
1219     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1220     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1221     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1222     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1223
1224     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1225     memset(&ddsd, 0, sizeof(ddsd));
1226     ddsd.dwSize = sizeof(ddsd);
1227     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1228     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1229     ddsd.dwWidth = 16;
1230     ddsd.dwHeight = 16;
1231     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1232     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1233
1234     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1235     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1236     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1237     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1238     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1239     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1240     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1241     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1242     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1243     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1244     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1245     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1246
1247     IDirectDrawSurface7_Release(surface4);
1248
1249     memset(&ddsd, 0, sizeof(ddsd));
1250     ddsd.dwSize = sizeof(ddsd);
1251     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1252     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1253     ddsd.dwWidth = 16;
1254     ddsd.dwHeight = 16;
1255     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1256     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1257
1258     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1259     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1260     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1261     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);  /* Succeeds on refrast */
1262     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1263     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1264     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);  /* Succeeds on refrast */
1265     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1266     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1267     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1268     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1269     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1270     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);  /* Succeeds on refrast */
1271     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1272     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1273     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1274     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1275     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1276
1277     IDirectDrawSurface7_Release(surface4);
1278     IDirectDrawSurface7_Release(surface3);
1279     IDirectDrawSurface7_Release(surface2);
1280     IDirectDrawSurface7_Release(surface1);
1281
1282     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1283     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1284
1285     /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1286     memset(&ddsd, 0, sizeof(ddsd));
1287     ddsd.dwSize = sizeof(ddsd);
1288     ddsd.dwFlags = DDSD_CAPS;
1289     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1290     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1291     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1292     /* This old ddraw version happily creates explicit front buffers */
1293     memset(&ddsd, 0, sizeof(ddsd));
1294     ddsd.dwSize = sizeof(ddsd);
1295     ddsd.dwFlags = DDSD_CAPS;
1296     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1297     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1298     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1299     IDirectDrawSurface_Release(surface1);
1300
1301     /* Try a single primary and two offscreen plain surfaces */
1302     memset(&ddsd, 0, sizeof(ddsd));
1303     ddsd.dwSize = sizeof(ddsd);
1304     ddsd.dwFlags = DDSD_CAPS;
1305     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1306     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1307     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1308
1309     memset(&ddsd, 0, sizeof(ddsd));
1310     ddsd.dwSize = sizeof(ddsd);
1311     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1312     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1313     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1314     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1315     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1316     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1317
1318     memset(&ddsd, 0, sizeof(ddsd));
1319     ddsd.dwSize = sizeof(ddsd);
1320     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1321     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1322     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1323     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1324     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1325     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1326
1327     /* This one has a different size */
1328     memset(&ddsd, 0, sizeof(ddsd));
1329     ddsd.dwSize = sizeof(ddsd);
1330     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1331     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1332     ddsd.dwWidth = 128;
1333     ddsd.dwHeight = 128;
1334     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1335     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1336
1337     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1338     ok(hr == DD_OK, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1339     /* Try the reverse without detaching first */
1340     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1341     ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1342     hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1343     ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1344     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1345     ok(hr == DD_OK, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1346     /* Try to detach reversed */
1347     hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1348     ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1349     /* Now the proper detach */
1350     hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1351     ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1352     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1353     ok(hr == DD_OK, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1354     if(SUCCEEDED(hr))
1355     {
1356         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1357         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1358     }
1359     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1360     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1361     hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1362     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1363
1364     IDirectDrawSurface_Release(surface4);
1365     IDirectDrawSurface_Release(surface3);
1366     IDirectDrawSurface_Release(surface2);
1367     IDirectDrawSurface_Release(surface1);
1368
1369     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1370     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1371
1372     DestroyWindow(window);
1373 }
1374
1375 struct compare
1376 {
1377     DWORD width, height;
1378     DWORD caps, caps2;
1379     UINT mips;
1380 };
1381
1382 HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1383 {
1384     UINT *mips = context;
1385
1386     (*mips)++;
1387     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1388                                              context,
1389                                              CubeTestLvl2Enum);
1390
1391     return DDENUMRET_OK;
1392 }
1393
1394 HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1395 {
1396     UINT mips = 0;
1397     UINT *num = (UINT *) context;
1398     static const struct compare expected[] =
1399     {
1400         {
1401             128, 128,
1402             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1403             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1404             7
1405         },
1406         {
1407             128, 128,
1408             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1409             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1410             7
1411         },
1412         {
1413             128, 128,
1414             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1415             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1416             7
1417         },
1418         {
1419             128, 128,
1420             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1421             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1422             7
1423         },
1424         {
1425             128, 128,
1426             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1427             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1428             7
1429         },
1430         {
1431             64, 64, /* This is the first mipmap */
1432             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1433             DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1434             6
1435         },
1436     };
1437
1438     mips = 0;
1439     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1440                                              &mips,
1441                                              CubeTestLvl2Enum);
1442
1443     ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1444     ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1445     ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1446     ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1447     ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1448
1449     (*num)++;
1450
1451     IDirectDrawSurface7_Release(surface);
1452
1453     return DDENUMRET_OK;
1454 }
1455
1456 static void CubeMapTest(void)
1457 {
1458     IDirectDraw7 *dd7 = NULL;
1459     IDirectDrawSurface7 *cubemap;
1460     DDSURFACEDESC2 ddsd;
1461     HRESULT hr;
1462     UINT num = 0;
1463     struct enumstruct ctx;
1464
1465     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1466     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1467
1468     memset(&ddsd, 0, sizeof(ddsd));
1469     ddsd.dwSize = sizeof(ddsd);
1470     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1471     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1472     ddsd.dwWidth = 128;
1473     ddsd.dwHeight = 128;
1474     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1475     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1476
1477     /* D3DFMT_R5G6B5 */
1478     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1479     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1480     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1481     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1482     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1483
1484     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1485     ok(hr == DD_OK, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1486
1487     hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1488     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1489     ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1490        "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1491     ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1492        "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1493
1494     IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1495                                              &num,
1496                                              CubeTestLvl1Enum);
1497     trace("Enumerated %d surfaces in total\n", num);
1498     ok(num == 6, "Surface has %d attachments\n", num);
1499     IDirectDrawSurface7_Release(cubemap);
1500
1501     /* What happens if I do not specify any faces? */
1502     memset(&ddsd, 0, sizeof(ddsd));
1503     ddsd.dwSize = sizeof(ddsd);
1504     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1505     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1506     ddsd.dwWidth = 128;
1507     ddsd.dwHeight = 128;
1508     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1509     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1510
1511     /* D3DFMT_R5G6B5 */
1512     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1513     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1514     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1515     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1516     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1517
1518     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1519     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1520
1521     /* Cube map faces without a cube map? */
1522     memset(&ddsd, 0, sizeof(ddsd));
1523     ddsd.dwSize = sizeof(ddsd);
1524     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1525     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1526     ddsd.dwWidth = 128;
1527     ddsd.dwHeight = 128;
1528     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1529     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1530
1531     /* D3DFMT_R5G6B5 */
1532     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1533     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1534     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1535     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1536     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1537
1538     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1539     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1540
1541     memset(&ddsd, 0, sizeof(ddsd));
1542     ddsd.dwSize = sizeof(ddsd);
1543     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1544     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1545     ddsd.dwWidth = 128;
1546     ddsd.dwHeight = 128;
1547     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1548     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1549
1550     /* D3DFMT_R5G6B5 */
1551     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1552     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1553     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1554     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1555     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1556
1557     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1558     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1559
1560     /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1561     memset(&ctx, 0, sizeof(ctx));
1562     memset(&ddsd, 0, sizeof(ddsd));
1563     ddsd.dwSize = sizeof(DDSURFACEDESC);
1564     hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1565     ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1566     ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1567
1568     IDirectDraw7_Release(dd7);
1569 }
1570
1571 static void test_lockrect_invalid(void)
1572 {
1573     unsigned int i, j;
1574
1575     RECT valid[] = {
1576         {60, 60, 68, 68},
1577         {60, 60, 60, 68},
1578         {60, 60, 68, 60},
1579         {120, 60, 128, 68},
1580         {60, 120, 68, 128},
1581     };
1582
1583     RECT invalid[] = {
1584         {68, 60, 60, 68},       /* left > right */
1585         {60, 68, 68, 60},       /* top > bottom */
1586         {-8, 60,  0, 68},       /* left < surface */
1587         {60, -8, 68,  0},       /* top < surface */
1588         {-16, 60, -8, 68},      /* right < surface */
1589         {60, -16, 68, -8},      /* bottom < surface */
1590         {60, 60, 136, 68},      /* right > surface */
1591         {60, 60, 68, 136},      /* bottom > surface */
1592         {136, 60, 144, 68},     /* left > surface */
1593         {60, 136, 68, 144},     /* top > surface */
1594     };
1595
1596     const DWORD dds_caps[] = {
1597         DDSCAPS_OFFSCREENPLAIN,
1598         DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE,
1599     };
1600
1601     for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1602     {
1603         IDirectDrawSurface *surface = 0;
1604         DDSURFACEDESC surface_desc = {0};
1605         DDSURFACEDESC locked_desc = {0};
1606         HRESULT hr;
1607
1608         surface_desc.dwSize = sizeof(surface_desc);
1609         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1610         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1611         surface_desc.ddsCaps.dwCaps = dds_caps[j];
1612         surface_desc.dwWidth = 128;
1613         surface_desc.dwHeight = 128;
1614         surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1615         U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1616         U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1617         U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1618         U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1619
1620         hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1621         ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1622         if (FAILED(hr)) {
1623             skip("failed to create surface\n");
1624             continue;
1625         }
1626
1627         for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1628         {
1629             RECT *rect = &valid[i];
1630
1631             memset(&locked_desc, 0, sizeof(locked_desc));
1632             locked_desc.dwSize = sizeof(locked_desc);
1633
1634             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1635             ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1636                     hr, rect->left, rect->top, rect->right, rect->bottom);
1637
1638             hr = IDirectDrawSurface_Unlock(surface, NULL);
1639             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1640         }
1641
1642         for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1643         {
1644             RECT *rect = &invalid[i];
1645
1646             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1647             ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1648                     ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1649                     rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1650         }
1651
1652         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1653         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1654         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1655         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1656         if(SUCCEEDED(hr)) {
1657             hr = IDirectDrawSurface_Unlock(surface, NULL);
1658             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1659         }
1660         hr = IDirectDrawSurface_Unlock(surface, NULL);
1661         ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1662
1663         memset(&locked_desc, 0, sizeof(locked_desc));
1664         locked_desc.dwSize = sizeof(locked_desc);
1665         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1666         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1667            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1668         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1669         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1670            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1671
1672         /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1673          * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1674          */
1675
1676         hr = IDirectDrawSurface_Unlock(surface, NULL);
1677         ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1678
1679         IDirectDrawSurface_Release(surface);
1680     }
1681 }
1682
1683 static void CompressedTest(void)
1684 {
1685     HRESULT hr;
1686     IDirectDrawSurface7 *surface;
1687     DDSURFACEDESC2 ddsd, ddsd2;
1688     IDirectDraw7 *dd7 = NULL;
1689     RECT r = { 0, 0, 128, 128 };
1690     RECT r2 = { 32, 32, 64, 64 };
1691
1692     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1693     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1694
1695     memset(&ddsd, 0, sizeof(ddsd));
1696     ddsd.dwSize = sizeof(ddsd);
1697     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1698     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1699     ddsd.dwWidth = 128;
1700     ddsd.dwHeight = 128;
1701     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1702     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1703     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1704
1705     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1706     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1707     if (FAILED(hr)) {
1708         skip("failed to create surface\n");
1709         return;
1710     }
1711
1712     memset(&ddsd2, 0, sizeof(ddsd2));
1713     ddsd2.dwSize = sizeof(ddsd2);
1714     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1715     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1716     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1717
1718     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1719        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1720     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1721     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1722     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1723        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1724     ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1725     ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1726     IDirectDrawSurface7_Release(surface);
1727
1728     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1729     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1730     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1731     if (FAILED(hr)) {
1732         skip("failed to create surface\n");
1733         return;
1734     }
1735
1736     memset(&ddsd2, 0, sizeof(ddsd2));
1737     ddsd2.dwSize = sizeof(ddsd2);
1738     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1739     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1740     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1741
1742     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1743        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1744     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1745     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1746     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1747        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1748     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1749     IDirectDrawSurface7_Release(surface);
1750
1751     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1752     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1753     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1754     if (FAILED(hr)) {
1755         skip("failed to create surface\n");
1756         return;
1757     }
1758
1759     memset(&ddsd2, 0, sizeof(ddsd2));
1760     ddsd2.dwSize = sizeof(ddsd2);
1761     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1762     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1763     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1764
1765     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1766        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1767     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1768     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1769     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1770        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1771     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1772     ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1773
1774     memset(&ddsd2, 0, sizeof(ddsd2));
1775     ddsd2.dwSize = sizeof(ddsd2);
1776     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1777
1778     /* Show that the description is not changed when locking the surface. What is really interesting
1779      * about this is that DDSD_LPSURFACE isn't set.
1780      */
1781     hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1782     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1783
1784     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1785        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1786     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1787     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1788     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1789        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1790     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1791     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1792
1793     hr = IDirectDrawSurface7_Unlock(surface, NULL);
1794     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1795
1796     /* Now what about a locking rect?  */
1797     hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1798     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1799
1800     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1801        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1802     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1803     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1804     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1805        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1806     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1807     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1808
1809     hr = IDirectDrawSurface7_Unlock(surface, &r);
1810     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1811
1812     /* Now what about a different locking offset? */
1813     hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1814     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1815
1816     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1817        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1818     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1819     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1820     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1821        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1822     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1823     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1824
1825     hr = IDirectDrawSurface7_Unlock(surface, &r2);
1826     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1827     IDirectDrawSurface7_Release(surface);
1828
1829     /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
1830      * but seems to have a pitch instead.
1831      */
1832     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
1833     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1834
1835     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1836     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS,
1837        "CreateSurface returned %08x\n", hr);
1838
1839     /* Not supported everywhere */
1840     if(SUCCEEDED(hr))
1841     {
1842         memset(&ddsd2, 0, sizeof(ddsd2));
1843         ddsd2.dwSize = sizeof(ddsd2);
1844         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1845         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1846         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1847
1848         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1849         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1850         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1851         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1852         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1853         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1854         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1855         ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1856         IDirectDrawSurface7_Release(surface);
1857
1858         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1859         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1860         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1861
1862         memset(&ddsd2, 0, sizeof(ddsd2));
1863         ddsd2.dwSize = sizeof(ddsd2);
1864         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1865         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1866         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1867
1868         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1869         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1870         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1871         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1872         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1873         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1874         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1875         IDirectDrawSurface7_Release(surface);
1876
1877         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1878         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1879         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1880
1881         memset(&ddsd2, 0, sizeof(ddsd2));
1882         ddsd2.dwSize = sizeof(ddsd2);
1883         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1884         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1885         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1886
1887         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1888         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1889         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1890         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1891         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1892         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1893         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1894         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1895
1896         memset(&ddsd2, 0, sizeof(ddsd2));
1897         ddsd2.dwSize = sizeof(ddsd2);
1898         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1899
1900         /* Show that the description is not changed when locking the surface. What is really interesting
1901         * about this is that DDSD_LPSURFACE isn't set.
1902         */
1903         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1904         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1905
1906         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1907         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1908         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1909         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1910         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1911         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1912         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1913         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1914
1915         hr = IDirectDrawSurface7_Unlock(surface, NULL);
1916         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1917
1918         /* Now what about a locking rect?  */
1919         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1920         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1921
1922         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1923         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1924         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1925         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1926         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1927         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1928         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1929         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1930
1931         hr = IDirectDrawSurface7_Unlock(surface, &r);
1932         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1933
1934         /* Now what about a different locking offset? */
1935         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1936         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1937
1938         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1939         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1940         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1941         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1942         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1943         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1944         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1945         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1946
1947         hr = IDirectDrawSurface7_Unlock(surface, &r2);
1948         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1949
1950         IDirectDrawSurface7_Release(surface);
1951     }
1952     else
1953     {
1954         skip("Hardware DXTN textures not supported\n");
1955     }
1956
1957     /* What happens to managed textures? Interestingly, Windows reports them as being in system
1958      * memory. The linear size fits again.
1959      */
1960     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1961     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
1962     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1963
1964     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1965     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
1966
1967     /* Not supported everywhere */
1968     if(SUCCEEDED(hr))
1969     {
1970         memset(&ddsd2, 0, sizeof(ddsd2));
1971         ddsd2.dwSize = sizeof(ddsd2);
1972         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1973         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1974         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1975
1976         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1977         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1978         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1979         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1980         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1981         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1982         ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1983         ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1984         IDirectDrawSurface7_Release(surface);
1985
1986         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1987         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1988         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1989
1990         memset(&ddsd2, 0, sizeof(ddsd2));
1991         ddsd2.dwSize = sizeof(ddsd2);
1992         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1993         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1994         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1995
1996         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1997         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1998         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1999         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2000         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2001         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2002         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2003         IDirectDrawSurface7_Release(surface);
2004
2005         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2006         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2007         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2008
2009         memset(&ddsd2, 0, sizeof(ddsd2));
2010         ddsd2.dwSize = sizeof(ddsd2);
2011         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2012         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2013         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2014
2015         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2016         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2017         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2018         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2019         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2020         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2021         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2022         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2023
2024         memset(&ddsd2, 0, sizeof(ddsd2));
2025         ddsd2.dwSize = sizeof(ddsd2);
2026         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2027
2028         /* Show that the description is not changed when locking the surface. What is really interesting
2029         * about this is that DDSD_LPSURFACE isn't set.
2030         */
2031         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2032         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2033
2034         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2035         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2036         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2037         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2038         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2039         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2040         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2041         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2042
2043         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2044         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2045
2046         /* Now what about a locking rect?  */
2047         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2048         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2049
2050         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2051         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2052         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2053         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2054         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2055         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2056         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2057         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2058
2059         hr = IDirectDrawSurface7_Unlock(surface, &r);
2060         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2061
2062         /* Now what about a different locking offset? */
2063         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2064         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2065
2066         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2067         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2068         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2069         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2070         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2071         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2072         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2073         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2074
2075         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2076         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2077
2078         IDirectDrawSurface7_Release(surface);
2079     }
2080     else
2081     {
2082         skip("Hardware DXTN textures not supported\n");
2083     }
2084
2085     IDirectDraw7_Release(dd7);
2086 }
2087
2088 static void SizeTest(void)
2089 {
2090     LPDIRECTDRAWSURFACE dsurface = NULL;
2091     DDSURFACEDESC desc;
2092     HRESULT ret;
2093     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2094
2095     /* Create an offscreen surface surface without a size */
2096     ZeroMemory(&desc, sizeof(desc));
2097     desc.dwSize = sizeof(desc);
2098     desc.dwFlags = DDSD_CAPS;
2099     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2100     trace("before offscreenplain create dsurface = %p\n", dsurface);
2101     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2102     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2103     if(dsurface)
2104     {
2105         trace("Surface at %p\n", dsurface);
2106         IDirectDrawSurface_Release(dsurface);
2107         dsurface = NULL;
2108     }
2109
2110     /* Create an offscreen surface surface with only a width parameter */
2111     ZeroMemory(&desc, sizeof(desc));
2112     desc.dwSize = sizeof(desc);
2113     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2114     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2115     desc.dwWidth = 128;
2116     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2117     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without hight info returned %08x\n", ret);
2118     if(dsurface)
2119     {
2120         IDirectDrawSurface_Release(dsurface);
2121         dsurface = NULL;
2122     }
2123
2124     /* Create an offscreen surface surface with only a height parameter */
2125     ZeroMemory(&desc, sizeof(desc));
2126     desc.dwSize = sizeof(desc);
2127     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2128     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2129     desc.dwHeight = 128;
2130     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2131     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2132     if(dsurface)
2133     {
2134         IDirectDrawSurface_Release(dsurface);
2135         dsurface = NULL;
2136     }
2137
2138     /* Sanity check */
2139     ZeroMemory(&desc, sizeof(desc));
2140     desc.dwSize = sizeof(desc);
2141     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2142     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2143     desc.dwHeight = 128;
2144     desc.dwWidth = 128;
2145     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2146     ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2147     if(dsurface)
2148     {
2149         IDirectDrawSurface_Release(dsurface);
2150         dsurface = NULL;
2151     }
2152
2153     /* Test a primary surface size */
2154     ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2155     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2156
2157     ZeroMemory(&desc, sizeof(desc));
2158     desc.dwSize = sizeof(desc);
2159     desc.dwFlags = DDSD_CAPS;
2160     desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2161     desc.dwHeight = 128; /* Keep them set to  check what happens */
2162     desc.dwWidth = 128; /* Keep them set to  check what happens */
2163     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2164     ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2165     if(dsurface)
2166     {
2167         ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2168         ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2169
2170         IDirectDrawSurface_Release(dsurface);
2171         dsurface = NULL;
2172
2173         ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2174         ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2175         ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2176         ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2177     }
2178     ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2179     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2180 }
2181
2182 static void PrivateDataTest(void)
2183 {
2184     HRESULT hr;
2185     IDirectDrawSurface7 *surface7 = NULL;
2186     IDirectDrawSurface *surface = NULL;
2187     DDSURFACEDESC desc;
2188     ULONG ref, ref2;
2189     IUnknown *ptr;
2190     DWORD size = sizeof(IUnknown *);
2191
2192     ZeroMemory(&desc, sizeof(desc));
2193     desc.dwSize = sizeof(desc);
2194     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2195     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2196     desc.dwHeight = 128;
2197     desc.dwWidth = 128;
2198     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2199     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2200     if(!surface)
2201     {
2202         return;
2203     }
2204     hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2205     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2206     if(!surface)
2207     {
2208         IDirectDrawSurface_Release(surface);
2209         return;
2210     }
2211
2212     /* This fails */
2213     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2214     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2215     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2216     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2217     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2218     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2219
2220     ref = getref((IUnknown *) lpDD);
2221     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2222     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2223     ref2 = getref((IUnknown *) lpDD);
2224     ok(ref2 == ref + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2225     hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2226     ref2 = getref((IUnknown *) lpDD);
2227     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2228
2229     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2230     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2231     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2232     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2233     ref2 = getref((IUnknown *) lpDD);
2234     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2235
2236     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2237     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2238     hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2239     ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2240     ref2 = getref((IUnknown *) lpDD);
2241     /* Object is NOT beein addrefed */
2242     ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2243     ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2244
2245     IDirectDrawSurface_Release(surface);
2246     IDirectDrawSurface7_Release(surface7);
2247
2248     /* Destroying the surface frees the held reference */
2249     ref2 = getref((IUnknown *) lpDD);
2250     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2251 }
2252
2253 static void BltParamTest(void)
2254 {
2255     IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2256     DDSURFACEDESC desc;
2257     HRESULT hr;
2258     DDBLTFX BltFx;
2259     RECT valid = {10, 10, 20, 20};
2260     RECT invalid1 = {20, 10, 10, 20};
2261     RECT invalid2 = {20, 20, 20, 20};
2262     RECT invalid3 = {-1, -1, 20, 20};
2263     RECT invalid4 = {60, 60, 70, 70};
2264
2265     memset(&desc, 0, sizeof(desc));
2266     desc.dwSize = sizeof(desc);
2267     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2268     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2269     desc.dwHeight = 128;
2270     desc.dwWidth = 128;
2271     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2272     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2273
2274     desc.dwHeight = 64;
2275     desc.dwWidth = 64;
2276     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2277     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2278
2279     if(0)
2280     {
2281         /* This crashes */
2282         hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2283         ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2284     }
2285     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2286     ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2287     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2288     ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2289     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2290     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2291     hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2292     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2293     hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2294     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2295     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2296     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2297     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2298     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2299     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2300     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2301     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2302     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2303     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2304     ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2305
2306     /* Blt(non-fast) tests */
2307     memset(&BltFx, 0, sizeof(BltFx));
2308     BltFx.dwSize = sizeof(BltFx);
2309     U5(BltFx).dwFillColor = 0xaabbccdd;
2310
2311     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2312     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2313     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2314     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2315     hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2316     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2317     hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2318     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2319     hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2320     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2321     hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2322     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2323
2324     /* Valid on surface 1 */
2325     hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2326     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2327
2328     /* Works - stretched blit */
2329     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2330     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2331     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2332     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2333
2334     /* Invalid dest rects in sourced blits */
2335     hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2336     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2337     hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2338     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2339     hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2340     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2341     hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2342     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2343
2344     /* Invalid src rects */
2345     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2346     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2347     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2348     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2349     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2350     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2351     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2352     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2353
2354     IDirectDrawSurface_Release(surface1);
2355     IDirectDrawSurface_Release(surface2);
2356 }
2357
2358 static void StructSizeTest(void)
2359 {
2360     IDirectDrawSurface *surface1;
2361     IDirectDrawSurface7 *surface7;
2362     union {
2363         DDSURFACEDESC desc1;
2364         DDSURFACEDESC2 desc2;
2365         char blob[1024]; /* To get a bunch of writable memory */
2366     } desc;
2367     DDSURFACEDESC create;
2368     HRESULT hr;
2369
2370     memset(&desc, 0, sizeof(desc));
2371     memset(&create, 0, sizeof(create));
2372
2373     memset(&create, 0, sizeof(create));
2374     create.dwSize = sizeof(create);
2375     create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2376     create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2377     create.dwHeight = 128;
2378     create.dwWidth = 128;
2379     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2380     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2381     hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2382     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2383
2384     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2385     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2386     ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2387     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2388     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2389
2390     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2391     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2392     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2393     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2394     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2395
2396     desc.desc2.dwSize = 0;
2397     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2398     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2399     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2400     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2401
2402     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2403     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2404     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2405     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2406     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2407
2408     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2409     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2410     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2411     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2412     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2413
2414     /* Tests for Lock() */
2415
2416     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2417     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2418     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2419     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2420     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2421     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2422     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2423     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2424     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2425
2426     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2427     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2428     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2429     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2430     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2431     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2432     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2433     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2434     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2435
2436     desc.desc2.dwSize = 0;
2437     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2438     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2439     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2440     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2441     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2442     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2443
2444     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2445     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2446     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2447     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2448     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2449     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2450     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2451
2452     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2453     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2454     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2455     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2456     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2457     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2458     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2459
2460     IDirectDrawSurface7_Release(surface7);
2461     IDirectDrawSurface_Release(surface1);
2462 }
2463
2464 START_TEST(dsurface)
2465 {
2466     if (!CreateDirectDraw())
2467         return;
2468     MipMapCreationTest();
2469     SrcColorKey32BlitTest();
2470     QueryInterface();
2471     GetDDInterface_1();
2472     GetDDInterface_2();
2473     GetDDInterface_4();
2474     GetDDInterface_7();
2475     EnumTest();
2476     AttachmentTest();
2477     AttachmentTest7();
2478     CubeMapTest();
2479     test_lockrect_invalid();
2480     CompressedTest();
2481     SizeTest();
2482     PrivateDataTest();
2483     BltParamTest();
2484     StructSizeTest();
2485     ReleaseDirectDraw();
2486 }