1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for NtGdiDdCreateDirectDrawObject
5  * PROGRAMMERS:
6  */
7 
8 #include <win32nt.h>
9 
10 #include <ddrawi.h>
11 
12 /* Note : OsThunkDdQueryDirectDrawObject is the usermode name of NtGdiDdQueryDirectDrawObject
13  *        it lives in d3d8thk.dll and in windows 2000 it doing syscall direcly to win32k.sus
14  *        in windows xp and higher it call to gdi32.dll to DdEntry41 and it doing the syscall
15  */
16 START_TEST(NtGdiDdQueryDirectDrawObject)
17 {
18     HANDLE hDirectDraw;
19     DD_HALINFO *pHalInfo = NULL;
20     DWORD *pCallBackFlags = NULL;
21     LPD3DNTHAL_CALLBACKS puD3dCallbacks = NULL;
22     LPD3DNTHAL_GLOBALDRIVERDATA puD3dDriverData = NULL;
23     PDD_D3DBUFCALLBACKS puD3dBufferCallbacks = NULL;
24     LPDDSURFACEDESC puD3dTextureFormats = NULL;
25     DWORD *puNumHeaps = NULL;
26     VIDEOMEMORY *puvmList = NULL;
27     DWORD *puNumFourCC = NULL;
28     DWORD *puFourCC = NULL;
29 
30     DD_HALINFO HalInfo;
31     DD_HALINFO oldHalInfo;
32     DWORD CallBackFlags[4];
33 
34     D3DNTHAL_CALLBACKS D3dCallbacks;
35     D3DNTHAL_CALLBACKS oldD3dCallbacks;
36 
37     D3DNTHAL_GLOBALDRIVERDATA D3dDriverData;
38     D3DNTHAL_GLOBALDRIVERDATA oldD3dDriverData;
39 
40     DD_D3DBUFCALLBACKS D3dBufferCallbacks;
41     DD_D3DBUFCALLBACKS oldD3dBufferCallbacks;
42 
43     DDSURFACEDESC2 D3dTextureFormats[100];
44     DWORD NumHeaps = 0;
45     VIDEOMEMORY vmList;
46     //DWORD NumFourCC = 0;
47     //DWORD FourCC = 0;
48     DEVMODE devmode;
49     HDC hdc;
50 
51     DWORD dwTextureCounter = 0;
52     DDSURFACEDESC *myDesc = NULL;
53 
54     /* clear data */
55     memset(&vmList,0,sizeof(VIDEOMEMORY));
56     memset(&D3dTextureFormats,0,sizeof(DDSURFACEDESC));
57     memset(&D3dBufferCallbacks,0,sizeof(DD_D3DBUFCALLBACKS));
58     memset(&D3dDriverData,0,sizeof(D3DNTHAL_GLOBALDRIVERDATA));
59     memset(&D3dCallbacks,0,sizeof(D3DNTHAL_CALLBACKS));
60     memset(&HalInfo,0,sizeof(DD_HALINFO));
61     memset(CallBackFlags,0,sizeof(DWORD)*3);
62 
63     /* Get current display mode */
64     EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devmode);
65 
66     /* Create hdc that we can use */
67     hdc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
68     ASSERT(hdc != NULL);
69 
70 
71     hDirectDraw = NtGdiDdCreateDirectDrawObject(hdc);
72     RTEST(hDirectDraw != NULL);
73 
74     /* testing  OsThunkDdQueryDirectDrawObject( NULL, ....  */
75     RTEST(NtGdiDdQueryDirectDrawObject( NULL, pHalInfo,
76                                         pCallBackFlags, puD3dCallbacks,
77                                         puD3dDriverData, puD3dBufferCallbacks,
78                                         puD3dTextureFormats, puNumHeaps,
79                                         puvmList, puNumFourCC,
80                                         puFourCC) == FALSE);
81 
82     RTEST(pHalInfo == NULL);
83     RTEST(pCallBackFlags == NULL);
84     RTEST(puD3dCallbacks == NULL);
85     RTEST(puD3dDriverData == NULL);
86     RTEST(puD3dBufferCallbacks == NULL);
87     RTEST(puD3dTextureFormats == NULL);
88     RTEST(puNumFourCC == NULL);
89     RTEST(puFourCC == NULL);
90     RTEST(puNumHeaps == NULL);
91     RTEST(puvmList == NULL);
92 
93     if (hDirectDraw == NULL)
94     {
95         skip("No DirectDrawObject\n");
96         ok(DeleteDC(hdc) != 0, "DeleteDC() failed\n");
97         return;
98     }
99 
100     /* testing  NtGdiDdQueryDirectDrawObject( hDirectDrawLocal, NULL, ....  */
101     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
102                                         pCallBackFlags, puD3dCallbacks,
103                                         puD3dDriverData, puD3dBufferCallbacks,
104                                         puD3dTextureFormats, puNumHeaps,
105                                         puvmList, puNumFourCC,
106                                         puFourCC) == FALSE);
107 
108     RTEST(pHalInfo == NULL);
109     RTEST(pCallBackFlags == NULL);
110     RTEST(puD3dCallbacks == NULL);
111     RTEST(puD3dDriverData == NULL);
112     RTEST(puD3dBufferCallbacks == NULL);
113     RTEST(puD3dTextureFormats == NULL);
114     RTEST(puNumFourCC == NULL);
115     RTEST(puFourCC == NULL);
116     RTEST(puNumHeaps == NULL);
117     RTEST(puvmList == NULL);
118 
119     /* testing  NtGdiDdQueryDirectDrawObject( hDirectDrawLocal, pHalInfo, NULL, ....  */
120     pHalInfo = &HalInfo;
121     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
122                                         pCallBackFlags, puD3dCallbacks,
123                                         puD3dDriverData, puD3dBufferCallbacks,
124                                         puD3dTextureFormats, puNumHeaps,
125                                         puvmList, puNumFourCC,
126                                         puFourCC)== FALSE);
127 
128     RTEST(pHalInfo != NULL);
129     ASSERT(pHalInfo != NULL);
130 
131     RTEST(pCallBackFlags == NULL);
132     RTEST(puD3dCallbacks == NULL);
133     RTEST(puD3dDriverData == NULL);
134     RTEST(puD3dBufferCallbacks == NULL);
135     RTEST(puD3dTextureFormats == NULL);
136     RTEST(puNumFourCC == NULL);
137     RTEST(puFourCC == NULL);
138     RTEST(puNumHeaps == NULL);
139     RTEST(puvmList == NULL);
140 
141     if ((pHalInfo->dwSize != sizeof(DD_HALINFO)) &&
142         (pHalInfo->dwSize != sizeof(DD_HALINFO_V4)))
143     {
144         RTEST(pHalInfo->dwSize != sizeof(DD_HALINFO));
145         ASSERT(pHalInfo->dwSize != sizeof(DD_HALINFO));
146     }
147 
148     if (pHalInfo->dwSize == sizeof(DD_HALINFO))
149     {
150         /*the offset, in bytes, to primary surface in the display memory  */
151         /* some graphic card like  sis 760 GX, Nvida GF7900GS does not set any offset at all */
152         // RTEST(pHalInfo->vmiData.fpPrimary != 0 );
153 
154         /* unsuse always 0 */
155         RTEST(pHalInfo->vmiData.dwFlags == 0 );
156 
157         /* Check the res */
158         RTEST(pHalInfo->vmiData.dwDisplayWidth == devmode.dmPelsWidth );
159         RTEST(pHalInfo->vmiData.dwDisplayHeight == devmode.dmPelsHeight );
160 
161         /*  This can never be test for it is who big the line is after it been align displayPitch */
162         RTEST(pHalInfo->vmiData.lDisplayPitch != 0);
163 
164         RTEST(pHalInfo->vmiData.ddpfDisplay.dwSize == sizeof(DDPIXELFORMAT) );
165         ASSERT(pHalInfo->vmiData.ddpfDisplay.dwSize == sizeof(DDPIXELFORMAT));
166 
167         /* We can not check if it DDPF_RGB flags been set for primary surface
168          * for it can be DDPF_PALETTEINDEXED1,DDPF_PALETTEINDEXED2,DDPF_PALETTEINDEXED4,DDPF_PALETTEINDEXED8, DDPF_PALETTEINDEXEDTO8, DDPF_RGB, DDPF_YUV
169          */
170         RTEST( (pHalInfo->vmiData.ddpfDisplay.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4 |
171                                                          DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8 | DDPF_RGB | DDPF_YUV)) != 0);
172 
173 
174         /* No fourcc are use on primary screen */
175         RTEST(pHalInfo->vmiData.ddpfDisplay.dwFourCC == 0 );
176 
177         /* Count RGB Bits 8/16/24/32 */
178         RTEST(pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount == devmode.dmBitsPerPel );
179 
180         /* The rgb mask can not be detected in user mode, for it can be 15Bpp convert to 16Bpp mode, so we have no way detect correct mask
181          * But the mask can never be Zero
182          */
183         RTEST(pHalInfo->vmiData.ddpfDisplay.dwRBitMask  !=  0 );
184         RTEST(pHalInfo->vmiData.ddpfDisplay.dwGBitMask !=  0 );
185         RTEST(pHalInfo->vmiData.ddpfDisplay.dwBBitMask != 0 );
186 
187         /* primary never set the alpha blend mask */
188         RTEST(pHalInfo->vmiData.ddpfDisplay.dwRGBAlphaBitMask ==  0 );
189 
190         /* This can not be test at usermode it is each hardware drv that fill in it,
191          * only way to found them is to use this call  */
192         // pHalInfo->vmiData->dwOffscreenAlign
193         // pHalInfo->vmiData->dwOverlayAlign
194         // pHalInfo->vmiData->dwTextureAlign
195         // pHalInfo->vmiData->dwZBufferAlign
196         // pHalInfo->vmiData->dwAlphaAlign
197 
198         /* the primary display address */
199         RTEST( ( (DWORD_PTR)pHalInfo->vmiData.pvPrimary & (~0x80000000)) != 0 );
200 
201         /* test see if we got back the pvmList here
202          * acording msdn vmiData.dwNumHeaps and vmiData.pvmList
203          * exists for _VIDEOMEMORYINFO but they do not, it reviews
204          * in ddk and wdk and own testcase
205          */
206          // RTEST(pHalInfo->vmiData.dwNumHeaps  != 0 );
207          // RTEST(pHalInfo->vmiData.pvmList  != 0 );
208 
209         /* Test see if we got any hardware acclartions for 2d or 3d, this always fill in
210          * that mean we found a bugi drv and dx does not work on this drv
211          */
212 
213         /* the SIS 760 GX will never fill it in, it is a bugi drv */
214         RTEST(pHalInfo->ddCaps.dwSize == sizeof(DDCORECAPS));
215 
216         /* Testing see if we got any hw support for
217          * This test can fail on video card that does not support 2d/overlay/3d
218          */
219         RTEST( pHalInfo->ddCaps.dwCaps != 0);
220         RTEST( pHalInfo->ddCaps.ddsCaps.dwCaps != 0);
221 
222         /* This flags is obsolete and should not be used by the driver */
223         RTEST( pHalInfo->ddCaps.dwFXAlphaCaps == 0);
224 
225 
226         /* basic dx 2 is found if this flags not set
227          * if this fail we do not have a dx driver install acodring ms, some version of windows it
228          * is okay this fail and drv does then only support basic dx
229          *
230          */
231         if (pHalInfo->dwFlags != 0)
232         {
233             RTEST( (pHalInfo->dwFlags & (DDHALINFO_GETDRIVERINFOSET | DDHALINFO_GETDRIVERINFO2)) != 0 );
234             RTEST( ( (DWORD_PTR)pHalInfo->GetDriverInfo & 0x80000000) != 0 );
235             ASSERT( ((DWORD_PTR)pHalInfo->GetDriverInfo & 0x80000000) != 0 );
236         }
237 
238         /* point to kmode direcly to the graphic drv, the drv is kmode and it is kmode address we getting back*/
239 
240 
241        /* the pHalInfo->ddCaps.ddsCaps.dwCaps & DDSCAPS_3DDEVICE will be ignore, only way detect it proper follow code,
242         * this will be fill in of all drv, it is not only for 3d stuff, this always fill by win32k.sys or dxg.sys depns
243         * if it windows 2000 or windows xp/2003
244         *
245         * point to kmode direcly to the win32k.sys, win32k.sys is kmode and it is kmode address we getting back
246         */
247         RTEST( ( (DWORD_PTR)pHalInfo->lpD3DGlobalDriverData & (~0x80000000)) != 0 );
248         RTEST( ( (DWORD_PTR)pHalInfo->lpD3DHALCallbacks & (~0x80000000)) != 0 );
249         RTEST( ( (DWORD_PTR)pHalInfo->lpD3DHALCallbacks & (~0x80000000)) != 0 );
250     }
251 
252     /* Backup DD_HALINFO so we do not need resting it */
253     RtlCopyMemory(&oldHalInfo, &HalInfo, sizeof(DD_HALINFO));
254 
255     /* testing  NtGdiDdQueryDirectDrawObject( hDirectDrawLocal, pHalInfo, pCallBackFlags, NULL, ....  */
256     pHalInfo = &HalInfo;
257     pCallBackFlags = CallBackFlags;
258     RtlZeroMemory(pHalInfo,sizeof(DD_HALINFO));
259 
260     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
261                                         pCallBackFlags, puD3dCallbacks,
262                                         puD3dDriverData, puD3dBufferCallbacks,
263                                         puD3dTextureFormats, puNumHeaps,
264                                         puvmList, puNumFourCC,
265                                         puFourCC)== FALSE);
266     RTEST(pHalInfo != NULL);
267     ASSERT(pHalInfo != NULL);
268 
269     RTEST(pCallBackFlags != NULL);
270     ASSERT(pCallBackFlags != NULL);
271 
272     RTEST(puD3dCallbacks == NULL);
273     RTEST(puD3dDriverData == NULL);
274     RTEST(puD3dBufferCallbacks == NULL);
275     RTEST(puD3dTextureFormats == NULL);
276     RTEST(puNumFourCC == NULL);
277     RTEST(puFourCC == NULL);
278     RTEST(puNumHeaps == NULL);
279     RTEST(puvmList == NULL);
280 
281     /* We do not retesting DD_HALINFO, instead we compare it */
282     RTEST(memcmp(&oldHalInfo, pHalInfo, sizeof(DD_HALINFO)) == 0);
283 
284     /* Rember on some nivida drv the pCallBackFlags will not be set even they api exists in the drv
285      * known workaround is to check if the drv really return a kmode pointer for the drv functions
286      * we want to use.
287      */
288     RTEST(pCallBackFlags[0] != 0);
289     RTEST(pCallBackFlags[1] != 0);
290     RTEST(pCallBackFlags[2] == 0);
291 
292     /* testing  NtGdiDdQueryDirectDrawObject( hDirectDrawLocal, pHalInfo, pCallBackFlags, D3dCallbacks, NULL, ....  */
293     pHalInfo = &HalInfo;
294     pCallBackFlags = CallBackFlags;
295     puD3dCallbacks = &D3dCallbacks;
296 
297     RtlZeroMemory(pHalInfo,sizeof(DD_HALINFO));
298     RtlZeroMemory(pCallBackFlags,sizeof(DWORD)*3);
299 
300     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
301                                         pCallBackFlags, puD3dCallbacks,
302                                         puD3dDriverData, puD3dBufferCallbacks,
303                                         puD3dTextureFormats, puNumHeaps,
304                                         puvmList, puNumFourCC,
305                                         puFourCC)== FALSE);
306     RTEST(pHalInfo != NULL);
307     ASSERT(pHalInfo != NULL);
308 
309     RTEST(pCallBackFlags != NULL);
310     ASSERT(pCallBackFlags != NULL);
311 
312     /* rember puD3dCallbacks shall never return NULL */
313     RTEST(puD3dCallbacks != NULL);
314     ASSERT(puD3dCallbacks != NULL);
315 
316     /* the pHalInfo->ddCaps.ddsCaps.dwCaps & DDSCAPS_3DDEVICE will be ignore, only way detect it proper follow code,
317      * this will be fill in of all drv, it is not only for 3d stuff, this always fill by win32k.sys or dxg.sys depns
318      * if it windows 2000 or windows xp/2003
319      */
320     RTEST(puD3dCallbacks->dwSize == sizeof(D3DNTHAL_CALLBACKS));
321 
322     /* Nivda like GF7900GS will not follow ms design rule here,
323      * ContextDestroyAll must alwyas be NULL for it is not longer inuse in windows 2000 and higher
324      */
325     RTEST(puD3dCallbacks->ContextDestroyAll == NULL);
326 
327     /* Nivda like GF7900GS will not follow ms design rule here,
328      * SceneCapture must alwyas be NULL for it is not longer inuse in windows 2000 and higher
329      */
330     RTEST(puD3dCallbacks->SceneCapture  == NULL);
331     RTEST(puD3dCallbacks->dwReserved10 == 0);
332     RTEST(puD3dCallbacks->dwReserved11 == 0);
333     RTEST(puD3dCallbacks->dwReserved22 == 0);
334     RTEST(puD3dCallbacks->dwReserved23 == 0);
335     RTEST(puD3dCallbacks->dwReserved == 0);
336     RTEST(puD3dCallbacks->TextureCreate  == NULL);
337     RTEST(puD3dCallbacks->TextureDestroy  == NULL);
338     RTEST(puD3dCallbacks->TextureSwap  == NULL);
339     RTEST(puD3dCallbacks->TextureGetSurf  == NULL);
340     RTEST(puD3dCallbacks->dwReserved12 == 0);
341     RTEST(puD3dCallbacks->dwReserved13 == 0);
342     RTEST(puD3dCallbacks->dwReserved14 == 0);
343     RTEST(puD3dCallbacks->dwReserved15 == 0);
344     RTEST(puD3dCallbacks->dwReserved16 == 0);
345     RTEST(puD3dCallbacks->dwReserved17 == 0);
346     RTEST(puD3dCallbacks->dwReserved18 == 0);
347     RTEST(puD3dCallbacks->dwReserved19 == 0);
348     RTEST(puD3dCallbacks->dwReserved20 == 0);
349     RTEST(puD3dCallbacks->dwReserved21 == 0);
350     RTEST(puD3dCallbacks->dwReserved24 == 0);
351     RTEST(puD3dCallbacks->dwReserved0 == 0);
352     RTEST(puD3dCallbacks->dwReserved1 == 0);
353     RTEST(puD3dCallbacks->dwReserved2 == 0);
354     RTEST(puD3dCallbacks->dwReserved3 == 0);
355     RTEST(puD3dCallbacks->dwReserved4 == 0);
356     RTEST(puD3dCallbacks->dwReserved5 == 0);
357     RTEST(puD3dCallbacks->dwReserved6 == 0);
358     RTEST(puD3dCallbacks->dwReserved7 == 0);
359     RTEST(puD3dCallbacks->dwReserved8 == 0);
360     RTEST(puD3dCallbacks->dwReserved9 == 0);
361 
362     /* how detect puD3dCallbacks->ContextCreate and puD3dCallbacks->ContextDestroy shall be set for bugi drv like nivda ? */
363     /* pointer direcly to the graphic drv, it is kmode pointer */
364     // RTEST( ( (DWORD)puD3dCallbacks->ContextCreate & (~0x80000000)) != 0 );
365     // RTEST( ( (DWORD)puD3dCallbacks->ContextDestroy & (~0x80000000)) != 0 );
366 
367     RTEST(puD3dDriverData == NULL);
368     RTEST(puD3dBufferCallbacks == NULL);
369     RTEST(puD3dTextureFormats == NULL);
370     RTEST(puNumFourCC == NULL);
371     RTEST(puFourCC == NULL);
372     RTEST(puNumHeaps == NULL);
373     RTEST(puvmList == NULL);
374 
375     /* We do not retesting DD_HALINFO, instead we compare it */
376     RTEST(memcmp(&oldHalInfo, pHalInfo, sizeof(DD_HALINFO)) == 0);
377     RTEST(pCallBackFlags[0] != 0);
378     RTEST(pCallBackFlags[1] != 0);
379     RTEST(pCallBackFlags[2] == 0);
380 
381     /* Backup D3DNTHAL_CALLBACKS so we do not need resting it */
382     RtlCopyMemory(&oldD3dCallbacks, &D3dCallbacks, sizeof(D3DNTHAL_CALLBACKS));
383 
384 
385 /* testing  NtGdiDdQueryDirectDrawObject( hDD, pHalInfo, pCallBackFlags, puD3dCallbacks, puD3dDriverData, NULL, */
386     pHalInfo = &HalInfo;
387     pCallBackFlags = CallBackFlags;
388     puD3dCallbacks = &D3dCallbacks;
389     puD3dDriverData = &D3dDriverData;
390 
391     RtlZeroMemory(pHalInfo,sizeof(DD_HALINFO));
392     RtlZeroMemory(pCallBackFlags,sizeof(DWORD)*3);
393     RtlZeroMemory(puD3dCallbacks,sizeof(D3DNTHAL_CALLBACKS));
394 
395     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
396                                         pCallBackFlags, puD3dCallbacks,
397                                         puD3dDriverData, puD3dBufferCallbacks,
398                                         puD3dTextureFormats, puNumHeaps,
399                                         puvmList, puNumFourCC,
400                                         puFourCC)== FALSE);
401     RTEST(pHalInfo != NULL);
402     ASSERT(pHalInfo != NULL);
403 
404     RTEST(pCallBackFlags != NULL);
405     ASSERT(pCallBackFlags != NULL);
406 
407     RTEST(puD3dCallbacks != NULL);
408     ASSERT(puD3dCallbacks != NULL);
409 
410     RTEST(puD3dDriverData != NULL);
411     ASSERT(puD3dDriverData != NULL);
412 
413     RTEST(puD3dBufferCallbacks == NULL);
414     RTEST(puD3dTextureFormats == NULL);
415     RTEST(puNumFourCC == NULL);
416     RTEST(puFourCC == NULL);
417     RTEST(puNumHeaps == NULL);
418     RTEST(puvmList == NULL);
419 
420     /* We retesting pCallBackFlags  */
421     RTEST(pCallBackFlags[0] != 0);
422     RTEST(pCallBackFlags[1] != 0);
423     RTEST(pCallBackFlags[2] == 0);
424 
425     /* We do not retesting instead we compare it */
426     RTEST(memcmp(&oldHalInfo, pHalInfo, sizeof(DD_HALINFO)) == 0);
427     RTEST(memcmp(&oldD3dCallbacks, puD3dCallbacks, sizeof(D3DNTHAL_CALLBACKS)) == 0);
428 
429     /* start test of puD3dDriverData */
430 
431     RTEST(puD3dDriverData->dwSize == sizeof(D3DNTHAL_GLOBALDRIVERDATA));
432     RTEST(puD3dDriverData->hwCaps.dwSize == sizeof(D3DNTHALDEVICEDESC_V1));
433     RTEST(puD3dDriverData->hwCaps.dtcTransformCaps.dwSize == sizeof(D3DTRANSFORMCAPS));
434     RTEST(puD3dDriverData->hwCaps.dlcLightingCaps.dwSize == sizeof(D3DLIGHTINGCAPS));
435     RTEST(puD3dDriverData->hwCaps.dpcLineCaps.dwSize == sizeof(D3DPRIMCAPS));
436     RTEST(puD3dDriverData->hwCaps.dpcTriCaps.dwSize  == sizeof(D3DPRIMCAPS));
437     RTEST(puD3dDriverData->hwCaps.dwMaxBufferSize == 0);
438     RTEST(puD3dDriverData->hwCaps.dwMaxVertexCount == 0);
439 
440     /* Backup D3DHAL_GLOBALDRIVERDATA so we do not need resting it */
441     RtlCopyMemory(&oldD3dDriverData, &D3dDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA));
442 
443 /* testing  NtGdiDdQueryDirectDrawObject( hDD, pHalInfo, pCallBackFlags, puD3dCallbacks, puD3dDriverData, puD3dBufferCallbacks, NULL, */
444     pHalInfo = &HalInfo;
445     pCallBackFlags = CallBackFlags;
446     puD3dCallbacks = &D3dCallbacks;
447     puD3dDriverData = &D3dDriverData;
448     puD3dBufferCallbacks = &D3dBufferCallbacks;
449 
450     RtlZeroMemory(pHalInfo,sizeof(DD_HALINFO));
451     RtlZeroMemory(pCallBackFlags,sizeof(DWORD)*3);
452     RtlZeroMemory(puD3dCallbacks,sizeof(D3DNTHAL_CALLBACKS));
453     RtlZeroMemory(puD3dDriverData,sizeof(D3DNTHAL_CALLBACKS));
454 
455     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
456                                         pCallBackFlags, puD3dCallbacks,
457                                         puD3dDriverData, puD3dBufferCallbacks,
458                                         puD3dTextureFormats, puNumHeaps,
459                                         puvmList, puNumFourCC,
460                                         puFourCC)== FALSE);
461     RTEST(pHalInfo != NULL);
462     RTEST(pCallBackFlags != NULL);
463 
464     if (pHalInfo->ddCaps.ddsCaps.dwCaps  & DDSCAPS_3DDEVICE )
465     {
466         RTEST(puD3dCallbacks != NULL);
467         RTEST(puD3dDriverData != NULL);
468         RTEST(puD3dBufferCallbacks != NULL);
469     }
470 
471     RTEST(pHalInfo != NULL);
472     ASSERT(pHalInfo != NULL);
473 
474     RTEST(pCallBackFlags != NULL);
475     ASSERT(pCallBackFlags != NULL);
476 
477     RTEST(puD3dCallbacks != NULL);
478     ASSERT(puD3dCallbacks != NULL);
479 
480     RTEST(puD3dDriverData != NULL);
481     ASSERT(puD3dDriverData != NULL);
482 
483     RTEST(puD3dBufferCallbacks != NULL);
484     ASSERT(puD3dDriverData != NULL);
485 
486     RTEST(puD3dTextureFormats == NULL);
487     RTEST(puNumFourCC == NULL);
488     RTEST(puFourCC == NULL);
489     RTEST(puNumHeaps == NULL);
490     RTEST(puvmList == NULL);
491 
492     /* We retesting the flags */
493     RTEST(pCallBackFlags[0] != 0);
494     RTEST(pCallBackFlags[1] != 0);
495     RTEST(pCallBackFlags[2] == 0);
496 
497     /* We do not retesting instead we compare it */
498     RTEST(memcmp(&oldHalInfo, pHalInfo, sizeof(DD_HALINFO)) == 0);
499     RTEST(memcmp(&oldD3dCallbacks, puD3dCallbacks, sizeof(D3DNTHAL_CALLBACKS)) == 0);
500     RTEST(memcmp(&oldD3dDriverData, puD3dDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA)) == 0);
501 
502     /* start test of puD3dBufferCallbacks */
503     RTEST(puD3dBufferCallbacks->dwSize == sizeof(DD_D3DBUFCALLBACKS));
504     if (puD3dBufferCallbacks->dwFlags & DDHAL_D3DBUFCB32_CANCREATED3DBUF)
505     {
506         /* point to kmode direcly to the graphic drv, the drv is kmode and it is kmode address we getting back*/
507         RTEST( ( (DWORD_PTR)puD3dBufferCallbacks->CanCreateD3DBuffer & (~0x80000000)) != 0 );
508     }
509     else
510     {
511         RTEST( puD3dBufferCallbacks->CanCreateD3DBuffer == NULL);
512     }
513 
514     if (puD3dBufferCallbacks->dwFlags & DDHAL_D3DBUFCB32_CREATED3DBUF)
515     {
516         /* point to kmode direcly to the graphic drv, the drv is kmode and it is kmode address we getting back*/
517         RTEST( ( (DWORD_PTR)puD3dBufferCallbacks->CreateD3DBuffer & (~0x80000000)) != 0 );
518     }
519     else
520     {
521         RTEST( puD3dBufferCallbacks->CreateD3DBuffer == NULL);
522     }
523 
524     if (puD3dBufferCallbacks->dwFlags & DDHAL_D3DBUFCB32_DESTROYD3DBUF)
525     {
526         /* point to kmode direcly to the graphic drv, the drv is kmode and it is kmode address we getting back*/
527         RTEST( ( (DWORD_PTR)puD3dBufferCallbacks->DestroyD3DBuffer & (~0x80000000)) != 0 );
528     }
529     else
530     {
531         RTEST( puD3dBufferCallbacks->DestroyD3DBuffer == NULL);
532     }
533 
534     if (puD3dBufferCallbacks->dwFlags & DDHAL_D3DBUFCB32_LOCKD3DBUF)
535     {
536         /* point to kmode direcly to the graphic drv, the drv is kmode and it is kmode address we getting back*/
537         RTEST( ( (DWORD_PTR)puD3dBufferCallbacks->LockD3DBuffer & (~0x80000000)) != 0 );
538     }
539     else
540     {
541         RTEST( puD3dBufferCallbacks->LockD3DBuffer == NULL);
542     }
543 
544     if (puD3dBufferCallbacks->dwFlags & DDHAL_D3DBUFCB32_UNLOCKD3DBUF)
545     {
546         /* point to kmode direcly to the graphic drv, the drv is kmode and it is kmode address we getting back*/
547         RTEST( ( (DWORD_PTR)puD3dBufferCallbacks->UnlockD3DBuffer & (~0x80000000)) != 0 );
548     }
549     else
550     {
551         RTEST( puD3dBufferCallbacks->UnlockD3DBuffer == NULL);
552     }
553 
554     /* Backup DD_D3DBUFCALLBACKS so we do not need resting it */
555     RtlCopyMemory(&oldD3dBufferCallbacks, &D3dBufferCallbacks, sizeof(DD_D3DBUFCALLBACKS));
556 
557 
558 /* testing  NtGdiDdQueryDirectDrawObject( hDD, pHalInfo, pCallBackFlags, puD3dCallbacks, puD3dDriverData, puD3dBufferCallbacks, puD3dTextureFormats, NULL, */
559     pHalInfo = &HalInfo;
560     pCallBackFlags = CallBackFlags;
561     puD3dCallbacks = &D3dCallbacks;
562     puD3dDriverData = &D3dDriverData;
563     puD3dBufferCallbacks = &D3dBufferCallbacks;
564 
565     /* It is forbein to return a  DDSURFACEDESC2 it should always be DDSURFACEDESC
566         This is only for detected bad drivers that does not follow the rules, if they
567         does not follow tthe rules, not everthing being copy then in gdi32.dll
568         gdi32.dll always assume it is DDSURFACEDESC size
569     */
570     if (puD3dDriverData->dwNumTextureFormats != 0)
571     {
572         puD3dTextureFormats = malloc (puD3dDriverData->dwNumTextureFormats * sizeof(DDSURFACEDESC2));
573     }
574 
575     RtlZeroMemory(pHalInfo,sizeof(DD_HALINFO));
576     RtlZeroMemory(pCallBackFlags,sizeof(DWORD)*3);
577     RtlZeroMemory(puD3dCallbacks,sizeof(D3DNTHAL_CALLBACKS));
578     RtlZeroMemory(puD3dDriverData,sizeof(D3DNTHAL_GLOBALDRIVERDATA));
579     RtlZeroMemory(&D3dBufferCallbacks,sizeof(DD_D3DBUFCALLBACKS));
580 
581     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
582                                         pCallBackFlags, puD3dCallbacks,
583                                         puD3dDriverData, puD3dBufferCallbacks,
584                                         puD3dTextureFormats, puNumHeaps,
585                                         puvmList, puNumFourCC,
586                                         puFourCC)== FALSE);
587 
588     RTEST(pHalInfo != NULL);
589     ASSERT(pHalInfo != NULL);
590 
591     RTEST(pCallBackFlags != NULL);
592     ASSERT(pCallBackFlags != NULL);
593 
594     RTEST(puD3dCallbacks != NULL);
595     ASSERT(puD3dCallbacks != NULL);
596 
597     RTEST(puD3dDriverData != NULL);
598     ASSERT(puD3dDriverData != NULL);
599 
600     RTEST(puD3dBufferCallbacks != NULL);
601     ASSERT(puD3dDriverData != NULL);
602 
603     RTEST(puD3dTextureFormats != NULL);
604     ASSERT(puD3dTextureFormats != NULL);
605 
606     RTEST(puNumFourCC == NULL);
607     RTEST(puFourCC == NULL);
608     RTEST(puNumHeaps == NULL);
609     RTEST(puvmList == NULL);
610 
611     /* We retesting the flags */
612     RTEST(pCallBackFlags[0] != 0);
613     RTEST(pCallBackFlags[1] != 0);
614     RTEST(pCallBackFlags[2] == 0);
615 
616     /* We do not retesting instead we compare it */
617     RTEST(memcmp(&oldHalInfo, pHalInfo, sizeof(DD_HALINFO)) == 0);
618     RTEST(memcmp(&oldD3dCallbacks, puD3dCallbacks, sizeof(D3DNTHAL_CALLBACKS)) == 0);
619     RTEST(memcmp(&oldD3dDriverData, puD3dDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA)) == 0);
620     RTEST(memcmp(&oldD3dBufferCallbacks, puD3dBufferCallbacks, sizeof(DD_D3DBUFCALLBACKS)) == 0);
621 
622     /* start test of dwNumTextureFormats */
623     if (puD3dDriverData->dwNumTextureFormats != 0)
624     {
625         myDesc = puD3dTextureFormats;
626         for (dwTextureCounter=0;dwTextureCounter<puD3dDriverData->dwNumTextureFormats;dwTextureCounter++)
627         {
628             RTEST(myDesc->dwSize == sizeof(DDSURFACEDESC));
629             ASSERT(myDesc->dwSize == sizeof(DDSURFACEDESC));
630 
631             RTEST( (myDesc->dwFlags & (~(DDSD_CAPS|DDSD_PIXELFORMAT))) == 0);
632             RTEST(myDesc->dwHeight == 0);
633             RTEST(myDesc->dwWidth == 0);
634             RTEST(myDesc->dwLinearSize == 0);
635             RTEST(myDesc->dwBackBufferCount == 0);
636             RTEST(myDesc->dwZBufferBitDepth == 0);
637             RTEST(myDesc->dwAlphaBitDepth == 0);
638             RTEST(myDesc->dwReserved == 0);
639             RTEST(myDesc->lpSurface == 0);
640             RTEST(myDesc->ddckCKDestOverlay.dwColorSpaceLowValue == 0);
641             RTEST(myDesc->ddckCKDestOverlay.dwColorSpaceHighValue == 0);
642             RTEST(myDesc->ddckCKDestBlt.dwColorSpaceLowValue == 0);
643             RTEST(myDesc->ddckCKDestBlt.dwColorSpaceHighValue == 0);
644             RTEST(myDesc->ddckCKSrcOverlay.dwColorSpaceLowValue == 0);
645             RTEST(myDesc->ddckCKSrcOverlay.dwColorSpaceHighValue == 0);
646             RTEST(myDesc->ddckCKSrcBlt.dwColorSpaceLowValue == 0);
647             RTEST(myDesc->ddckCKSrcBlt.dwColorSpaceHighValue == 0);
648             RTEST(myDesc->ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT));
649             RTEST(myDesc->ddpfPixelFormat.dwFlags != 0);
650             if (myDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC)
651             {
652                 RTEST(myDesc->ddpfPixelFormat.dwFourCC != 0);
653             }
654             RTEST(myDesc->ddsCaps.dwCaps == DDSCAPS_TEXTURE);
655 
656             myDesc = (DDSURFACEDESC *) (((DWORD_PTR) myDesc) + sizeof(DDSURFACEDESC));
657         }
658     }
659 
660 
661     /* testing  NtGdiDdQueryDirectDrawObject( hDD, pHalInfo, pCallBackFlags, puD3dCallbacks, puD3dDriverData, puD3dBufferCallbacks, puD3dTextureFormats, puNumHeaps, NULL, */
662     pHalInfo = &HalInfo;
663     pCallBackFlags = CallBackFlags;
664     puD3dCallbacks = &D3dCallbacks;
665     puD3dDriverData = &D3dDriverData;
666     puD3dBufferCallbacks = &D3dBufferCallbacks;
667     puNumHeaps = &NumHeaps;
668 
669     if (puD3dDriverData->dwNumTextureFormats != 0)
670     {
671         RtlZeroMemory(puD3dTextureFormats, puD3dDriverData->dwNumTextureFormats * sizeof(DDSURFACEDESC2));
672     }
673     RtlZeroMemory(pHalInfo,sizeof(DD_HALINFO));
674     RtlZeroMemory(pCallBackFlags,sizeof(DWORD)*3);
675     RtlZeroMemory(puD3dCallbacks,sizeof(D3DNTHAL_CALLBACKS));
676     RtlZeroMemory(puD3dDriverData,sizeof(D3DNTHAL_GLOBALDRIVERDATA));
677     RtlZeroMemory(&D3dBufferCallbacks,sizeof(DD_D3DBUFCALLBACKS));
678 
679     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
680                                         pCallBackFlags, puD3dCallbacks,
681                                         puD3dDriverData, puD3dBufferCallbacks,
682                                         puD3dTextureFormats, puNumHeaps,
683                                         puvmList, puNumFourCC,
684                                         puFourCC)== FALSE);
685 
686     RTEST(pHalInfo != NULL);
687     ASSERT(pHalInfo != NULL);
688 
689     RTEST(pCallBackFlags != NULL);
690     ASSERT(pCallBackFlags != NULL);
691 
692     RTEST(puD3dCallbacks != NULL);
693     ASSERT(puD3dCallbacks != NULL);
694 
695     RTEST(puD3dDriverData != NULL);
696     ASSERT(puD3dDriverData != NULL);
697 
698     RTEST(puD3dBufferCallbacks != NULL);
699     ASSERT(puD3dDriverData != NULL);
700 
701     RTEST(puD3dTextureFormats != NULL);
702     ASSERT(puD3dTextureFormats != NULL);
703 
704     RTEST(puNumHeaps != NULL);
705     ASSERT(puNumHeaps != NULL);
706     RTEST(NumHeaps == 0);
707 
708     RTEST(puNumFourCC == NULL);
709     RTEST(puFourCC == NULL);
710 
711     RTEST(puvmList == NULL);
712 
713     /* We retesting the flags */
714     RTEST(pCallBackFlags[0] != 0);
715     RTEST(pCallBackFlags[1] != 0);
716     RTEST(pCallBackFlags[2] == 0);
717 
718     /* We do not retesting instead we compare it */
719     RTEST(memcmp(&oldHalInfo, pHalInfo, sizeof(DD_HALINFO)) == 0);
720     RTEST(memcmp(&oldD3dCallbacks, puD3dCallbacks, sizeof(D3DNTHAL_CALLBACKS)) == 0);
721     RTEST(memcmp(&oldD3dDriverData, puD3dDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA)) == 0);
722     RTEST(memcmp(&oldD3dBufferCallbacks, puD3dBufferCallbacks, sizeof(DD_D3DBUFCALLBACKS)) == 0);
723     /* we skip resting texture */
724 
725 
726     /* testing  NtGdiDdQueryDirectDrawObject( hDD, pHalInfo, pCallBackFlags, puD3dCallbacks, puD3dDriverData, puD3dBufferCallbacks, puD3dTextureFormats, puNumHeaps, puvmList, NULL, */
727     pHalInfo = &HalInfo;
728     pCallBackFlags = CallBackFlags;
729     puD3dCallbacks = &D3dCallbacks;
730     puD3dDriverData = &D3dDriverData;
731     puD3dBufferCallbacks = &D3dBufferCallbacks;
732     puNumHeaps = &NumHeaps;
733     puvmList = &vmList;
734 
735     if (puD3dDriverData->dwNumTextureFormats != 0)
736     {
737         RtlZeroMemory(puD3dTextureFormats, puD3dDriverData->dwNumTextureFormats * sizeof(DDSURFACEDESC2));
738     }
739     RtlZeroMemory(pHalInfo,sizeof(DD_HALINFO));
740     RtlZeroMemory(pCallBackFlags,sizeof(DWORD)*3);
741     RtlZeroMemory(puD3dCallbacks,sizeof(D3DNTHAL_CALLBACKS));
742     RtlZeroMemory(puD3dDriverData,sizeof(D3DNTHAL_GLOBALDRIVERDATA));
743     RtlZeroMemory(&D3dBufferCallbacks,sizeof(DD_D3DBUFCALLBACKS));
744 
745     RTEST(NtGdiDdQueryDirectDrawObject( hDirectDraw, pHalInfo,
746                                         pCallBackFlags, puD3dCallbacks,
747                                         puD3dDriverData, puD3dBufferCallbacks,
748                                         puD3dTextureFormats, puNumHeaps,
749                                         puvmList, puNumFourCC,
750                                         puFourCC)== FALSE);
751 
752     RTEST(pHalInfo != NULL);
753     ASSERT(pHalInfo != NULL);
754 
755     RTEST(pCallBackFlags != NULL);
756     ASSERT(pCallBackFlags != NULL);
757 
758     RTEST(puD3dCallbacks != NULL);
759     ASSERT(puD3dCallbacks != NULL);
760 
761     RTEST(puD3dDriverData != NULL);
762     ASSERT(puD3dDriverData != NULL);
763 
764     RTEST(puD3dBufferCallbacks != NULL);
765     ASSERT(puD3dDriverData != NULL);
766 
767     RTEST(puD3dTextureFormats != NULL);
768     ASSERT(puD3dTextureFormats != NULL);
769 
770     RTEST(puNumHeaps != NULL);
771     ASSERT(puNumHeaps != NULL);
772     RTEST(NumHeaps == 0);
773 
774     RTEST(puvmList != NULL);
775 
776     RTEST(puNumFourCC == NULL);
777     RTEST(puFourCC == NULL);
778 
779 
780 
781     /* We retesting the flags */
782     RTEST(pCallBackFlags[0] != 0);
783     RTEST(pCallBackFlags[1] != 0);
784     RTEST(pCallBackFlags[2] == 0);
785 
786     /* We do not retesting instead we compare it */
787     RTEST(memcmp(&oldHalInfo, pHalInfo, sizeof(DD_HALINFO)) == 0);
788     RTEST(memcmp(&oldD3dCallbacks, puD3dCallbacks, sizeof(D3DNTHAL_CALLBACKS)) == 0);
789     RTEST(memcmp(&oldD3dDriverData, puD3dDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA)) == 0);
790     RTEST(memcmp(&oldD3dBufferCallbacks, puD3dBufferCallbacks, sizeof(DD_D3DBUFCALLBACKS)) == 0);
791     /* we skip resting texture */
792 
793     /* Todo
794     * adding test for
795     * puNumFourCC
796     * puFourCC
797     */
798 
799     ok(NtGdiDdDeleteDirectDrawObject(hDirectDraw) == TRUE,
800        "NtGdiDdDeleteDirectDrawObject() failed\n");
801 
802     ok(DeleteDC(hdc) != 0, "DeleteDC() failed\n");
803 }
804