1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for NtGdiCreateDIBSection
5  * PROGRAMMERS:
6  */
7 
8 #include "../win32nt.h"
9 
10 /*
11 HBITMAP
12 APIENTRY
13 NtGdiCreateDIBSection(
14     IN HDC hDC,
15     IN OPTIONAL HANDLE hSection,
16     IN DWORD dwOffset,
17     IN LPBITMAPINFO pbmi,
18     IN DWORD iUsage,
19     IN UINT cjHeader,
20     IN FLONG fl,
21     IN ULONG_PTR dwColorSpace,
22     OUT PVOID *ppvBits)
23 */
24 
25 ULONG
26 GetBitmapSize(BITMAPINFOHEADER *pbih)
27 {
28     ULONG WidthBits, WidthBytes;
29 
30     WidthBits = pbih->biWidth * pbih->biBitCount * pbih->biPlanes;
31     WidthBytes = ((WidthBits + 31) & ~ 31) >> 3;
32 
33     return pbih->biHeight * WidthBytes;
34 }
35 
36 
37 START_TEST(NtGdiCreateDIBSection)
38 {
39     HBITMAP hbmp;
40     HDC hDC;
41     ULONG cjHeader;
42     PVOID pvBits = NULL;
43     ULONG cEntries;
44     DIBSECTION dibsection;
45 
46     struct
47     {
48         BITMAPINFOHEADER bmiHeader;
49         RGBQUAD          bmiColors[100];
50     } bmi;
51     PBITMAPINFO pbmi = (PBITMAPINFO)&bmi;
52     PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)&bmi.bmiHeader;
53     PBITMAPV4HEADER pbV4h = (PBITMAPV4HEADER)&bmi.bmiHeader;
54     PBITMAPV5HEADER pbV5h = (PBITMAPV5HEADER)&bmi.bmiHeader;
55 
56     HANDLE hSection;
57     NTSTATUS Status;
58     LARGE_INTEGER MaximumSize;
59 
60     hDC = GetDC(0);
61     pbih->biSize = sizeof(BITMAPINFOHEADER);
62     pbih->biWidth = 2;
63     pbih->biHeight = 2;
64     pbih->biPlanes = 1;
65     pbih->biBitCount = 1;
66     pbih->biCompression = BI_RGB;
67     pbih->biSizeImage = 0;
68     pbih->biXPelsPerMeter = 100;
69     pbih->biYPelsPerMeter = 100;
70     pbih->biClrUsed = 2;
71     pbih->biClrImportant = 2;
72 
73     cEntries = 0;
74 
75 /** iUsage = 0 (DIB_RGB_COLORS) ***********************************************/
76 
77     cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 8;
78 
79     /* Test something simple */
80     SetLastError(0);
81     pvBits = 0;
82     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
83     TEST(pvBits != NULL);
84     TEST(hbmp != 0);
85 //    TEST(GetLastError() == 0);
86     TEST(GetObject(hbmp, sizeof(DIBSECTION), &dibsection) == sizeof(DIBSECTION));
87     TEST(dibsection.dsBitfields[0] == 0);
88     TEST(dibsection.dsBitfields[1] == 0);
89     TEST(dibsection.dsBitfields[2] == 0);
90     TEST(dibsection.dshSection == 0);
91     TEST(dibsection.dsOffset == 0);
92     if (hbmp) DeleteObject(hbmp);
93 
94 
95     /* Test a 0 HDC */
96     SetLastError(0xdeadbeef);
97     pvBits = 0;
98     hbmp = NtGdiCreateDIBSection(0, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
99     TEST(pvBits != NULL);
100     TEST(hbmp != 0);
101     ok_hex(GetLastError(), 0xdeadbeef);
102     if (hbmp) DeleteObject(hbmp);
103 
104     /* Test a wrong HDC */
105     SetLastError(0xdeadbeef);
106     pvBits = 0;
107     hbmp = NtGdiCreateDIBSection((HDC)(LONG_PTR)0xdeadbeef, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
108     TEST(pvBits != 0);
109     TEST(hbmp != 0);
110     ok_hex(GetLastError(), 0xdeadbeef);
111     if (hbmp) DeleteObject(hbmp);
112 
113     /* Test pbmi = NULL */
114     SetLastError(0);
115     pvBits = (PVOID)-1;
116     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, NULL, 0, cjHeader, 0, 0, &pvBits);
117     TEST(pvBits == (PVOID)-1);
118     TEST(hbmp == 0);
119     TEST(GetLastError() == 0);
120     if (hbmp) DeleteObject(hbmp);
121 
122     /* Test invalid pbmi */
123     SetLastError(0);
124     pvBits = (PVOID)-1;
125     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, (PVOID)(LONG_PTR)0x80001234, 0, cjHeader, 0, 0, &pvBits);
126     TEST(pvBits == (PVOID)-1);
127     TEST(hbmp == 0);
128     TEST(GetLastError() == ERROR_INVALID_PARAMETER);
129     if (hbmp) DeleteObject(hbmp);
130 
131     /* Test invalid pbmi */
132     SetLastError(0);
133     pvBits = (PVOID)-1;
134     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, (PVOID)(LONG_PTR)1, 0, cjHeader, 0, 0, &pvBits);
135     TEST(pvBits == (PVOID)-1);
136     TEST(hbmp == 0);
137     TEST(GetLastError() == ERROR_INVALID_PARAMETER);
138     if (hbmp) DeleteObject(hbmp);
139 
140     /* Test ppvBits = NULL */
141     SetLastError(0);
142     hbmp = NtGdiCreateDIBSection(0, NULL, 0, pbmi, 0, cjHeader, 0, 0, NULL);
143     TEST(hbmp == 0);
144     TEST(GetLastError() == ERROR_INVALID_PARAMETER);
145     if (hbmp) DeleteObject(hbmp);
146 
147     /* Test ppvBits = NULL and pbmi == 0*/
148     SetLastError(0);
149     hbmp = NtGdiCreateDIBSection(0, NULL, 0, NULL, 0, cjHeader, 0, 0, NULL);
150     TEST(hbmp == 0);
151     TEST(GetLastError() == 0);
152     if (hbmp) DeleteObject(hbmp);
153 
154     /* Test ppvBits = NULL and wrong cjHeader */
155     SetLastError(0);
156     hbmp = NtGdiCreateDIBSection(0, NULL, 0, pbmi, 0, cjHeader+4, 0, 0, NULL);
157     TEST(hbmp == 0);
158     TEST(GetLastError() == 0);
159     if (hbmp) DeleteObject(hbmp);
160 
161     /* Test ppvBits = NULL and cjHeader = 0 */
162     SetLastError(0);
163     hbmp = NtGdiCreateDIBSection(0, NULL, 0, pbmi, 0, 0, 0, 0, NULL);
164     TEST(hbmp == 0);
165     TEST(GetLastError() == 0);
166     if (hbmp) DeleteObject(hbmp);
167 
168     /* Test wrong cjHeader */
169     SetLastError(0);
170     pvBits = (PVOID)-1;
171     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader+4, 0, 0, &pvBits);
172     pvBits = (PVOID)-1;
173     TEST(hbmp == 0);
174     TEST(GetLastError() == 0);
175     if (hbmp) DeleteObject(hbmp);
176 
177     /* Test different bitcount */
178     pbih->biBitCount = 4;
179     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
180     TEST(hbmp != 0);
181     if (hbmp) DeleteObject(hbmp);
182 
183     pbih->biBitCount = 8;
184     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
185     TEST(hbmp != 0);
186     if (hbmp) DeleteObject(hbmp);
187 
188     cjHeader = pbih->biSize;
189     pbih->biBitCount = 16;
190     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
191     TEST(hbmp != 0);
192     if (hbmp) DeleteObject(hbmp);
193 
194     pbih->biBitCount = 24;
195     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
196     TEST(hbmp != 0);
197     if (hbmp) DeleteObject(hbmp);
198 
199     pbih->biBitCount = 32;
200     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
201     TEST(hbmp != 0);
202     if (hbmp) DeleteObject(hbmp);
203 
204     /* Test BI_BITFIELDS */
205     cEntries = 3;
206     cjHeader = pbih->biSize + cEntries * sizeof(DWORD);
207     pbih->biBitCount = 16;
208     pbih->biCompression = BI_BITFIELDS;
209     ((DWORD*)pbmi->bmiColors)[0] = 0x0007;
210     ((DWORD*)pbmi->bmiColors)[1] = 0x0038;
211     ((DWORD*)pbmi->bmiColors)[2] = 0x01C0;
212     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
213     TEST(hbmp != 0);
214     TEST(GetObject(hbmp, sizeof(DIBSECTION), &dibsection) == sizeof(DIBSECTION));
215     TEST(dibsection.dsBm.bmType == 0);
216     TEST(dibsection.dsBm.bmWidth == 2);
217     TEST(dibsection.dsBm.bmHeight == 2);
218     TEST(dibsection.dsBm.bmWidthBytes == 4);
219     TEST(dibsection.dsBm.bmPlanes == 1);
220     TEST(dibsection.dsBm.bmBitsPixel == 16);
221     TEST(dibsection.dsBm.bmBits == pvBits);
222     TEST(dibsection.dsBmih.biSize == sizeof(BITMAPINFOHEADER));
223     TEST(dibsection.dsBmih.biWidth == 2);
224     TEST(dibsection.dsBmih.biHeight == 2);
225     TEST(dibsection.dsBmih.biPlanes == 1);
226     TEST(dibsection.dsBmih.biBitCount == 16);
227     TEST(dibsection.dsBmih.biCompression == BI_BITFIELDS);
228     TEST(dibsection.dsBmih.biSizeImage == 8);
229     TEST(dibsection.dsBmih.biXPelsPerMeter == 0);
230     TEST(dibsection.dsBmih.biYPelsPerMeter == 0);
231     TEST(dibsection.dsBmih.biClrUsed == 0);
232     TEST(dibsection.dsBmih.biClrImportant == 0);
233     TEST(dibsection.dsBitfields[0] == 0x0007);
234     TEST(dibsection.dsBitfields[1] == 0x0038);
235     TEST(dibsection.dsBitfields[2] == 0x01C0);
236     TEST(dibsection.dshSection == 0);
237     TEST(dibsection.dsOffset == 0);
238 
239 printf("dib with bitfileds: %p\n", hbmp);
240 //system("PAUSE");
241 
242     if (hbmp) DeleteObject(hbmp);
243 
244 
245     /* Test BI_BITFIELDS */
246     SetLastError(0);
247     pvBits = 0;
248 
249     pbih->biSize = sizeof(BITMAPINFOHEADER);
250     pbih->biWidth = 2;
251     pbih->biHeight = 2;
252     pbih->biPlanes = 1;
253     pbih->biBitCount = 4;
254     pbih->biCompression = BI_RGB;
255     pbih->biSizeImage = 0;
256     pbih->biXPelsPerMeter = 100;
257     pbih->biYPelsPerMeter = 100;
258     pbih->biClrUsed = 0;
259     pbih->biClrImportant = 0;
260     ((DWORD*)pbmi->bmiColors)[0] = 0xF800;
261     ((DWORD*)pbmi->bmiColors)[1] = 0x00ff00;
262     ((DWORD*)pbmi->bmiColors)[2] = 0x0000ff;
263     cEntries = 0;
264     cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 20;
265 
266 
267 /** iUsage = 1 (DIB_PAL_COLORS) ***********************************************/
268 
269     pbmi->bmiHeader.biClrUsed = 2;
270     pbmi->bmiHeader.biClrImportant = 2;
271 
272     cEntries = 2;
273     cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 8;
274 
275     /* Test iUsage = 1 */
276     SetLastError(0);
277     pvBits = (PVOID)-1;
278     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 1, cjHeader, 0, 0, &pvBits);
279     TEST(pvBits == (PVOID)-1);
280     TEST(hbmp == 0);
281     TEST(GetLastError() == 0);
282     if (hbmp) DeleteObject(hbmp);
283 
284 
285 
286 /** iUsage = 2 (???) **********************************************************/
287 
288     /* Test iUsage = 2 */
289     SetLastError(0);
290     pvBits = (PVOID)-1;
291     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 2, cjHeader, 0, 0, &pvBits);
292     TEST(pvBits == (PVOID)-1);
293     TEST(hbmp == 0);
294     TEST(GetLastError() == 0);
295     if (hbmp) DeleteObject(hbmp);
296 
297 
298 /** wrong iUsage **************************************************************/
299 
300     cEntries = 0;
301     cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 8;
302 
303     /* Test iUsage = 3 */
304     SetLastError(0);
305     pvBits = (PVOID)-1;
306     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 3, cjHeader, 0, 0, &pvBits);
307     TEST(pvBits == (PVOID)-1);
308     TEST(hbmp == 0);
309     TEST(GetLastError() == ERROR_INVALID_PARAMETER);
310     if (hbmp) DeleteObject(hbmp);
311 
312     /* Test iUsage = 3 */
313     SetLastError(0);
314     pvBits = (PVOID)-1;
315     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 3, cjHeader+4, 0, 0, &pvBits);
316     TEST(pvBits == (PVOID)-1);
317     TEST(hbmp == 0);
318     TEST(GetLastError() == 0);
319     if (hbmp) DeleteObject(hbmp);
320 
321     /* Test wrong iUsage */
322     SetLastError(0);
323     pvBits = (PVOID)-1;
324     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, -55, cjHeader, 0, 0, &pvBits);
325     TEST(pvBits == (PVOID)-1);
326     TEST(hbmp == 0);
327     TEST(GetLastError() == ERROR_INVALID_PARAMETER);
328     if (hbmp) DeleteObject(hbmp);
329 
330     /* Test wrong iUsage and wrong cjHeader */
331     SetLastError(0);
332     pvBits = (PVOID)-1;
333     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, -55, cjHeader+4, 0, 0, &pvBits);
334     TEST(pvBits == (PVOID)-1);
335     TEST(hbmp == 0);
336     TEST(GetLastError() == 0);
337     if (hbmp) DeleteObject(hbmp);
338 
339     /* increased header size */
340     pbih->biSize = sizeof(BITMAPINFOHEADER) + 4;
341     cjHeader = pbih->biSize + cEntries * 4 + 8;
342     SetLastError(0xdeadbeef);
343     pvBits = 0;
344     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
345     TEST(pvBits != NULL);
346     TEST(hbmp != 0);
347     ok_hex(GetLastError(), 0xdeadbeef);
348     if (hbmp) DeleteObject(hbmp);
349 
350     /* increased header size */
351     pbih->biSize = sizeof(BITMAPINFOHEADER) + 2;
352     cjHeader = pbih->biSize + cEntries * 4 + 8;
353     SetLastError(0);
354     pvBits = (PVOID)-1;
355     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
356     TEST(pvBits == (PVOID)-1);
357     TEST(hbmp == 0);
358     TEST(GetLastError() == 0);
359     if (hbmp) DeleteObject(hbmp);
360 
361     /* decreased header size */
362     pbih->biSize = sizeof(BITMAPINFOHEADER) - 4;
363     cjHeader = pbih->biSize + cEntries * 4 + 8;
364     SetLastError(0);
365     pvBits = (PVOID)-1;
366     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
367     TEST(pvBits == (PVOID)-1);
368     TEST(hbmp == 0);
369     TEST(GetLastError() == 0);
370     if (hbmp) DeleteObject(hbmp);
371 
372 
373 /** BITMAPV4HEADER ************************************************************/
374 
375     pbV4h->bV4Size = sizeof(BITMAPV4HEADER);
376     pbV4h->bV4Width = 2;
377     pbV4h->bV4Height = 3;
378     pbV4h->bV4Planes = 1;
379     pbV4h->bV4BitCount = 1;
380     pbV4h->bV4V4Compression = BI_RGB;
381     pbV4h->bV4SizeImage = 0;
382     pbV4h->bV4XPelsPerMeter = 100;
383     pbV4h->bV4YPelsPerMeter = 100;
384     pbV4h->bV4ClrUsed = 0;
385     pbV4h->bV4ClrImportant = 0;
386     pbV4h->bV4RedMask = 0;
387     pbV4h->bV4GreenMask = 0;
388     pbV4h->bV4BlueMask = 0;
389     pbV4h->bV4AlphaMask = 0;
390     pbV4h->bV4CSType = 0;
391     memset(&pbV4h->bV4Endpoints, 0, sizeof(CIEXYZTRIPLE));
392     pbV4h->bV4GammaRed = 0;
393     pbV4h->bV4GammaGreen = 0;
394     pbV4h->bV4GammaBlue = 0;
395 
396     cEntries = 0;
397     cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 8;
398 
399     /* Test something simple */
400     SetLastError(0xdeadbeef);
401     pvBits = 0;
402     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
403     TEST(pvBits != NULL);
404     TEST(hbmp != 0);
405     ok_hex(GetLastError(), 0xdeadbeef);
406     if (hbmp) DeleteObject(hbmp);
407 
408 
409 /** BITMAPV5HEADER ************************************************************/
410 
411     pbV5h->bV5Size = sizeof(BITMAPV5HEADER);
412     pbV5h->bV5Width = 2;
413     pbV5h->bV5Height = 3;
414     pbV5h->bV5Planes = 1;
415     pbV5h->bV5BitCount = 1;
416     pbV5h->bV5Compression = BI_RGB;
417     pbV5h->bV5SizeImage = 0;
418     pbV5h->bV5XPelsPerMeter = 100;
419     pbV5h->bV5YPelsPerMeter = 100;
420     pbV5h->bV5ClrUsed = 2;
421     pbV5h->bV5ClrImportant = 2;
422     pbV5h->bV5RedMask = 0;
423     pbV5h->bV5GreenMask = 0;
424     pbV5h->bV5BlueMask = 0;
425     pbV5h->bV5AlphaMask = 0;
426     pbV5h->bV5CSType = 0;
427     memset(&pbV5h->bV5Endpoints, 0, sizeof(CIEXYZTRIPLE));
428     pbV5h->bV5GammaRed = 0;
429     pbV5h->bV5GammaGreen = 0;
430     pbV5h->bV5GammaBlue = 0;
431     pbV5h->bV5Intent = 0;
432     pbV5h->bV5ProfileData = 0;
433     pbV5h->bV5ProfileSize = 0;
434     pbV5h->bV5Reserved = 0;
435 
436     cEntries = 0;
437     cjHeader = pbV5h->bV5Size + cEntries * 4 + 8;
438 
439     /* Test something simple */
440     SetLastError(0xdeadbeef);
441     pvBits = 0;
442     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
443     TEST(pvBits != NULL);
444     TEST(hbmp != 0);
445     ok_hex(GetLastError(), 0xdeadbeef);
446     if (hbmp) DeleteObject(hbmp);
447 
448     /* increased header size */
449     pbV5h->bV5Size = sizeof(BITMAPV5HEADER) + 64;
450     cjHeader = pbV5h->bV5Size + cEntries * 4 + 8;
451     SetLastError(0xdeadbeef);
452     pvBits = 0;
453     hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
454     TEST(pvBits != NULL);
455     TEST(hbmp != 0);
456     ok_hex(GetLastError(), 0xdeadbeef);
457     if (hbmp) DeleteObject(hbmp);
458 
459     /* Test section */
460     MaximumSize.QuadPart = 4096;
461     Status = NtCreateSection(&hSection,
462                              SECTION_ALL_ACCESS,
463                              NULL,
464                              &MaximumSize,
465                              PAGE_READWRITE,
466                              SEC_COMMIT,
467                              NULL);
468     ASSERT(NT_SUCCESS(Status));
469 
470     SetLastError(0);
471     pvBits = 0;
472     hbmp = NtGdiCreateDIBSection(hDC, hSection, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
473     TEST(pvBits != NULL);
474     TEST(hbmp != 0);
475 //    TEST(GetLastError() == 0);
476     printf("hbmp = %p, pvBits = %p, hSection = %p\n", hbmp, pvBits, hSection);
477 //system("PAUSE");
478     if (hbmp) DeleteObject(hbmp);
479 }
480