ddraw/tests: Properly release no longer used interfaces.
[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  * Copyright (C) 2008 Alexander Dorofeyev
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 #define COBJMACROS
25
26 #include <assert.h>
27 #include "wine/test.h"
28 #include "wine/exception.h"
29 #include "ddraw.h"
30 #include "d3d.h"
31 #include "unknwn.h"
32
33 static LPDIRECTDRAW lpDD = NULL;
34 static DDCAPS ddcaps;
35
36 static BOOL CreateDirectDraw(void)
37 {
38     HRESULT rc;
39
40     rc = DirectDrawCreate(NULL, &lpDD, NULL);
41     ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
42     if (!lpDD) {
43         trace("DirectDrawCreateEx() failed with an error %x\n", rc);
44         return FALSE;
45     }
46
47     rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
48     ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
49
50     return TRUE;
51 }
52
53
54 static void ReleaseDirectDraw(void)
55 {
56     if( lpDD != NULL )
57     {
58         IDirectDraw_Release(lpDD);
59         lpDD = NULL;
60     }
61 }
62
63 static void MipMapCreationTest(void)
64 {
65     LPDIRECTDRAWSURFACE lpDDSMipMapTest;
66     DDSURFACEDESC ddsd;
67     HRESULT rc;
68
69     /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
70        DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
71         requested mipmap levels. */
72     ddsd.dwSize = sizeof(ddsd);
73     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
74     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
75     U2(ddsd).dwMipMapCount = 3;
76     ddsd.dwWidth = 128;
77     ddsd.dwHeight = 32;
78     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
79     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
80     if (FAILED(rc))
81     {
82         skip("failed to create surface\n");
83         return;
84     }
85
86     /* Check the number of created mipmaps */
87     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
88     ddsd.dwSize = sizeof(ddsd);
89     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
90     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
91     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
92         "GetSurfaceDesc returned no mipmapcount.\n");
93     ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
94         U2(ddsd).dwMipMapCount);
95
96     /* Destroy the surface. */
97     IDirectDrawSurface_Release(lpDDSMipMapTest);
98
99
100     /* Second mipmap creation test: create a surface without a mipmap
101        count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
102        This creates a single mipmap level. */
103     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
104     ddsd.dwSize = sizeof(ddsd);
105     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
106     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
107     ddsd.dwWidth = 128;
108     ddsd.dwHeight = 32;
109     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
110     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
111     if (FAILED(rc))
112     {
113         skip("failed to create surface\n");
114         return;
115     }
116     /* Check the number of created mipmaps */
117     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
118     ddsd.dwSize = sizeof(ddsd);
119     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
120     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
121     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
122         "GetSurfaceDesc returned no mipmapcount.\n");
123     ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
124         U2(ddsd).dwMipMapCount);
125
126     /* Destroy the surface. */
127     IDirectDrawSurface_Release(lpDDSMipMapTest);
128
129
130     /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
131         DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
132        It's an undocumented features where a chain of mipmaps, starting from
133        he specified size and down to the smallest size, is automatically
134        created.
135        Anarchy Online needs this feature to work. */
136     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
137     ddsd.dwSize = sizeof(ddsd);
138     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
139     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
140     ddsd.dwWidth = 128;
141     ddsd.dwHeight = 32;
142     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
143     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
144     if (FAILED(rc))
145     {
146         skip("failed to create surface\n");
147         return;
148     }
149
150     /* Check the number of created mipmaps */
151     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
152     ddsd.dwSize = sizeof(ddsd);
153     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
154     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
155     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
156         "GetSurfaceDesc returned no mipmapcount.\n");
157     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
158         U2(ddsd).dwMipMapCount);
159
160     /* Destroy the surface. */
161     IDirectDrawSurface_Release(lpDDSMipMapTest);
162
163
164     /* Fourth mipmap creation test: same as above with a different texture
165        size.
166        The purpose is to verify that the number of generated mipmaps is
167        dependent on the smallest dimension. */
168     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
169     ddsd.dwSize = sizeof(ddsd);
170     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
171     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
172     ddsd.dwWidth = 32;
173     ddsd.dwHeight = 64;
174     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
175     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
176     if (FAILED(rc))
177     {
178         skip("failed to create surface\n");
179         return;
180     }
181
182     /* Check the number of created mipmaps */
183     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
184     ddsd.dwSize = sizeof(ddsd);
185     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
186     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
187     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
188         "GetSurfaceDesc returned no mipmapcount.\n");
189     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
190         U2(ddsd).dwMipMapCount);
191
192     /* Destroy the surface. */
193     IDirectDrawSurface_Release(lpDDSMipMapTest);
194
195
196     /* Fifth mipmap creation test: try to create a surface with
197        DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT,
198        where dwMipMapCount = 0. This should fail. */
199
200     ddsd.dwSize = sizeof(ddsd);
201     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
202     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
203     U2(ddsd).dwMipMapCount = 0;
204     ddsd.dwWidth = 128;
205     ddsd.dwHeight = 32;
206     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
207     ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc);
208
209     /* Destroy the surface. */
210     if( rc == DD_OK )
211         IDirectDrawSurface_Release(lpDDSMipMapTest);
212
213 }
214
215 static void SrcColorKey32BlitTest(void)
216 {
217     LPDIRECTDRAWSURFACE lpSrc;
218     LPDIRECTDRAWSURFACE lpDst;
219     DDSURFACEDESC ddsd, ddsd2, ddsd3;
220     DDCOLORKEY DDColorKey;
221     LPDWORD lpData;
222     HRESULT rc;
223     DDBLTFX fx;
224
225     ddsd2.dwSize = sizeof(ddsd2);
226     ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
227
228     ddsd.dwSize = sizeof(ddsd);
229     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
230     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
231     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
232     ddsd.dwWidth = 800;
233     ddsd.dwHeight = 600;
234     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
235     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
236     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
237     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
238     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
239     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
240     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
241     if (FAILED(rc))
242     {
243         skip("failed to create surface\n");
244         return;
245     }
246
247     ddsd.dwFlags |= DDSD_CKSRCBLT;
248     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
249     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
250     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
251     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
252     if (FAILED(rc))
253     {
254         skip("failed to create surface\n");
255         return;
256     }
257
258     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
259     ok(rc==DD_OK,"Lock returned: %x\n",rc);
260     lpData = ddsd2.lpSurface;
261     lpData[0] = 0xCCCCCCCC;
262     lpData[1] = 0xCCCCCCCC;
263     lpData[2] = 0xCCCCCCCC;
264     lpData[3] = 0xCCCCCCCC;
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 == ddsd3.lpSurface, "lpSurface from GetSurfaceDesc(%p) differs from the one returned by Lock(%p)\n", ddsd3.lpSurface, ddsd2.lpSurface);
272
273     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
274     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
275
276     memset(&ddsd3, 0, sizeof(ddsd3));
277     ddsd3.dwSize = sizeof(ddsd3);
278     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
279     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
280     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
281     ok(ddsd3.lpSurface == NULL, "lpSurface from GetSurfaceDesc(%p) is not NULL after unlock\n", ddsd3.lpSurface);
282
283     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
284     ok(rc==DD_OK,"Lock returned: %x\n",rc);
285     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
286     lpData = ddsd2.lpSurface;
287     lpData[0] = 0x77010203;
288     lpData[1] = 0x00010203;
289     lpData[2] = 0x77FF00FF;
290     lpData[3] = 0x00FF00FF;
291     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
292     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
293
294     IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
295
296     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
297     ok(rc==DD_OK,"Lock returned: %x\n",rc);
298     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
299     lpData = ddsd2.lpSurface;
300     /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
301      * color keying, but copy it to the destination surface. Others apply it for color keying, but
302      * do not copy it into the destination surface.
303      */
304     if(lpData[0]==0x00010203) {
305         trace("X channel was not copied into the destination surface\n");
306         ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
307            "Destination data after blitting is not correct\n");
308     } else {
309         ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
310            "Destination data after blitting is not correct\n");
311     }
312     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
313     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
314
315     /* Below we repeat the same test as above but now using BltFast instead of Blt. Before
316      * we can carry out the test we need to restore the color of the destination surface.
317      */
318     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
319     ok(rc==DD_OK,"Lock returned: %x\n",rc);
320     lpData = ddsd2.lpSurface;
321     lpData[0] = 0xCCCCCCCC;
322     lpData[1] = 0xCCCCCCCC;
323     lpData[2] = 0xCCCCCCCC;
324     lpData[3] = 0xCCCCCCCC;
325     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
326     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
327
328     IDirectDrawSurface_BltFast(lpDst, 0, 0, lpSrc, NULL, DDBLTFAST_SRCCOLORKEY);
329
330     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
331     ok(rc==DD_OK,"Lock returned: %x\n",rc);
332     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
333     lpData = ddsd2.lpSurface;
334     /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
335      * color keying, but copy it to the destination surface. Others apply it for color keying, but
336      * do not copy it into the destination surface.
337      */
338     if(lpData[0]==0x00010203) {
339         trace("X channel was not copied into the destination surface\n");
340         ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
341            "Destination data after blitting is not correct\n");
342     } else {
343         ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
344            "Destination data after blitting is not correct\n");
345     }
346     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
347     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
348
349     /* Also test SetColorKey */
350     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
351     ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
352        "GetColorKey does not return the colorkey used at surface creation\n");
353
354     DDColorKey.dwColorSpaceLowValue = 0x00FF00;
355     DDColorKey.dwColorSpaceHighValue = 0x00FF00;
356     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
357
358     DDColorKey.dwColorSpaceLowValue = 0;
359     DDColorKey.dwColorSpaceHighValue = 0;
360     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
361     ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
362        "GetColorKey does not return the colorkey set with SetColorKey\n");
363
364     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
365     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
366     IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
367     ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
368        "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
369
370     /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
371     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
372     DDColorKey.dwColorSpaceHighValue = 0x000000;
373     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
374
375     DDColorKey.dwColorSpaceLowValue = 0;
376     DDColorKey.dwColorSpaceHighValue = 0;
377     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
378     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
379        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
380
381     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
382     DDColorKey.dwColorSpaceHighValue = 0x000001;
383     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
384
385     DDColorKey.dwColorSpaceLowValue = 0;
386     DDColorKey.dwColorSpaceHighValue = 0;
387     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
388     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
389        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
390
391     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
392     DDColorKey.dwColorSpaceHighValue = 0x0000FE;
393     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
394
395     DDColorKey.dwColorSpaceLowValue = 0;
396     DDColorKey.dwColorSpaceHighValue = 0;
397     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
398     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
399        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
400
401     IDirectDrawSurface_Release(lpSrc);
402     IDirectDrawSurface_Release(lpDst);
403
404     /* start with a new set of surfaces to test the color keying parameters to blit */
405     memset(&ddsd, 0, sizeof(ddsd));
406     ddsd.dwSize = sizeof(ddsd);
407     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
408     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
409     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
410     ddsd.dwWidth = 800;
411     ddsd.dwHeight = 600;
412     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
413     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
414     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
415     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
416     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
417     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
418     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
419     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
420     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
421     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
422     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
423     if(FAILED(rc))
424     {
425         skip("Failed to create surface\n");
426         return;
427     }
428
429     /* start with a new set of surfaces to test the color keying parameters to blit */
430     memset(&ddsd, 0, sizeof(ddsd));
431     ddsd.dwSize = sizeof(ddsd);
432     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
433     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
434     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
435     ddsd.dwWidth = 800;
436     ddsd.dwHeight = 600;
437     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
438     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
439     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
440     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
441     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
442     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
443     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
444     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
445     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
446     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
447     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
448     if(FAILED(rc))
449     {
450         skip("Failed to create surface\n");
451         IDirectDrawSurface_Release(lpDst);
452         return;
453     }
454
455     memset(&fx, 0, sizeof(fx));
456     fx.dwSize = sizeof(fx);
457     fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
458     fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
459     fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
460     fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
461
462     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
463     ok(rc==DD_OK,"Lock returned: %x\n",rc);
464     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
465     lpData = ddsd2.lpSurface;
466     lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
467     lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
468     lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
469     lpData[3] = 0x0000FF00; /* Src color key in dst surface */
470     lpData[4] = 0x00001100; /* Src color key in ddbltfx */
471     lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
472     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
473     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
474
475     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
476     ok(rc==DD_OK,"Lock returned: %x\n",rc);
477     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
478     lpData = ddsd2.lpSurface;
479     lpData[0] = 0x55555555;
480     lpData[1] = 0x55555555;
481     lpData[2] = 0x55555555;
482     lpData[3] = 0x55555555;
483     lpData[4] = 0x55555555;
484     lpData[5] = 0x55555555;
485     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
486     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
487
488     /* Test a blit without keying */
489     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
490     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
491
492     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
493     ok(rc==DD_OK,"Lock returned: %x\n",rc);
494     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
495     lpData = ddsd2.lpSurface;
496     /* Should have copied src data unmodified to dst */
497     ok(lpData[0] == 0x000000FF &&
498        lpData[1] == 0x00000000 &&
499        lpData[2] == 0x00FF0000 &&
500        lpData[3] == 0x0000FF00 &&
501        lpData[4] == 0x00001100 &&
502        lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
503
504     lpData[0] = 0x55555555;
505     lpData[1] = 0x55555555;
506     lpData[2] = 0x55555555;
507     lpData[3] = 0x55555555;
508     lpData[4] = 0x55555555;
509     lpData[5] = 0x55555555;
510     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
511     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
512
513     /* Src key */
514     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
515     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
516
517     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
518     ok(rc==DD_OK,"Lock returned: %x\n",rc);
519     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
520     lpData = ddsd2.lpSurface;
521
522     ok(lpData[0] == 0x55555555 && /* Here the src key applied */
523        lpData[1] == 0x00000000 &&
524        lpData[2] == 0x00FF0000 &&
525        lpData[3] == 0x0000FF00 &&
526        lpData[4] == 0x00001100 &&
527        lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
528
529     lpData[0] = 0x55555555;
530     lpData[1] = 0x55555555;
531     lpData[2] = 0x55555555;
532     lpData[3] = 0x55555555;
533     lpData[4] = 0x55555555;
534     lpData[5] = 0x55555555;
535     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
536     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
537
538     /* Src override */
539     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
540     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
541
542     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
543     ok(rc==DD_OK,"Lock returned: %x\n",rc);
544     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
545     lpData = ddsd2.lpSurface;
546
547     ok(lpData[0] == 0x000000FF &&
548        lpData[1] == 0x00000000 &&
549        lpData[2] == 0x00FF0000 &&
550        lpData[3] == 0x0000FF00 &&
551        lpData[4] == 0x00001100 &&
552        lpData[5] == 0x55555555, /* Override key applies here */
553        "Surface data after src override key blit does not match\n");
554
555     lpData[0] = 0x55555555;
556     lpData[1] = 0x55555555;
557     lpData[2] = 0x55555555;
558     lpData[3] = 0x55555555;
559     lpData[4] = 0x55555555;
560     lpData[5] = 0x55555555;
561     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
562     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
563
564     /* Src override AND src key. That is not supposed to work */
565     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
566     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
567
568     /* Verify that the destination is unchanged */
569     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
570     ok(rc==DD_OK,"Lock returned: %x\n",rc);
571     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
572     lpData = ddsd2.lpSurface;
573
574     ok(lpData[0] == 0x55555555 &&
575        lpData[1] == 0x55555555 &&
576        lpData[2] == 0x55555555 &&
577        lpData[3] == 0x55555555 &&
578        lpData[4] == 0x55555555 &&
579        lpData[5] == 0x55555555, /* Override key applies here */
580        "Surface data after src key blit with override does not match\n");
581
582     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
583     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
584     lpData[2] = 0x00001100; /* Dest key in override */
585     lpData[3] = 0x00001100; /* Dest key in override */
586     lpData[4] = 0x00000000; /* Dest key in src surface */
587     lpData[5] = 0x00000000; /* Dest key in src surface */
588     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
589     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
590
591     /* Dest key blit */
592     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
593     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
594
595     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
596     ok(rc==DD_OK,"Lock returned: %x\n",rc);
597     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
598     lpData = ddsd2.lpSurface;
599
600     /* DirectDraw uses the dest blit key from the SOURCE surface ! */
601     ok(lpData[0] == 0x00ff0000 &&
602        lpData[1] == 0x00ff0000 &&
603        lpData[2] == 0x00001100 &&
604        lpData[3] == 0x00001100 &&
605        lpData[4] == 0x00001100 && /* Key applies here */
606        lpData[5] == 0x00110000,   /* Key applies here */
607        "Surface data after dest key blit does not match\n");
608
609     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
610     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
611     lpData[2] = 0x00001100; /* Dest key in override */
612     lpData[3] = 0x00001100; /* Dest key in override */
613     lpData[4] = 0x00000000; /* Dest key in src surface */
614     lpData[5] = 0x00000000; /* Dest key in src surface */
615     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
616     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
617
618     /* Dest override key blit */
619     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
620     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
621
622     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
623     ok(rc==DD_OK,"Lock returned: %x\n",rc);
624     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
625     lpData = ddsd2.lpSurface;
626
627     ok(lpData[0] == 0x00FF0000 &&
628        lpData[1] == 0x00FF0000 &&
629        lpData[2] == 0x00FF0000 && /* Key applies here */
630        lpData[3] == 0x0000FF00 && /* Key applies here */
631        lpData[4] == 0x00000000 &&
632        lpData[5] == 0x00000000,
633        "Surface data after dest key override blit does not match\n");
634
635     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
636     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
637     lpData[2] = 0x00001100; /* Dest key in override */
638     lpData[3] = 0x00001100; /* Dest key in override */
639     lpData[4] = 0x00000000; /* Dest key in src surface */
640     lpData[5] = 0x00000000; /* Dest key in src surface */
641     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
642     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
643
644     /* Dest override key blit. Supposed to fail too */
645     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
646     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
647
648     /* Check for unchanged data */
649     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
650     ok(rc==DD_OK,"Lock returned: %x\n",rc);
651     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
652     lpData = ddsd2.lpSurface;
653
654     ok(lpData[0] == 0x00FF0000 &&
655        lpData[1] == 0x00FF0000 &&
656        lpData[2] == 0x00001100 && /* Key applies here */
657        lpData[3] == 0x00001100 && /* Key applies here */
658        lpData[4] == 0x00000000 &&
659        lpData[5] == 0x00000000,
660        "Surface data with dest key and dest override does not match\n");
661
662     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
663     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
664     lpData[2] = 0x00001100; /* Dest key in override */
665     lpData[3] = 0x00001100; /* Dest key in override */
666     lpData[4] = 0x00000000; /* Dest key in src surface */
667     lpData[5] = 0x00000000; /* Dest key in src surface */
668     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
669     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
670
671     /* Modify the source data a bit to give some more conclusive results */
672     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
673     ok(rc==DD_OK,"Lock returned: %x\n",rc);
674     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
675     lpData = ddsd2.lpSurface;
676     lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
677     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
678     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
679
680     /* Source and destination key */
681     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
682     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
683
684     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
685     ok(rc==DD_OK,"Lock returned: %x\n",rc);
686     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
687     lpData = ddsd2.lpSurface;
688
689     ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
690        lpData[1] == 0x00FF0000 && /* Masked by Destination key */
691        lpData[2] == 0x00001100 && /* Masked by Destination key */
692        lpData[3] == 0x00001100 && /* Masked by Destination key */
693        lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
694        lpData[5] == 0x00000000,   /* Allowed by dst key, but masked by source key */
695        "Surface data with src key and dest key blit does not match\n");
696
697     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
698     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
699     lpData[2] = 0x00001100; /* Dest key in override */
700     lpData[3] = 0x00001100; /* Dest key in override */
701     lpData[4] = 0x00000000; /* Dest key in src surface */
702     lpData[5] = 0x00000000; /* Dest key in src surface */
703     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
704     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
705
706     /* Override keys without ddbltfx parameter fail */
707     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
708     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
709     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
710     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
711
712     /* Try blitting without keys in the source surface*/
713     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
714     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
715     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
716     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
717
718     /* That fails now. Do not bother to check that the data is unmodified */
719     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
720     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
721
722     /* Dest key blit still works. Which key is used this time??? */
723     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
724     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
725
726     /* With correctly passed override keys no key in the surface is needed.
727      * Again, the result was checked before, no need to do that again
728      */
729     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
730     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
731     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
732     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
733
734     IDirectDrawSurface_Release(lpSrc);
735     IDirectDrawSurface_Release(lpDst);
736 }
737
738 static void QueryInterface(void)
739 {
740     LPDIRECTDRAWSURFACE dsurface;
741     DDSURFACEDESC surface;
742     LPVOID object;
743     HRESULT ret;
744
745     /* Create a surface */
746     ZeroMemory(&surface, sizeof(surface));
747     surface.dwSize = sizeof(surface);
748     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
749     surface.dwHeight = 10;
750     surface.dwWidth = 10;
751     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
752     if(ret != DD_OK)
753     {
754         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
755         return;
756     }
757
758     /* Call IUnknown::QueryInterface */
759     ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
760     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
761
762     IDirectDrawSurface_Release(dsurface);
763 }
764
765 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
766  * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
767  * partially in the refcount test
768  */
769
770 static ULONG getref(IUnknown *iface)
771 {
772     IUnknown_AddRef(iface);
773     return IUnknown_Release(iface);
774 }
775
776 static void GetDDInterface_1(void)
777 {
778     LPDIRECTDRAWSURFACE dsurface;
779     LPDIRECTDRAWSURFACE2 dsurface2;
780     DDSURFACEDESC surface;
781     HRESULT ret;
782     IDirectDraw2 *dd2;
783     IDirectDraw4 *dd4;
784     IDirectDraw7 *dd7;
785     ULONG ref1, ref2, ref4, ref7;
786     void *dd;
787
788     /* Create a surface */
789     ZeroMemory(&surface, sizeof(surface));
790     surface.dwSize = sizeof(surface);
791     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
792     surface.dwHeight = 10;
793     surface.dwWidth = 10;
794     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
795     if(ret != DD_OK)
796     {
797         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
798         return;
799     }
800     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
801     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
802     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
803     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
804     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
805     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
806     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
807     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
808
809     ref1 = getref((IUnknown *) lpDD);
810     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
811     ref2 = getref((IUnknown *) dd2);
812     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
813     ref4 = getref((IUnknown *) dd4);
814     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
815     ref7 = getref((IUnknown *) dd7);
816     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
817
818
819     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
820     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
821     ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
822     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
823     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
824     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
825
826     ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
827     IUnknown_Release((IUnknown *) dd);
828
829     /* try a NULL pointer */
830     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
831     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
832
833     IDirectDraw_Release(dd2);
834     IDirectDraw_Release(dd4);
835     IDirectDraw_Release(dd7);
836     IDirectDrawSurface2_Release(dsurface2);
837     IDirectDrawSurface_Release(dsurface);
838 }
839
840 static void GetDDInterface_2(void)
841 {
842     LPDIRECTDRAWSURFACE dsurface;
843     LPDIRECTDRAWSURFACE2 dsurface2;
844     DDSURFACEDESC surface;
845     HRESULT ret;
846     IDirectDraw2 *dd2;
847     IDirectDraw4 *dd4;
848     IDirectDraw7 *dd7;
849     ULONG ref1, ref2, ref4, ref7;
850     void *dd;
851
852     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
853     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
854     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
855     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
856     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
857     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
858
859     /* Create a surface */
860     ZeroMemory(&surface, sizeof(surface));
861     surface.dwSize = sizeof(surface);
862     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
863     surface.dwHeight = 10;
864     surface.dwWidth = 10;
865     ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
866     if(ret != DD_OK)
867     {
868         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
869         return;
870     }
871     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
872     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
873
874     ref1 = getref((IUnknown *) lpDD);
875     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
876     ref2 = getref((IUnknown *) dd2);
877     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
878     ref4 = getref((IUnknown *) dd4);
879     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
880     ref7 = getref((IUnknown *) dd7);
881     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
882
883
884     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
885     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
886     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
887     ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
888     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
889     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
890
891     ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
892     IUnknown_Release((IUnknown *) dd);
893
894     IDirectDraw_Release(dd2);
895     IDirectDraw_Release(dd4);
896     IDirectDraw_Release(dd7);
897     IDirectDrawSurface2_Release(dsurface2);
898     IDirectDrawSurface_Release(dsurface);
899 }
900
901 static void GetDDInterface_4(void)
902 {
903     LPDIRECTDRAWSURFACE2 dsurface2;
904     LPDIRECTDRAWSURFACE4 dsurface4;
905     DDSURFACEDESC2 surface;
906     HRESULT ret;
907     IDirectDraw2 *dd2;
908     IDirectDraw4 *dd4;
909     IDirectDraw7 *dd7;
910     ULONG ref1, ref2, ref4, ref7;
911     void *dd;
912
913     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
914     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
915     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
916     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
917     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
918     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
919
920     /* Create a surface */
921     ZeroMemory(&surface, sizeof(surface));
922     surface.dwSize = sizeof(surface);
923     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
924     surface.dwHeight = 10;
925     surface.dwWidth = 10;
926     ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
927     if(ret != DD_OK)
928     {
929         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
930         return;
931     }
932     ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
933     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
934
935     ref1 = getref((IUnknown *) lpDD);
936     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
937     ref2 = getref((IUnknown *) dd2);
938     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
939     ref4 = getref((IUnknown *) dd4);
940     ok(ref4 == 2, "IDirectDraw4 refcount is %d\n", ref4);
941     ref7 = getref((IUnknown *) dd7);
942     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
943
944     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
945     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
946     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
947     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
948     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
949     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
950
951     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
952     IUnknown_Release((IUnknown *) dd);
953
954     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
955     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
956     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
957     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
958     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
959     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
960     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
961
962     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
963     IUnknown_Release((IUnknown *) dd);
964
965     IDirectDraw_Release(dd2);
966     IDirectDraw_Release(dd4);
967     IDirectDraw_Release(dd7);
968     IDirectDrawSurface4_Release(dsurface4);
969     IDirectDrawSurface2_Release(dsurface2);
970 }
971
972 static void GetDDInterface_7(void)
973 {
974     LPDIRECTDRAWSURFACE4 dsurface4;
975     LPDIRECTDRAWSURFACE7 dsurface7;
976     DDSURFACEDESC2 surface;
977     HRESULT ret;
978     IDirectDraw2 *dd2;
979     IDirectDraw4 *dd4;
980     IDirectDraw7 *dd7;
981     ULONG ref1, ref2, ref4, ref7;
982     void *dd;
983
984     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
985     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
986     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
987     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
988     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
989     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
990
991     /* Create a surface */
992     ZeroMemory(&surface, sizeof(surface));
993     surface.dwSize = sizeof(surface);
994     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
995     surface.dwHeight = 10;
996     surface.dwWidth = 10;
997     ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
998     if(ret != DD_OK)
999     {
1000         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
1001         return;
1002     }
1003     ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
1004     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
1005
1006     ref1 = getref((IUnknown *) lpDD);
1007     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
1008     ref2 = getref((IUnknown *) dd2);
1009     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
1010     ref4 = getref((IUnknown *) dd4);
1011     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
1012     ref7 = getref((IUnknown *) dd7);
1013     ok(ref7 == 2, "IDirectDraw7 refcount is %d\n", ref7);
1014
1015     ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
1016     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1017     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1018     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1019     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1020     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1021
1022     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1023     IUnknown_Release((IUnknown *) dd);
1024
1025     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
1026     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
1027     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1028     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1029     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1030     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1031     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1032
1033     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1034     IUnknown_Release((IUnknown *) dd);
1035
1036     IDirectDraw_Release(dd2);
1037     IDirectDraw_Release(dd4);
1038     IDirectDraw_Release(dd7);
1039     IDirectDrawSurface4_Release(dsurface4);
1040     IDirectDrawSurface7_Release(dsurface7);
1041 }
1042
1043 static ULONG getRefcount(IUnknown *iface)
1044 {
1045     IUnknown_AddRef(iface);
1046     return IUnknown_Release(iface);
1047 }
1048
1049 static void IFaceRefCount(void)
1050 {
1051     LPDIRECTDRAWSURFACE surf;
1052     DDSURFACEDESC surface;
1053     HRESULT ret;
1054     IDirectDrawSurface2 *surf2;
1055     IDirectDrawSurface2 *surf2a;
1056     IDirectDrawSurface3 *surf3;
1057     IDirectDrawSurface4 *surf4;
1058     IDirectDrawSurface7 *surf7a;
1059     IDirectDrawSurface7 *surf7b;
1060     IDirect3DTexture* tex;
1061     IDirect3DTexture2* tex2;
1062     IDirectDrawGammaControl* gamma;
1063     ULONG ref;
1064
1065     /* Create a surface */
1066     ZeroMemory(&surface, sizeof(surface));
1067     surface.dwSize = sizeof(surface);
1068     surface.dwFlags = DDSD_CAPS;
1069     surface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1070     ret = IDirectDraw_CreateSurface(lpDD, &surface, &surf, NULL);
1071
1072     if (ret != DD_OK)
1073     {
1074         ok(FALSE, "Could not create surface, skipping test\n");
1075         return;
1076     }
1077
1078     ref = getRefcount((IUnknown *) surf);
1079     ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1080
1081     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
1082     ref = getRefcount((IUnknown *) surf);
1083     ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1084     ref = getRefcount((IUnknown *) surf2);
1085     ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
1086
1087     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2a);
1088     ref = getRefcount((IUnknown *) surf2);
1089     ok(ref == 2, "Refcount is %u, expected 2\n", ref);   /* Surf2's refcount should be 2 now, but surf should be 1 */
1090     ref = getRefcount((IUnknown *) surf);
1091     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1092
1093     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface3, (void **) &surf3);
1094     ref = getRefcount((IUnknown *) surf3);
1095     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1096
1097     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
1098     ref = getRefcount((IUnknown *) surf4);
1099     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1100
1101     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7a);
1102     ref = getRefcount((IUnknown *) surf7a);
1103     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1104
1105     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7b);
1106     ref = getRefcount((IUnknown *) surf7b);
1107     ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1108
1109     /* IDirect3DTexture interface (unlike the others) alters the original IDirectDrawSurface ref count */
1110     ret = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture, (void **) &tex);
1111     if (SUCCEEDED(ret))
1112     {
1113         ref = getRefcount((IUnknown *) tex);
1114         ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1115         ref = getRefcount((IUnknown *) surf);
1116         ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1117
1118         IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture2, (void **) &tex2);
1119         ref = getRefcount((IUnknown *) tex);
1120         ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1121         ref = getRefcount((IUnknown *) tex2);
1122         ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1123         ref = getRefcount((IUnknown *) surf);
1124         ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1125
1126         IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawGammaControl, (void **) &gamma);
1127         ref = getRefcount((IUnknown *) gamma);
1128         ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1129
1130         ref = IDirect3DTexture2_Release(tex2); /* Release the texture */
1131         ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1132         ref = getRefcount((IUnknown *) surf);
1133         ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1134
1135         ref = IDirect3DTexture_Release(tex); /* Release the texture */
1136         ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1137         ref = getRefcount((IUnknown *) surf);
1138         ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1139
1140         ref = IDirectDrawGammaControl_Release(gamma); /* Release the gamma control */
1141         ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1142     }
1143
1144     ref = IDirectDrawSurface2_Release(surf2); /* Release one of the 2 surf2 interfaces */
1145     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1146
1147     ref = IDirectDrawSurface2_Release(surf2a); /* Release the other */
1148     ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1149
1150     ref = IDirectDrawSurface3_Release(surf3);
1151     ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1152
1153     ref = IDirectDrawSurface4_Release(surf4);
1154     ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1155
1156     ref = IDirectDrawSurface7_Release(surf7a);
1157     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1158
1159     ref = IDirectDrawSurface7_Release(surf7b);
1160     ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1161
1162     ref = IDirectDrawSurface_Release(surf);
1163     ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1164 }
1165
1166 #define MAXEXPECTED 8  /* Can match up to 8 expected surfaces */
1167 struct enumstruct
1168 {
1169     IDirectDrawSurface *expected[MAXEXPECTED];
1170     UINT count;
1171 };
1172
1173 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
1174 {
1175     int i;
1176     BOOL found = FALSE;
1177
1178     for(i = 0; i < MAXEXPECTED; i++)
1179     {
1180         if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
1181     }
1182
1183     ok(found, "Unexpected surface %p enumerated\n", surf);
1184     ((struct enumstruct *)ctx)->count++;
1185     IDirectDrawSurface_Release(surf);
1186     return DDENUMRET_OK;
1187 }
1188
1189 static void EnumTest(void)
1190 {
1191     HRESULT rc;
1192     DDSURFACEDESC ddsd;
1193     IDirectDrawSurface *surface;
1194     struct enumstruct ctx;
1195
1196     ddsd.dwSize = sizeof(ddsd);
1197     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1198     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1199     U2(ddsd).dwMipMapCount = 3;
1200     ddsd.dwWidth = 32;
1201     ddsd.dwHeight = 32;
1202     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
1203     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
1204
1205     memset(&ctx, 0, sizeof(ctx));
1206     ctx.expected[0] = surface;
1207     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1208     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1209     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1210     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1211     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1212     ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1213     ok(!ctx.expected[3], "expected NULL pointer\n");
1214     ctx.count = 0;
1215
1216     rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, &ctx, enumCB);
1217     ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1218     ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1219
1220     IDirectDrawSurface_Release(ctx.expected[2]);
1221     IDirectDrawSurface_Release(ctx.expected[1]);
1222     IDirectDrawSurface_Release(surface);
1223 }
1224
1225 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1226 {
1227     UINT *num = context;
1228     (*num)++;
1229     IDirectDrawSurface_Release(surface);
1230     return DDENUMRET_OK;
1231 }
1232
1233 static void AttachmentTest7(void)
1234 {
1235     HRESULT hr;
1236     IDirectDraw7 *dd7;
1237     IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1238     DDSURFACEDESC2 ddsd, ddsd2;
1239     UINT num;
1240     DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}, caps2 = {DDSCAPS_BACKBUFFER,0,0,0};
1241     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1242
1243     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1244     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1245
1246     memset(&ddsd, 0, sizeof(ddsd));
1247     ddsd.dwSize = sizeof(ddsd);
1248     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1249     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1250     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1251     ddsd.dwWidth = 128;
1252     ddsd.dwHeight = 128;
1253     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1254     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1255
1256     /* ROOT */
1257     num = 0;
1258     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1259     ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1260     /* DONE ROOT */
1261
1262     /* LEVEL 1 */
1263     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1264     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1265     num = 0;
1266     IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1267     ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1268     /* DONE LEVEL 1 */
1269
1270     /* LEVEL 2 */
1271     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1272     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1273     IDirectDrawSurface7_Release(surface2);
1274     num = 0;
1275     IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1276     ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1277     /* Done level 2 */
1278     /* Mip level 3 is still needed */
1279     hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
1280     ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
1281     ok(!surface4, "expected NULL pointer\n");
1282
1283     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1284     memset(&ddsd, 0, sizeof(ddsd));
1285     ddsd.dwSize = sizeof(ddsd);
1286     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1287     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1288     ddsd.dwWidth = 16;
1289     ddsd.dwHeight = 16;
1290     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1291     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1292
1293     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1294     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1295     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1296     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1297     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1298     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1299     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1300     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1301
1302     IDirectDrawSurface7_Release(surface2);
1303
1304     memset(&ddsd, 0, sizeof(ddsd));
1305     ddsd.dwSize = sizeof(ddsd);
1306     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1307     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1308     ddsd.dwWidth = 16;
1309     ddsd.dwHeight = 16;
1310     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1311     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1312
1313     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1314     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1315     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1316     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1317     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1318     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1319     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1320     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1321
1322     IDirectDrawSurface7_Release(surface3);
1323     IDirectDrawSurface7_Release(surface2);
1324     IDirectDrawSurface7_Release(surface1);
1325
1326     hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1327     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1328
1329     memset(&ddsd, 0, sizeof(ddsd));
1330     ddsd.dwSize = sizeof(ddsd);
1331     ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1332     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1333     ddsd.dwBackBufferCount = 2;
1334     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1335     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1336
1337     /* backbuffer surfaces must not have dwBackBufferCount set */
1338     ddsd2.dwSize = sizeof(ddsd2);
1339     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps2, &surface2);
1340     ok(hr==DD_OK,"GetAttachedSurface returned: %x\n", hr);
1341     hr = IDirectDrawSurface7_GetSurfaceDesc(surface2, &ddsd2);
1342     ok(hr==DD_OK,"GetSurfaceDesc returned: %x\n", hr);
1343     ok(ddsd2.dwBackBufferCount==0,"backbuffer surface has dwBackBufferCount==%u\n", ddsd2.dwBackBufferCount);
1344
1345     num = 0;
1346     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1347     ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1348     IDirectDrawSurface7_Release(surface1);
1349
1350     /* Those are some invalid descriptions, no need to test attachments with them */
1351     memset(&ddsd, 0, sizeof(ddsd));
1352     ddsd.dwSize = sizeof(ddsd);
1353     ddsd.dwFlags = DDSD_CAPS;
1354     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1355     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1356     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1357     memset(&ddsd, 0, sizeof(ddsd));
1358     ddsd.dwSize = sizeof(ddsd);
1359     ddsd.dwFlags = DDSD_CAPS;
1360     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1361     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1362     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1363
1364     /* Try a single primary and two offscreen plain surfaces */
1365     memset(&ddsd, 0, sizeof(ddsd));
1366     ddsd.dwSize = sizeof(ddsd);
1367     ddsd.dwFlags = DDSD_CAPS;
1368     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1369     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1370     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1371
1372     memset(&ddsd, 0, sizeof(ddsd));
1373     ddsd.dwSize = sizeof(ddsd);
1374     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1375     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1376     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1377     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1378     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1379     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1380
1381     memset(&ddsd, 0, sizeof(ddsd));
1382     ddsd.dwSize = sizeof(ddsd);
1383     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1384     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1385     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1386     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1387     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1388     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1389
1390     /* This one has a different size */
1391     memset(&ddsd, 0, sizeof(ddsd));
1392     ddsd.dwSize = sizeof(ddsd);
1393     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1394     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1395     ddsd.dwWidth = 128;
1396     ddsd.dwHeight = 128;
1397     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1398     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1399
1400     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1401     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1402     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1403     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1404     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1405     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1406     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1407     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1408     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1409     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1410
1411     IDirectDrawSurface7_Release(surface4);
1412     IDirectDrawSurface7_Release(surface3);
1413     IDirectDrawSurface7_Release(surface2);
1414     IDirectDrawSurface7_Release(surface1);
1415
1416     hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1417     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1418     IDirectDraw7_Release(dd7);
1419 }
1420
1421 static void AttachmentTest(void)
1422 {
1423     HRESULT hr;
1424     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1425     DDSURFACEDESC ddsd;
1426     DDSCAPS caps = {DDSCAPS_TEXTURE};
1427     BOOL refrast = FALSE;
1428     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1429
1430     memset(&ddsd, 0, sizeof(ddsd));
1431     ddsd.dwSize = sizeof(ddsd);
1432     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1433     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1434     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1435     ddsd.dwWidth = 128;
1436     ddsd.dwHeight = 128;
1437     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1438     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1439
1440     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1441     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1442     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1443     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1444
1445     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1446     memset(&ddsd, 0, sizeof(ddsd));
1447     ddsd.dwSize = sizeof(ddsd);
1448     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1449     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1450     ddsd.dwWidth = 16;
1451     ddsd.dwHeight = 16;
1452     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1453     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1454
1455     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1456     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1457     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1458     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1459     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1460     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1461     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1462     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1463     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1464     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1465     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1466     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1467
1468     IDirectDrawSurface7_Release(surface4);
1469
1470     memset(&ddsd, 0, sizeof(ddsd));
1471     ddsd.dwSize = sizeof(ddsd);
1472     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1473     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1474     ddsd.dwWidth = 16;
1475     ddsd.dwHeight = 16;
1476     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1477     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1478
1479     if (SUCCEEDED(IDirectDrawSurface7_AddAttachedSurface(surface1, surface4)))
1480     {
1481         IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1482         refrast = TRUE;
1483     }
1484
1485     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1486     if (refrast)
1487         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1488     else
1489         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1490     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1491
1492     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);  /* Succeeds on refrast */
1493     if (refrast)
1494         ok(hr == S_OK, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1495     else
1496         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1497     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1498
1499     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);  /* Succeeds on refrast */
1500     if (refrast)
1501         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1502     else
1503         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1504     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1505
1506     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1507     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1508     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1509
1510     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);  /* Succeeds on refrast */
1511     if (refrast)
1512         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1513     else
1514         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1515     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1516
1517     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1518     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1519     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1520
1521     IDirectDrawSurface7_Release(surface4);
1522     IDirectDrawSurface7_Release(surface3);
1523     IDirectDrawSurface7_Release(surface2);
1524     IDirectDrawSurface7_Release(surface1);
1525
1526     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1527     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1528
1529     /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1530     memset(&ddsd, 0, sizeof(ddsd));
1531     ddsd.dwSize = sizeof(ddsd);
1532     ddsd.dwFlags = DDSD_CAPS;
1533     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1534     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1535     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1536     /* This old ddraw version happily creates explicit front buffers */
1537     memset(&ddsd, 0, sizeof(ddsd));
1538     ddsd.dwSize = sizeof(ddsd);
1539     ddsd.dwFlags = DDSD_CAPS;
1540     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1541     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1542     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1543     IDirectDrawSurface_Release(surface1);
1544
1545     /* Try a single primary and two offscreen plain surfaces */
1546     memset(&ddsd, 0, sizeof(ddsd));
1547     ddsd.dwSize = sizeof(ddsd);
1548     ddsd.dwFlags = DDSD_CAPS;
1549     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1550     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1551     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1552
1553     memset(&ddsd, 0, sizeof(ddsd));
1554     ddsd.dwSize = sizeof(ddsd);
1555     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1556     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1557     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1558     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1559     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1560     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1561
1562     memset(&ddsd, 0, sizeof(ddsd));
1563     ddsd.dwSize = sizeof(ddsd);
1564     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1565     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1566     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1567     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1568     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1569     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1570
1571     /* This one has a different size */
1572     memset(&ddsd, 0, sizeof(ddsd));
1573     ddsd.dwSize = sizeof(ddsd);
1574     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1575     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1576     ddsd.dwWidth = 128;
1577     ddsd.dwHeight = 128;
1578     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1579     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1580
1581     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1582     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1583        "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1584     if(SUCCEEDED(hr))
1585     {
1586         /* Try the reverse without detaching first */
1587         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1588         ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1589         hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1590         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1591     }
1592     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1593     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1594        "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1595     if(SUCCEEDED(hr))
1596     {
1597         /* Try to detach reversed */
1598         hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1599         ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1600         /* Now the proper detach */
1601         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1602         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1603     }
1604     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1605     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1606        "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1607     if(SUCCEEDED(hr))
1608     {
1609         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1610         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1611     }
1612     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1613     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1614     hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1615     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1616
1617     IDirectDrawSurface_Release(surface4);
1618     IDirectDrawSurface_Release(surface3);
1619     IDirectDrawSurface_Release(surface2);
1620     IDirectDrawSurface_Release(surface1);
1621
1622     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1623     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1624
1625     DestroyWindow(window);
1626 }
1627
1628 struct compare
1629 {
1630     DWORD width, height;
1631     DWORD caps, caps2;
1632     UINT mips;
1633 };
1634
1635 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1636 {
1637     UINT *mips = context;
1638
1639     (*mips)++;
1640     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1641                                              context,
1642                                              CubeTestLvl2Enum);
1643
1644     return DDENUMRET_OK;
1645 }
1646
1647 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1648 {
1649     UINT mips = 0;
1650     UINT *num = context;
1651     static const struct compare expected[] =
1652     {
1653         {
1654             128, 128,
1655             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1656             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1657             7
1658         },
1659         {
1660             128, 128,
1661             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1662             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1663             7
1664         },
1665         {
1666             128, 128,
1667             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1668             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1669             7
1670         },
1671         {
1672             128, 128,
1673             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1674             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1675             7
1676         },
1677         {
1678             128, 128,
1679             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1680             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1681             7
1682         },
1683         {
1684             64, 64, /* This is the first mipmap */
1685             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1686             DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1687             6
1688         },
1689     };
1690
1691     mips = 0;
1692     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1693                                              &mips,
1694                                              CubeTestLvl2Enum);
1695
1696     ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1697     ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1698     ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1699     ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1700     ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1701
1702     (*num)++;
1703
1704     IDirectDrawSurface7_Release(surface);
1705
1706     return DDENUMRET_OK;
1707 }
1708
1709 static void CubeMapTest(void)
1710 {
1711     IDirectDraw7 *dd7 = NULL;
1712     IDirectDrawSurface7 *cubemap = NULL;
1713     DDSURFACEDESC2 ddsd;
1714     HRESULT hr;
1715     UINT num = 0;
1716     struct enumstruct ctx;
1717
1718     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1719     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1720     if (FAILED(hr)) goto err;
1721
1722     memset(&ddsd, 0, sizeof(ddsd));
1723     ddsd.dwSize = sizeof(ddsd);
1724     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1725     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1726     ddsd.dwWidth = 128;
1727     ddsd.dwHeight = 128;
1728     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1729     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1730
1731     /* D3DFMT_R5G6B5 */
1732     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1733     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1734     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1735     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1736     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1737
1738     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1739     if (FAILED(hr))
1740     {
1741         skip("Can't create cubemap surface\n");
1742         goto err;
1743     }
1744
1745     hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1746     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1747     ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1748        "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1749     ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1750        "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1751
1752     IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1753                                              &num,
1754                                              CubeTestLvl1Enum);
1755     ok(num == 6, "Surface has %d attachments\n", num);
1756     IDirectDrawSurface7_Release(cubemap);
1757
1758     /* What happens if I do not specify any faces? */
1759     memset(&ddsd, 0, sizeof(ddsd));
1760     ddsd.dwSize = sizeof(ddsd);
1761     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1762     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1763     ddsd.dwWidth = 128;
1764     ddsd.dwHeight = 128;
1765     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1766     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1767
1768     /* D3DFMT_R5G6B5 */
1769     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1770     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1771     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1772     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1773     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1774
1775     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1776     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1777
1778     /* Cube map faces without a cube map? */
1779     memset(&ddsd, 0, sizeof(ddsd));
1780     ddsd.dwSize = sizeof(ddsd);
1781     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1782     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1783     ddsd.dwWidth = 128;
1784     ddsd.dwHeight = 128;
1785     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1786     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1787
1788     /* D3DFMT_R5G6B5 */
1789     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1790     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1791     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1792     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1793     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1794
1795     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1796     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1797
1798     memset(&ddsd, 0, sizeof(ddsd));
1799     ddsd.dwSize = sizeof(ddsd);
1800     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1801     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1802     ddsd.dwWidth = 128;
1803     ddsd.dwHeight = 128;
1804     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1805     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1806
1807     /* D3DFMT_R5G6B5 */
1808     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1809     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1810     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1811     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1812     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1813
1814     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1815     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1816
1817     /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1818     memset(&ctx, 0, sizeof(ctx));
1819     memset(&ddsd, 0, sizeof(ddsd));
1820     ddsd.dwSize = sizeof(DDSURFACEDESC);
1821     hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1822     ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1823     ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1824
1825     err:
1826     if (dd7) IDirectDraw7_Release(dd7);
1827 }
1828
1829 static void test_lockrect_invalid(void)
1830 {
1831     unsigned int i, j;
1832
1833     RECT valid[] = {
1834         {60, 60, 68, 68},
1835         {60, 60, 60, 68},
1836         {60, 60, 68, 60},
1837         {120, 60, 128, 68},
1838         {60, 120, 68, 128},
1839     };
1840
1841     RECT invalid[] = {
1842         {68, 60, 60, 68},       /* left > right */
1843         {60, 68, 68, 60},       /* top > bottom */
1844         {-8, 60,  0, 68},       /* left < surface */
1845         {60, -8, 68,  0},       /* top < surface */
1846         {-16, 60, -8, 68},      /* right < surface */
1847         {60, -16, 68, -8},      /* bottom < surface */
1848         {60, 60, 136, 68},      /* right > surface */
1849         {60, 60, 68, 136},      /* bottom > surface */
1850         {136, 60, 144, 68},     /* left > surface */
1851         {60, 136, 68, 144},     /* top > surface */
1852     };
1853
1854     const DWORD dds_caps[] = {
1855         DDSCAPS_OFFSCREENPLAIN
1856     };
1857
1858     for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1859     {
1860         IDirectDrawSurface *surface = 0;
1861         DDSURFACEDESC surface_desc = {0};
1862         DDSURFACEDESC locked_desc = {0};
1863         HRESULT hr;
1864
1865         surface_desc.dwSize = sizeof(surface_desc);
1866         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1867         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1868         surface_desc.ddsCaps.dwCaps = dds_caps[j];
1869         surface_desc.dwWidth = 128;
1870         surface_desc.dwHeight = 128;
1871         surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1872         U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1873         U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1874         U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1875         U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1876
1877         hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1878         ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1879         if (FAILED(hr))
1880         {
1881             skip("failed to create surface\n");
1882             continue;
1883         }
1884
1885         for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1886         {
1887             RECT *rect = &valid[i];
1888
1889             memset(&locked_desc, 0, sizeof(locked_desc));
1890             locked_desc.dwSize = sizeof(locked_desc);
1891
1892             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1893             ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1894                     hr, rect->left, rect->top, rect->right, rect->bottom);
1895
1896             hr = IDirectDrawSurface_Unlock(surface, NULL);
1897             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1898         }
1899
1900         for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1901         {
1902             RECT *rect = &invalid[i];
1903
1904             memset(&locked_desc, 1, sizeof(locked_desc));
1905             locked_desc.dwSize = sizeof(locked_desc);
1906
1907             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1908             ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1909                     ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1910                     rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1911             ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1912         }
1913
1914         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1915         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1916         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1917         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1918         if(SUCCEEDED(hr)) {
1919             hr = IDirectDrawSurface_Unlock(surface, NULL);
1920             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1921         }
1922         hr = IDirectDrawSurface_Unlock(surface, NULL);
1923         ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1924
1925         memset(&locked_desc, 0, sizeof(locked_desc));
1926         locked_desc.dwSize = sizeof(locked_desc);
1927         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1928         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1929            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1930         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1931         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1932            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1933
1934         /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1935          * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1936          */
1937
1938         hr = IDirectDrawSurface_Unlock(surface, NULL);
1939         ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1940
1941         IDirectDrawSurface_Release(surface);
1942     }
1943 }
1944
1945 static void CompressedTest(void)
1946 {
1947     HRESULT hr;
1948     IDirectDrawSurface7 *surface;
1949     DDSURFACEDESC2 ddsd, ddsd2;
1950     IDirectDraw7 *dd7 = NULL;
1951     RECT r = { 0, 0, 128, 128 };
1952     RECT r2 = { 32, 32, 64, 64 };
1953
1954     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1955     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1956
1957     memset(&ddsd, 0, sizeof(ddsd));
1958     ddsd.dwSize = sizeof(ddsd);
1959     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1960     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1961     ddsd.dwWidth = 128;
1962     ddsd.dwHeight = 128;
1963     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1964     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1965     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1966
1967     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1968     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1969     if (FAILED(hr))
1970     {
1971         skip("failed to create surface\n");
1972         return;
1973     }
1974
1975     memset(&ddsd2, 0, sizeof(ddsd2));
1976     ddsd2.dwSize = sizeof(ddsd2);
1977     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1978     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1979     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1980
1981     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1982        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1983     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1984     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1985     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1986        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1987     ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1988     ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1989     IDirectDrawSurface7_Release(surface);
1990
1991     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1992     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1993     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1994     if (FAILED(hr))
1995     {
1996         skip("failed to create surface\n");
1997         return;
1998     }
1999
2000     memset(&ddsd2, 0, sizeof(ddsd2));
2001     ddsd2.dwSize = sizeof(ddsd2);
2002     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2003     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2004     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2005
2006     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2007        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2008     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2009     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2010     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2011        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2012     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2013     IDirectDrawSurface7_Release(surface);
2014
2015     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2016     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2017     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2018     if (FAILED(hr))
2019     {
2020         skip("failed to create surface\n");
2021         return;
2022     }
2023
2024     memset(&ddsd2, 0, sizeof(ddsd2));
2025     ddsd2.dwSize = sizeof(ddsd2);
2026     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2027     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2028     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2029
2030     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2031        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2032     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2033     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2034     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2035        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2036     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2037     ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2038
2039     memset(&ddsd2, 0, sizeof(ddsd2));
2040     ddsd2.dwSize = sizeof(ddsd2);
2041     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2042
2043     /* Show that the description is not changed when locking the surface. What is really interesting
2044      * about this is that DDSD_LPSURFACE isn't set.
2045      */
2046     hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2047     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2048
2049     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2050        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2051     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2052     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2053     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2054        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2055     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2056     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2057
2058     hr = IDirectDrawSurface7_Unlock(surface, NULL);
2059     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2060
2061     /* Now what about a locking rect?  */
2062     hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2063     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2064
2065     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2066        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2067     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2068     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2069     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2070        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2071     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2072     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2073
2074     hr = IDirectDrawSurface7_Unlock(surface, &r);
2075     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2076
2077     /* Now what about a different locking offset? */
2078     hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2079     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2080
2081     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2082        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2083     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2084     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2085     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2086        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2087     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2088     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2089
2090     hr = IDirectDrawSurface7_Unlock(surface, &r2);
2091     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2092     IDirectDrawSurface7_Release(surface);
2093
2094     /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
2095      * but seems to have a pitch instead.
2096      */
2097     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
2098     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2099
2100     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2101     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
2102        broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
2103
2104     /* Not supported everywhere */
2105     if(SUCCEEDED(hr))
2106     {
2107         memset(&ddsd2, 0, sizeof(ddsd2));
2108         ddsd2.dwSize = sizeof(ddsd2);
2109         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2110         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2111         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2112
2113         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2114         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2115         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2116         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2117         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2118         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2119         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2120         ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2121         IDirectDrawSurface7_Release(surface);
2122
2123         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2124         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2125         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2126
2127         memset(&ddsd2, 0, sizeof(ddsd2));
2128         ddsd2.dwSize = sizeof(ddsd2);
2129         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2130         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2131         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2132
2133         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2134         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2135         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2136         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2137         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2138         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2139         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2140         IDirectDrawSurface7_Release(surface);
2141
2142         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2143         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2144         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2145
2146         memset(&ddsd2, 0, sizeof(ddsd2));
2147         ddsd2.dwSize = sizeof(ddsd2);
2148         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2149         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2150         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2151
2152         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2153         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2154         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2155         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2156         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2157         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2158         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2159         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2160
2161         memset(&ddsd2, 0, sizeof(ddsd2));
2162         ddsd2.dwSize = sizeof(ddsd2);
2163         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2164
2165         /* Show that the description is not changed when locking the surface. What is really interesting
2166         * about this is that DDSD_LPSURFACE isn't set.
2167         */
2168         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2169         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2170
2171         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2172         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2173         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2174         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2175         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2176         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2177         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2178         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2179
2180         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2181         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2182
2183         /* Now what about a locking rect?  */
2184         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2185         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2186
2187         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2188         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2189         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2190         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2191         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2192         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2193         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2194         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2195
2196         hr = IDirectDrawSurface7_Unlock(surface, &r);
2197         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2198
2199         /* Now what about a different locking offset? */
2200         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2201         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2202
2203         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2204         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2205         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2206         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2207         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2208         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2209         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2210         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2211
2212         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2213         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2214
2215         IDirectDrawSurface7_Release(surface);
2216     }
2217     else
2218     {
2219         skip("Hardware DXTN textures not supported\n");
2220     }
2221
2222     /* What happens to managed textures? Interestingly, Windows reports them as being in system
2223      * memory. The linear size fits again.
2224      */
2225     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2226     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
2227     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2228
2229     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2230     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
2231
2232     /* Not supported everywhere */
2233     if(SUCCEEDED(hr))
2234     {
2235         memset(&ddsd2, 0, sizeof(ddsd2));
2236         ddsd2.dwSize = sizeof(ddsd2);
2237         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2238         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2239         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2240
2241         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2242         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2243         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2244         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2245         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2246         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2247         ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2248         ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2249         IDirectDrawSurface7_Release(surface);
2250
2251         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2252         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2253         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2254
2255         memset(&ddsd2, 0, sizeof(ddsd2));
2256         ddsd2.dwSize = sizeof(ddsd2);
2257         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2258         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2259         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2260
2261         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2262         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2263         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2264         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2265         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2266         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2267         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2268         IDirectDrawSurface7_Release(surface);
2269
2270         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2271         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2272         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2273
2274         memset(&ddsd2, 0, sizeof(ddsd2));
2275         ddsd2.dwSize = sizeof(ddsd2);
2276         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2277         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2278         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2279
2280         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2281         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2282         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2283         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2284         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2285         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2286         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2287         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2288
2289         memset(&ddsd2, 0, sizeof(ddsd2));
2290         ddsd2.dwSize = sizeof(ddsd2);
2291         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2292
2293         /* Show that the description is not changed when locking the surface. What is really interesting
2294         * about this is that DDSD_LPSURFACE isn't set.
2295         */
2296         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2297         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2298
2299         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2300         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2301         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2302         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2303         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2304         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2305         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2306         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2307
2308         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2309         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2310
2311         /* Now what about a locking rect?  */
2312         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2313         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2314
2315         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2316         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2317         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2318         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2319         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2320         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2321         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2322         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2323
2324         hr = IDirectDrawSurface7_Unlock(surface, &r);
2325         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2326
2327         /* Now what about a different locking offset? */
2328         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2329         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2330
2331         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2332         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2333         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2334         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2335         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2336         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2337         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2338         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2339
2340         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2341         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2342
2343         IDirectDrawSurface7_Release(surface);
2344     }
2345     else
2346     {
2347         skip("Hardware DXTN textures not supported\n");
2348     }
2349
2350     IDirectDraw7_Release(dd7);
2351 }
2352
2353 static void SizeTest(void)
2354 {
2355     LPDIRECTDRAWSURFACE dsurface = NULL;
2356     DDSURFACEDESC desc;
2357     HRESULT ret;
2358     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2359
2360     /* Create an offscreen surface surface without a size */
2361     ZeroMemory(&desc, sizeof(desc));
2362     desc.dwSize = sizeof(desc);
2363     desc.dwFlags = DDSD_CAPS;
2364     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2365     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2366     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2367     if(dsurface)
2368     {
2369         trace("Surface at %p\n", dsurface);
2370         IDirectDrawSurface_Release(dsurface);
2371         dsurface = NULL;
2372     }
2373
2374     /* Create an offscreen surface surface with only a width parameter */
2375     ZeroMemory(&desc, sizeof(desc));
2376     desc.dwSize = sizeof(desc);
2377     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2378     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2379     desc.dwWidth = 128;
2380     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2381     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without height info returned %08x\n", ret);
2382     if(dsurface)
2383     {
2384         IDirectDrawSurface_Release(dsurface);
2385         dsurface = NULL;
2386     }
2387
2388     /* Create an offscreen surface surface with only a height parameter */
2389     ZeroMemory(&desc, sizeof(desc));
2390     desc.dwSize = sizeof(desc);
2391     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2392     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2393     desc.dwHeight = 128;
2394     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2395     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2396     if(dsurface)
2397     {
2398         IDirectDrawSurface_Release(dsurface);
2399         dsurface = NULL;
2400     }
2401
2402     /* Test 0 height. */
2403     memset(&desc, 0, sizeof(desc));
2404     desc.dwSize = sizeof(desc);
2405     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2406     desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2407     desc.dwWidth = 1;
2408     desc.dwHeight = 0;
2409     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2410     ok(ret == DDERR_INVALIDPARAMS, "Creating a 0 height surface returned %#x, expected DDERR_INVALIDPARAMS.\n", ret);
2411     if (SUCCEEDED(ret)) IDirectDrawSurface_Release(dsurface);
2412     dsurface = NULL;
2413
2414     /* Test 0 width. */
2415     memset(&desc, 0, sizeof(desc));
2416     desc.dwSize = sizeof(desc);
2417     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2418     desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2419     desc.dwWidth = 0;
2420     desc.dwHeight = 1;
2421     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2422     ok(ret == DDERR_INVALIDPARAMS, "Creating a 0 width surface returned %#x, expected DDERR_INVALIDPARAMS.\n", ret);
2423     if (SUCCEEDED(ret)) IDirectDrawSurface_Release(dsurface);
2424     dsurface = NULL;
2425
2426     /* Sanity check */
2427     ZeroMemory(&desc, sizeof(desc));
2428     desc.dwSize = sizeof(desc);
2429     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2430     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2431     desc.dwHeight = 128;
2432     desc.dwWidth = 128;
2433     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2434     ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2435     if(dsurface)
2436     {
2437         IDirectDrawSurface_Release(dsurface);
2438         dsurface = NULL;
2439     }
2440
2441     /* Test a primary surface size */
2442     ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2443     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2444
2445     ZeroMemory(&desc, sizeof(desc));
2446     desc.dwSize = sizeof(desc);
2447     desc.dwFlags = DDSD_CAPS;
2448     desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2449     desc.dwHeight = 128; /* Keep them set to  check what happens */
2450     desc.dwWidth = 128; /* Keep them set to  check what happens */
2451     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2452     ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2453     if(dsurface)
2454     {
2455         ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2456         ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2457
2458         IDirectDrawSurface_Release(dsurface);
2459         dsurface = NULL;
2460
2461         ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2462         ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2463         ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2464         ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2465     }
2466     ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2467     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2468 }
2469
2470 static void PrivateDataTest(void)
2471 {
2472     HRESULT hr;
2473     IDirectDrawSurface7 *surface7 = NULL;
2474     IDirectDrawSurface *surface = NULL;
2475     DDSURFACEDESC desc;
2476     ULONG ref, ref2;
2477     IUnknown *ptr;
2478     DWORD size = sizeof(IUnknown *);
2479
2480     ZeroMemory(&desc, sizeof(desc));
2481     desc.dwSize = sizeof(desc);
2482     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2483     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2484     desc.dwHeight = 128;
2485     desc.dwWidth = 128;
2486     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2487     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2488     if(!surface)
2489     {
2490         return;
2491     }
2492     hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2493     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2494     if(!surface7)
2495     {
2496         IDirectDrawSurface_Release(surface);
2497         return;
2498     }
2499
2500     /* This fails */
2501     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2502     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2503     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2504     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2505     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2506     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2507
2508     ref = getref((IUnknown *) lpDD);
2509     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2510     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2511     ref2 = getref((IUnknown *) lpDD);
2512     ok(ref2 == ref + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2513     hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2514     ok(SUCCEEDED(hr), "IDirectDrawSurface7_FreePrivateData returned %#x.\n", hr);
2515     ref2 = getref((IUnknown *) lpDD);
2516     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2517
2518     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2519     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2520     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2521     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2522     ref2 = getref((IUnknown *) lpDD);
2523     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2524
2525     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2526     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2527     hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2528     ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2529     ref2 = getref((IUnknown *) lpDD);
2530     /* Object is NOT being addrefed */
2531     ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2532     ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2533
2534     IDirectDrawSurface_Release(surface);
2535     IDirectDrawSurface7_Release(surface7);
2536
2537     /* Destroying the surface frees the held reference */
2538     ref2 = getref((IUnknown *) lpDD);
2539     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2540 }
2541
2542 static void BltParamTest(void)
2543 {
2544     IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2545     DDSURFACEDESC desc;
2546     HRESULT hr;
2547     DDBLTFX BltFx;
2548     RECT valid = {10, 10, 20, 20};
2549     RECT invalid1 = {20, 10, 10, 20};
2550     RECT invalid2 = {20, 20, 20, 20};
2551     RECT invalid3 = {-1, -1, 20, 20};
2552     RECT invalid4 = {60, 60, 70, 70};
2553
2554     memset(&desc, 0, sizeof(desc));
2555     desc.dwSize = sizeof(desc);
2556     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2557     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2558     desc.dwHeight = 128;
2559     desc.dwWidth = 128;
2560     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2561     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2562
2563     desc.dwHeight = 64;
2564     desc.dwWidth = 64;
2565     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2566     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2567
2568     if(0)
2569     {
2570         /* This crashes */
2571         hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2572         ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2573     }
2574     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2575     ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2576     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2577     ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2578     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2579     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2580     hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2581     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2582     hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2583     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2584
2585     hr = IDirectDrawSurface_BltFast(surface1, -10, 0, surface2, NULL, 0);
2586     ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2587     hr = IDirectDrawSurface_BltFast(surface1, 0, -10, surface2, NULL, 0);
2588     ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2589     hr = IDirectDrawSurface_BltFast(surface2, 20, 20, surface1, &valid, 0);
2590     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle and offset returned %08x\n", hr);
2591
2592     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2593     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2594     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2595     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2596     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2597     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2598     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2599     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2600     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2601     ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2602
2603     /* Blt(non-fast) tests */
2604     memset(&BltFx, 0, sizeof(BltFx));
2605     BltFx.dwSize = sizeof(BltFx);
2606     U5(BltFx).dwFillColor = 0xaabbccdd;
2607
2608     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2609     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2610     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2611     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2612     hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2613     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2614     hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2615     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2616     hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2617     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2618     hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2619     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2620
2621     /* Valid on surface 1 */
2622     hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2623     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2624
2625     /* Works - stretched blit */
2626     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2627     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2628     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2629     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2630
2631     /* Invalid dest rects in sourced blits */
2632     hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2633     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2634     hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2635     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2636     hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2637     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2638     hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2639     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2640
2641     /* Invalid src rects */
2642     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2643     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2644     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2645     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2646     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2647     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2648     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2649     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2650
2651     IDirectDrawSurface_Release(surface1);
2652     IDirectDrawSurface_Release(surface2);
2653 }
2654
2655 static void PaletteTest(void)
2656 {
2657     HRESULT hr;
2658     LPDIRECTDRAWSURFACE lpSurf = NULL;
2659     DDSURFACEDESC ddsd;
2660     IDirectDrawPalette *palette = NULL;
2661     PALETTEENTRY Table[256];
2662     PALETTEENTRY palEntries[256];
2663     int i;
2664
2665     for(i=0; i<256; i++)
2666     {
2667         Table[i].peRed   = 0xff;
2668         Table[i].peGreen = 0;
2669         Table[i].peBlue  = 0;
2670         Table[i].peFlags = 0;
2671     }
2672
2673     /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2674     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2675     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2676     if (FAILED(hr)) goto err;
2677     /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2678     /  entry 0 and 255 should have been overwritten with black and white */
2679     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2680     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2681     if(hr == DD_OK)
2682     {
2683         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2684            "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2685            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2686         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2687            "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2688            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2689
2690         /* Entry 1-254 should contain red */
2691         for(i=1; i<255; i++)
2692             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2693                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2694                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2695     }
2696
2697     /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2698     /  now check we are able to update the entries afterwards. */
2699     IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2700     ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2701     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2702     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2703     if(hr == DD_OK)
2704     {
2705         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2706            "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2707            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2708         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2709            "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2710            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2711     }
2712     IDirectDrawPalette_Release(palette);
2713
2714     /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2715     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2716     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2717     if (FAILED(hr)) goto err;
2718
2719     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2720     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2721     if(hr == DD_OK)
2722     {
2723         /* All entries should contain red */
2724         for(i=0; i<256; i++)
2725             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2726                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2727                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2728     }
2729
2730     /* Try to set palette to a non-palettized surface */
2731     ddsd.dwSize = sizeof(ddsd);
2732     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2733     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2734     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2735     ddsd.dwWidth = 800;
2736     ddsd.dwHeight = 600;
2737     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2738     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2739     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2740     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2741     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2742     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2743     ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2744     if (FAILED(hr))
2745     {
2746         skip("failed to create surface\n");
2747         goto err;
2748     }
2749
2750     hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2751     ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2752
2753     IDirectDrawPalette_Release(palette);
2754     palette = NULL;
2755
2756     hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2757     ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2758
2759     err:
2760
2761     if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2762     if (palette) IDirectDrawPalette_Release(palette);
2763 }
2764
2765 static void StructSizeTest(void)
2766 {
2767     IDirectDrawSurface *surface1;
2768     IDirectDrawSurface7 *surface7;
2769     union {
2770         DDSURFACEDESC desc1;
2771         DDSURFACEDESC2 desc2;
2772         char blob[1024]; /* To get a bunch of writable memory */
2773     } desc;
2774     DDSURFACEDESC create;
2775     HRESULT hr;
2776
2777     memset(&desc, 0, sizeof(desc));
2778     memset(&create, 0, sizeof(create));
2779
2780     memset(&create, 0, sizeof(create));
2781     create.dwSize = sizeof(create);
2782     create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2783     create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2784     create.dwHeight = 128;
2785     create.dwWidth = 128;
2786     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2787     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2788     hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2789     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2790
2791     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2792     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2793     ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2794     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2795     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2796
2797     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2798     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2799     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2800     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2801     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2802
2803     desc.desc2.dwSize = 0;
2804     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2805     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2806     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2807     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2808
2809     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2810     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2811     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2812     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2813     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2814
2815     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2816     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2817     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2818     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2819     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2820
2821     /* Tests for Lock() */
2822
2823     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2824     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2825     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2826     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2827     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2828     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2829     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2830     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2831     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2832
2833     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2834     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2835     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2836     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2837     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2838     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2839     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2840     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2841     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2842
2843     desc.desc2.dwSize = 0;
2844     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2845     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2846     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2847     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2848     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2849     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2850
2851     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2852     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2853     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2854     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2855     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2856     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2857     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2858
2859     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2860     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2861     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2862     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2863     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2864     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2865     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2866
2867     IDirectDrawSurface7_Release(surface7);
2868     IDirectDrawSurface_Release(surface1);
2869 }
2870
2871 static void SurfaceCapsTest(void)
2872 {
2873     DDSURFACEDESC create;
2874     DDSURFACEDESC desc;
2875     HRESULT hr;
2876     IDirectDrawSurface *surface1 = NULL;
2877     DDSURFACEDESC2 create2, desc2;
2878     IDirectDrawSurface7 *surface7 = NULL;
2879     IDirectDraw7 *dd7 = NULL;
2880     DWORD create_caps[] = {
2881         DDSCAPS_OFFSCREENPLAIN,
2882         DDSCAPS_TEXTURE,
2883         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2884         0,
2885         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2886         DDSCAPS_PRIMARYSURFACE,
2887         DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY,
2888         DDSCAPS_3DDEVICE,
2889         DDSCAPS_ZBUFFER,
2890         DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN
2891     };
2892     DWORD expected_caps[] = {
2893         DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2894         DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2895         DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2896         DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2897         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2898         DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2899         DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE,
2900         DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2901         DDSCAPS_ZBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY,
2902         DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM
2903     };
2904     UINT i;
2905
2906     /* Tests various surface flags, what changes do they undergo during surface creation. Forsaken
2907      * engine expects texture surfaces without memory flag to get a video memory flag right after
2908      * creation. Currently, Wine adds DDSCAPS_FRONTBUFFER to primary surface, but native doesn't do this
2909      * for single buffered primaries. Because of this primary surface creation tests are todo_wine. No real
2910      * app is known so far to care about this. */
2911
2912     if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2913     {
2914         skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2915         return ;
2916     }
2917
2918     for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2919     {
2920         memset(&create, 0, sizeof(create));
2921         create.dwSize = sizeof(create);
2922         create.ddsCaps.dwCaps = create_caps[i];
2923         create.dwFlags = DDSD_CAPS;
2924
2925         if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2926         {
2927             create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2928             create.dwHeight = 128;
2929             create.dwWidth = 128;
2930         }
2931
2932         if (create.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2933         {
2934             create.dwFlags |= DDSD_PIXELFORMAT;
2935             create.ddpfPixelFormat.dwSize = sizeof(create.ddpfPixelFormat);
2936             create.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2937             U1(create.ddpfPixelFormat).dwZBufferBitDepth = 16;
2938             U3(create.ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2939         }
2940
2941         hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2942         ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2943
2944         if (SUCCEEDED(hr))
2945         {
2946             memset(&desc, 0, sizeof(desc));
2947             desc.dwSize = sizeof(DDSURFACEDESC);
2948             hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2949             ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2950
2951             if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2952                 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2953                     "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
2954                     desc.ddsCaps.dwCaps, expected_caps[i]);
2955             else
2956                 todo_wine ok(desc.ddsCaps.dwCaps == expected_caps[i],
2957                                 "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
2958                                 desc.ddsCaps.dwCaps, expected_caps[i]);
2959
2960             IDirectDrawSurface_Release(surface1);
2961         }
2962     }
2963
2964     /* Test for differences in ddraw 7 */
2965     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2966     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2967     if (FAILED(hr))
2968     {
2969         skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2970     }
2971     else
2972     {
2973         for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2974         {
2975             memset(&create2, 0, sizeof(create2));
2976             create2.dwSize = sizeof(create2);
2977             create2.ddsCaps.dwCaps = create_caps[i];
2978             create2.dwFlags = DDSD_CAPS;
2979
2980             if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2981             {
2982                 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2983                 create2.dwHeight = 128;
2984                 create2.dwWidth = 128;
2985             }
2986
2987             if (create2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
2988             {
2989                 create2.dwFlags |= DDSD_PIXELFORMAT;
2990                 U4(create2).ddpfPixelFormat.dwSize = sizeof(U4(create2).ddpfPixelFormat);
2991                 U4(create2).ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
2992                 U1(U4(create2).ddpfPixelFormat).dwZBufferBitDepth = 16;
2993                 U3(U4(create2).ddpfPixelFormat).dwZBitMask = 0x0000FFFF;
2994             }
2995
2996             hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2997             ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2998
2999             if (SUCCEEDED(hr))
3000             {
3001                 memset(&desc2, 0, sizeof(desc2));
3002                 desc2.dwSize = sizeof(DDSURFACEDESC2);
3003                 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
3004                 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
3005
3006                 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
3007                     ok(desc2.ddsCaps.dwCaps == expected_caps[i],
3008                         "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
3009                         desc2.ddsCaps.dwCaps, expected_caps[i]);
3010                 else
3011                     todo_wine ok(desc2.ddsCaps.dwCaps == expected_caps[i],
3012                                     "GetSurfaceDesc test %d returned caps %x, expected %x\n", i,
3013                                     desc2.ddsCaps.dwCaps, expected_caps[i]);
3014
3015                 IDirectDrawSurface7_Release(surface7);
3016             }
3017         }
3018
3019         IDirectDraw7_Release(dd7);
3020     }
3021
3022     memset(&create, 0, sizeof(create));
3023     create.dwSize = sizeof(create);
3024     create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3025     create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
3026     create.dwWidth = 64;
3027     create.dwHeight = 64;
3028     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
3029     ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
3030     if(surface1) IDirectDrawSurface_Release(surface1);
3031 }
3032
3033 static BOOL can_create_primary_surface(void)
3034 {
3035     DDSURFACEDESC ddsd;
3036     IDirectDrawSurface *surface;
3037     HRESULT hr;
3038
3039     memset(&ddsd, 0, sizeof(ddsd));
3040     ddsd.dwSize = sizeof(ddsd);
3041     ddsd.dwFlags = DDSD_CAPS;
3042     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3043     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
3044     if(FAILED(hr)) return FALSE;
3045     IDirectDrawSurface_Release(surface);
3046     return TRUE;
3047 }
3048
3049 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
3050     HRESULT hr;
3051     HDC dc, dc2 = (HDC) 0x1234;
3052     DDSURFACEDESC ddsd;
3053     DDSURFACEDESC2 ddsd2;
3054
3055     memset(&ddsd, 0, sizeof(ddsd));
3056     ddsd.dwSize = sizeof(ddsd);
3057     memset(&ddsd2, 0, sizeof(ddsd2));
3058     ddsd2.dwSize = sizeof(ddsd2);
3059
3060     hr = IDirectDrawSurface_GetDC(surf, &dc);
3061     ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
3062
3063     hr = IDirectDrawSurface_GetDC(surf, &dc2);
3064     ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
3065     ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
3066
3067     hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
3068     ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_ALREADYLOCKED\n", hr);
3069
3070     hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3071     ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
3072     hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3073     ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
3074 }
3075
3076 static void GetDCTest(void)
3077 {
3078     DDSURFACEDESC ddsd;
3079     DDSURFACEDESC2 ddsd2;
3080     IDirectDrawSurface *surf;
3081     IDirectDrawSurface2 *surf2;
3082     IDirectDrawSurface4 *surf4;
3083     IDirectDrawSurface7 *surf7;
3084     IDirectDrawSurface *tmp;
3085     IDirectDrawSurface7 *tmp7;
3086     HRESULT hr;
3087     IDirectDraw2 *dd2;
3088     IDirectDraw4 *dd4;
3089     IDirectDraw7 *dd7;
3090     HDC dc;
3091     ULONG ref;
3092
3093     memset(&ddsd, 0, sizeof(ddsd));
3094     ddsd.dwSize = sizeof(ddsd);
3095     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3096     ddsd.dwWidth = 64;
3097     ddsd.dwHeight = 64;
3098     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3099     memset(&ddsd2, 0, sizeof(ddsd2));
3100     ddsd2.dwSize = sizeof(ddsd2);
3101     ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3102     ddsd2.dwWidth = 64;
3103     ddsd2.dwHeight = 64;
3104     ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3105
3106     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3107     ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3108     dctest_surf(surf, 1);
3109     IDirectDrawSurface_Release(surf);
3110
3111     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3112     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3113
3114     hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3115     ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3116     dctest_surf(surf, 1);
3117
3118     hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
3119     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
3120     dctest_surf((IDirectDrawSurface *) surf2, 1);
3121
3122     IDirectDrawSurface2_Release(surf2);
3123     IDirectDrawSurface_Release(surf);
3124     IDirectDraw2_Release(dd2);
3125
3126     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3127     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3128
3129     surf = NULL;
3130     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3131     ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3132     dctest_surf((IDirectDrawSurface *) surf4, 2);
3133
3134     hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf);
3135     ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3136
3137     ref = getRefcount((IUnknown *) surf);
3138     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
3139     ref = getRefcount((IUnknown *) surf4);
3140     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
3141
3142     hr = IDirectDrawSurface4_GetDC(surf4, &dc);
3143     ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3144
3145     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
3146     ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3147
3148     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3149     ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3150     ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
3151
3152     ref = getRefcount((IUnknown *) surf);
3153     ok(ref == 2, "Refcount is %u, expected 2\n", ref);
3154     ref = getRefcount((IUnknown *) tmp);
3155     ok(ref == 2, "Refcount is %u, expected 2\n", ref);
3156     ref = getRefcount((IUnknown *) surf4);
3157     ok(ref == 1, "Refcount is %u, expected 1\n", ref);
3158
3159     hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
3160     ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3161
3162     IDirectDrawSurface_Release(tmp);
3163
3164     dc = CreateCompatibleDC(NULL);
3165     ok(!!dc, "CreateCompatibleDC failed.\n");
3166
3167     tmp = (IDirectDrawSurface *)0xdeadbeef;
3168     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3169     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3170     ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3171
3172     ok(DeleteDC(dc), "DeleteDC failed.\n");
3173
3174     tmp = (IDirectDrawSurface *)0xdeadbeef;
3175     hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
3176     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3177     ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3178
3179     IDirectDrawSurface4_Release(surf4);
3180     IDirectDrawSurface_Release(surf);
3181     IDirectDraw4_Release(dd4);
3182
3183     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3184     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3185
3186     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3187     ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3188     dctest_surf((IDirectDrawSurface *) surf7, 2);
3189
3190     hr = IDirectDrawSurface7_GetDC(surf7, &dc);
3191     ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3192
3193     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
3194     ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3195
3196     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3197     ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3198     ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
3199     IDirectDrawSurface7_Release(tmp7);
3200
3201     hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
3202     ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3203
3204     dc = CreateCompatibleDC(NULL);
3205     ok(!!dc, "CreateCompatibleDC failed.\n");
3206
3207     tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3208     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3209     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3210     ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3211
3212     ok(DeleteDC(dc), "DeleteDC failed.\n");
3213
3214     tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3215     hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
3216     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3217     ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3218
3219     IDirectDrawSurface7_Release(surf7);
3220     IDirectDraw7_Release(dd7);
3221 }
3222
3223 static void GetDCFormatTest(void)
3224 {
3225     DDSURFACEDESC2 ddsd;
3226     unsigned int i;
3227     IDirectDrawSurface7 *surface;
3228     IDirectDraw7 *dd7;
3229     HRESULT hr;
3230     HDC dc;
3231
3232     struct
3233     {
3234         const char *name;
3235         DDPIXELFORMAT fmt;
3236         BOOL getdc_capable;
3237         HRESULT alt_result;
3238     } testdata[] = {
3239         {
3240             "D3DFMT_A8R8G8B8",
3241             {
3242                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3243                 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3244             },
3245             TRUE
3246         },
3247         {
3248             "D3DFMT_X8R8G8B8",
3249             {
3250                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3251                 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
3252             },
3253             TRUE
3254         },
3255         {
3256             "D3DFMT_X8B8G8R8",
3257             {
3258                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3259                 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
3260             },
3261             TRUE,
3262             DDERR_CANTCREATEDC /* Vista+ */
3263         },
3264         {
3265             "D3DFMT_X8B8G8R8",
3266             {
3267                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3268                        {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}
3269             },
3270             TRUE,
3271             DDERR_CANTCREATEDC /* Vista+ */
3272         },
3273         {
3274             "D3DFMT_A4R4G4B4",
3275             {
3276                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3277                        {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}
3278             },
3279             TRUE,
3280             DDERR_CANTCREATEDC /* Vista+ */
3281         },
3282         {
3283             "D3DFMT_X4R4G4B4",
3284             {
3285                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3286                        {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}
3287             },
3288             TRUE,
3289             DDERR_CANTCREATEDC /* Vista+ */
3290         },
3291         {
3292             "D3DFMT_R5G6B5",
3293             {
3294                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3295                        {16}, {0x0000F800}, {0x000007E0}, {0x0000001F}, {0x00000000}
3296             },
3297             TRUE
3298         },
3299         {
3300             "D3DFMT_A1R5G5B5",
3301             {
3302                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3303                        {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00008000}
3304             },
3305             TRUE
3306         },
3307         {
3308             "D3DFMT_X1R5G5B5",
3309             {
3310                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3311                        {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00000000}
3312             },
3313             TRUE
3314         },
3315         {
3316             "D3DFMT_R3G3B2",
3317             {
3318                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3319                        { 8}, {0x000000E0}, {0x0000001C}, {0x00000003}, {0x00000000}
3320             },
3321             FALSE
3322         },
3323         {
3324             /* Untested, windows test machine didn't support this format */
3325             "D3DFMT_A2R10G10B10",
3326             {
3327                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3328                        {32}, {0xC0000000}, {0x3FF00000}, {0x000FFC00}, {0x000003FF}
3329             },
3330             TRUE
3331         },
3332         /*
3333          * GetDC on a P8 surface fails unless the display mode is 8 bpp. This is not
3334          * implemented in wine yet, so disable the test for now. Succeeding P8 getDC
3335          * calls are tested in the ddraw.visual test.
3336          *
3337         {
3338             "D3DFMT_P8",
3339             {
3340                 sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
3341                 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3342             },
3343             FALSE
3344         },
3345          */
3346         {
3347             "D3DFMT_L8",
3348             {
3349                 sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0,
3350                 {8 }, {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}
3351             },
3352             FALSE
3353         },
3354         {
3355             "D3DFMT_A8L8",
3356             {
3357                 sizeof(DDPIXELFORMAT), DDPF_ALPHAPIXELS | DDPF_LUMINANCE, 0,
3358                 {16}, {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}
3359             },
3360             FALSE
3361         },
3362         {
3363             "D3DFMT_DXT1",
3364             {
3365                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','1'),
3366                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3367             },
3368             FALSE
3369         },
3370         {
3371             "D3DFMT_DXT2",
3372             {
3373                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','2'),
3374                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3375             },
3376             FALSE
3377         },
3378         {
3379             "D3DFMT_DXT3",
3380             {
3381                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','3'),
3382                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3383             },
3384             FALSE
3385         },
3386         {
3387             "D3DFMT_DXT4",
3388             {
3389                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','4'),
3390                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3391             },
3392             FALSE
3393         },
3394         {
3395             "D3DFMT_DXT5",
3396             {
3397                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','5'),
3398                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3399             },
3400             FALSE
3401         },
3402     };
3403
3404     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3405     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed, hr = 0x%08x\n", hr);
3406
3407     for(i = 0; i < (sizeof(testdata) / sizeof(testdata[0])); i++)
3408     {
3409         memset(&ddsd, 0, sizeof(ddsd));
3410         ddsd.dwSize = sizeof(ddsd);
3411         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3412         ddsd.dwWidth = 64;
3413         ddsd.dwHeight = 64;
3414         U4(ddsd).ddpfPixelFormat = testdata[i].fmt;
3415         ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3416
3417         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3418         if(FAILED(hr))
3419         {
3420             ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
3421             ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
3422             hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3423             if(FAILED(hr))
3424             {
3425                 skip("IDirectDraw7_CreateSurface failed, hr = 0x%08x, format %s\n", hr, testdata[i].name);
3426                 continue;
3427             }
3428         }
3429
3430         dc = (void *) 0x1234;
3431         hr = IDirectDrawSurface7_GetDC(surface, &dc);
3432         if(testdata[i].getdc_capable)
3433         {
3434             ok(SUCCEEDED(hr) ||
3435                (testdata[i].alt_result && hr == testdata[i].alt_result),
3436                "GetDC on a %s surface failed(0x%08x), expected it to work\n",
3437                testdata[i].name, hr);
3438         }
3439         else
3440         {
3441             ok(FAILED(hr), "GetDC on a %s surface succeeded(0x%08x), expected it to fail\n",
3442                testdata[i].name, hr);
3443         }
3444
3445         if(SUCCEEDED(hr))
3446         {
3447             IDirectDrawSurface7_ReleaseDC(surface, dc);
3448             ok(hr == DD_OK, "IDirectDrawSurface7_ReleaseDC failed, hr = 0x%08x\n", hr);
3449             dc = 0;
3450         }
3451         else
3452         {
3453             ok(dc == NULL, "After failed GetDC dc is %p\n", dc);
3454         }
3455
3456         IDirectDrawSurface7_Release(surface);
3457     }
3458
3459     IDirectDraw7_Release(dd7);
3460 }
3461
3462 static void BackBufferCreateSurfaceTest(void)
3463 {
3464     DDSURFACEDESC ddsd;
3465     DDSURFACEDESC created_ddsd;
3466     DDSURFACEDESC2 ddsd2;
3467     IDirectDrawSurface *surf;
3468     IDirectDrawSurface4 *surf4;
3469     IDirectDrawSurface7 *surf7;
3470     HRESULT hr;
3471     IDirectDraw2 *dd2;
3472     IDirectDraw4 *dd4;
3473     IDirectDraw7 *dd7;
3474
3475     const DWORD caps = DDSCAPS_BACKBUFFER;
3476     const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3477
3478     if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3479     {
3480         skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3481         return ;
3482     }
3483
3484     memset(&ddsd, 0, sizeof(ddsd));
3485     ddsd.dwSize = sizeof(ddsd);
3486     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3487     ddsd.dwWidth = 64;
3488     ddsd.dwHeight = 64;
3489     ddsd.ddsCaps.dwCaps = caps;
3490     memset(&ddsd2, 0, sizeof(ddsd2));
3491     ddsd2.dwSize = sizeof(ddsd2);
3492     ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3493     ddsd2.dwWidth = 64;
3494     ddsd2.dwHeight = 64;
3495     ddsd2.ddsCaps.dwCaps = caps;
3496     memset(&created_ddsd, 0, sizeof(created_ddsd));
3497     created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3498
3499     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3500     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3501     if (surf != NULL)
3502     {
3503         hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3504         ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3505         ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3506            "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3507            expected_caps);
3508         IDirectDrawSurface_Release(surf);
3509     }
3510
3511     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3512     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3513
3514     hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3515     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3516        DDERR_INVALIDCAPS, hr);
3517
3518     IDirectDraw2_Release(dd2);
3519
3520     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3521     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3522
3523     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3524     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3525        DDERR_INVALIDCAPS, hr);
3526
3527     IDirectDraw4_Release(dd4);
3528
3529     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3530     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3531
3532     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3533     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3534        DDERR_INVALIDCAPS, hr);
3535
3536     IDirectDraw7_Release(dd7);
3537 }
3538
3539 static void BackBufferAttachmentFlipTest(void)
3540 {
3541     HRESULT hr;
3542     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3543     DDSURFACEDESC ddsd;
3544     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3545
3546     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3547     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3548
3549     /* Perform attachment tests on a back-buffer */
3550     memset(&ddsd, 0, sizeof(ddsd));
3551     ddsd.dwSize = sizeof(ddsd);
3552     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3553     ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3554     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3555     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3556     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
3557     ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3558
3559     if (surface2 != NULL)
3560     {
3561         /* Try a single primary and a two back buffers */
3562         memset(&ddsd, 0, sizeof(ddsd));
3563         ddsd.dwSize = sizeof(ddsd);
3564         ddsd.dwFlags = DDSD_CAPS;
3565         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3566         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
3567         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3568
3569         memset(&ddsd, 0, sizeof(ddsd));
3570         ddsd.dwSize = sizeof(ddsd);
3571         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3572         ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3573         ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3574         ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3575         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
3576         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3577
3578         /* This one has a different size */
3579         memset(&ddsd, 0, sizeof(ddsd));
3580         ddsd.dwSize = sizeof(ddsd);
3581         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3582         ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3583         ddsd.dwWidth = 128;
3584         ddsd.dwHeight = 128;
3585         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
3586         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3587
3588         hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3589         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3590            "Attaching a back buffer to a front buffer returned %08x\n", hr);
3591         if(SUCCEEDED(hr))
3592         {
3593             /* Try flipping the surfaces */
3594             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3595             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3596             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3597             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3598
3599             /* Try the reverse without detaching first */
3600             hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3601             ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3602             hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3603             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3604         }
3605         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3606         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3607            "Attaching a front buffer to a back buffer returned %08x\n", hr);
3608         if(SUCCEEDED(hr))
3609         {
3610             /* Try flipping the surfaces */
3611             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3612             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3613             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3614             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3615
3616             /* Try to detach reversed */
3617             hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3618             ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3619             /* Now the proper detach */
3620             hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3621             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3622         }
3623         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3624         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3625            "Attaching a back buffer to another back buffer returned %08x\n", hr);
3626         if(SUCCEEDED(hr))
3627         {
3628             /* Try flipping the surfaces */
3629             hr = IDirectDrawSurface_Flip(surface3, NULL, DDFLIP_WAIT);
3630             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3631             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3632             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3633             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3634             ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3635
3636             hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3637             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3638         }
3639         hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3640         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3641         hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3642         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3643
3644         IDirectDrawSurface_Release(surface4);
3645         IDirectDrawSurface_Release(surface3);
3646         IDirectDrawSurface_Release(surface2);
3647         IDirectDrawSurface_Release(surface1);
3648     }
3649
3650     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
3651     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3652
3653     DestroyWindow(window);
3654 }
3655
3656 static void CreateSurfaceBadCapsSizeTest(void)
3657 {
3658     DDSURFACEDESC ddsd_ok;
3659     DDSURFACEDESC ddsd_bad1;
3660     DDSURFACEDESC ddsd_bad2;
3661     DDSURFACEDESC ddsd_bad3;
3662     DDSURFACEDESC ddsd_bad4;
3663     DDSURFACEDESC2 ddsd2_ok;
3664     DDSURFACEDESC2 ddsd2_bad1;
3665     DDSURFACEDESC2 ddsd2_bad2;
3666     DDSURFACEDESC2 ddsd2_bad3;
3667     DDSURFACEDESC2 ddsd2_bad4;
3668     IDirectDrawSurface *surf;
3669     IDirectDrawSurface4 *surf4;
3670     IDirectDrawSurface7 *surf7;
3671     HRESULT hr;
3672     IDirectDraw2 *dd2;
3673     IDirectDraw4 *dd4;
3674     IDirectDraw7 *dd7;
3675
3676     const DWORD caps = DDSCAPS_OFFSCREENPLAIN;
3677
3678     memset(&ddsd_ok, 0, sizeof(ddsd_ok));
3679     ddsd_ok.dwSize = sizeof(ddsd_ok);
3680     ddsd_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3681     ddsd_ok.dwWidth = 64;
3682     ddsd_ok.dwHeight = 64;
3683     ddsd_ok.ddsCaps.dwCaps = caps;
3684     memcpy(&ddsd_bad1, &ddsd_ok, sizeof(ddsd_bad1));
3685     ddsd_bad1.dwSize--;
3686     memcpy(&ddsd_bad2, &ddsd_ok, sizeof(ddsd_bad2));
3687     ddsd_bad2.dwSize++;
3688     memcpy(&ddsd_bad3, &ddsd_ok, sizeof(ddsd_bad3));
3689     ddsd_bad3.dwSize = 0;
3690     memcpy(&ddsd_bad4, &ddsd_ok, sizeof(ddsd_bad4));
3691     ddsd_bad4.dwSize = sizeof(DDSURFACEDESC2);
3692
3693     memset(&ddsd2_ok, 0, sizeof(ddsd2_ok));
3694     ddsd2_ok.dwSize = sizeof(ddsd2_ok);
3695     ddsd2_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3696     ddsd2_ok.dwWidth = 64;
3697     ddsd2_ok.dwHeight = 64;
3698     ddsd2_ok.ddsCaps.dwCaps = caps;
3699     memcpy(&ddsd2_bad1, &ddsd2_ok, sizeof(ddsd2_bad1));
3700     ddsd2_bad1.dwSize--;
3701     memcpy(&ddsd2_bad2, &ddsd2_ok, sizeof(ddsd2_bad2));
3702     ddsd2_bad2.dwSize++;
3703     memcpy(&ddsd2_bad3, &ddsd2_ok, sizeof(ddsd2_bad3));
3704     ddsd2_bad3.dwSize = 0;
3705     memcpy(&ddsd2_bad4, &ddsd2_ok, sizeof(ddsd2_bad4));
3706     ddsd2_bad4.dwSize = sizeof(DDSURFACEDESC);
3707
3708     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_ok, &surf, NULL);
3709     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3710     IDirectDrawSurface_Release(surf);
3711
3712     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad1, &surf, NULL);
3713     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3714        DDERR_INVALIDPARAMS, hr);
3715     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad2, &surf, NULL);
3716     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3717        DDERR_INVALIDPARAMS, hr);
3718     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad3, &surf, NULL);
3719     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3720        DDERR_INVALIDPARAMS, hr);
3721     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad4, &surf, NULL);
3722     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3723        DDERR_INVALIDPARAMS, hr);
3724     hr = IDirectDraw_CreateSurface(lpDD, NULL, &surf, NULL);
3725     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3726        DDERR_INVALIDPARAMS, hr);
3727
3728     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3729     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3730
3731     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_ok, &surf, NULL);
3732     ok(SUCCEEDED(hr), "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3733     IDirectDrawSurface_Release(surf);
3734
3735     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad1, &surf, NULL);
3736     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3737        DDERR_INVALIDPARAMS, hr);
3738     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad2, &surf, NULL);
3739     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3740        DDERR_INVALIDPARAMS, hr);
3741     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad3, &surf, NULL);
3742     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3743        DDERR_INVALIDPARAMS, hr);
3744     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad4, &surf, NULL);
3745     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3746        DDERR_INVALIDPARAMS, hr);
3747     hr = IDirectDraw2_CreateSurface(dd2, NULL, &surf, NULL);
3748     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3749        DDERR_INVALIDPARAMS, hr);
3750
3751     IDirectDraw2_Release(dd2);
3752
3753     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3754     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3755
3756     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_ok, &surf4, NULL);
3757     ok(SUCCEEDED(hr), "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3758     IDirectDrawSurface4_Release(surf4);
3759
3760     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad1, &surf4, NULL);
3761     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3762        DDERR_INVALIDPARAMS, hr);
3763     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad2, &surf4, NULL);
3764     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3765        DDERR_INVALIDPARAMS, hr);
3766     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad3, &surf4, NULL);
3767     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3768        DDERR_INVALIDPARAMS, hr);
3769     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad4, &surf4, NULL);
3770     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3771        DDERR_INVALIDPARAMS, hr);
3772     hr = IDirectDraw4_CreateSurface(dd4, NULL, &surf4, NULL);
3773     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3774        DDERR_INVALIDPARAMS, hr);
3775
3776     IDirectDraw4_Release(dd4);
3777
3778     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3779     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3780
3781     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_ok, &surf7, NULL);
3782     ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3783     IDirectDrawSurface7_Release(surf7);
3784
3785     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad1, &surf7, NULL);
3786     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3787        DDERR_INVALIDPARAMS, hr);
3788     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad2, &surf7, NULL);
3789     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3790        DDERR_INVALIDPARAMS, hr);
3791     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad3, &surf7, NULL);
3792     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3793        DDERR_INVALIDPARAMS, hr);
3794     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad4, &surf7, NULL);
3795     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3796        DDERR_INVALIDPARAMS, hr);
3797     hr = IDirectDraw7_CreateSurface(dd7, NULL, &surf7, NULL);
3798     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3799        DDERR_INVALIDPARAMS, hr);
3800
3801     IDirectDraw7_Release(dd7);
3802 }
3803
3804 START_TEST(dsurface)
3805 {
3806     HRESULT ret;
3807     IDirectDraw4 *dd4;
3808
3809     if (!CreateDirectDraw())
3810         return;
3811
3812     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3813     if (ret == E_NOINTERFACE)
3814     {
3815         win_skip("DirectDraw4 and higher are not supported\n");
3816         ReleaseDirectDraw();
3817         return;
3818     }
3819     IDirectDraw_Release(dd4);
3820
3821     if(!can_create_primary_surface())
3822     {
3823         skip("Unable to create primary surface\n");
3824         return;
3825     }
3826
3827     ddcaps.dwSize = sizeof(DDCAPS);
3828     ret = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
3829     if (ret != DD_OK)
3830     {
3831         skip("IDirectDraw_GetCaps failed with %08x\n", ret);
3832         return;
3833     }
3834
3835     MipMapCreationTest();
3836     SrcColorKey32BlitTest();
3837     QueryInterface();
3838     GetDDInterface_1();
3839     GetDDInterface_2();
3840     GetDDInterface_4();
3841     GetDDInterface_7();
3842     IFaceRefCount();
3843     EnumTest();
3844     AttachmentTest();
3845     AttachmentTest7();
3846     CubeMapTest();
3847     test_lockrect_invalid();
3848     CompressedTest();
3849     SizeTest();
3850     PrivateDataTest();
3851     BltParamTest();
3852     StructSizeTest();
3853     PaletteTest();
3854     SurfaceCapsTest();
3855     GetDCTest();
3856     GetDCFormatTest();
3857     BackBufferCreateSurfaceTest();
3858     BackBufferAttachmentFlipTest();
3859     CreateSurfaceBadCapsSizeTest();
3860     ReleaseDirectDraw();
3861 }