1 /*
2  * PROJECT:     ReactOS Print Spooler DLL API Tests
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Tests for IsValidDevmodeA/IsValidDevmodeW
5  * COPYRIGHT:   Copyright 2016 Colin Finck (colin@reactos.org)
6  */
7 
8 #include <apitest.h>
9 
10 #define WIN32_NO_STATUS
11 #include <windef.h>
12 #include <winbase.h>
13 #include <wingdi.h>
14 #include <winspool.h>
15 #include <wchar.h>
16 
17 typedef struct _MINIMUM_SIZE_TABLE
18 {
19     DWORD dwField;
20     WORD wSize;
21 }
22 MINIMUM_SIZE_TABLE, *PMINIMUM_SIZE_TABLE;
23 
24 static MINIMUM_SIZE_TABLE MinimumSizeA[] = {
25     { DM_PANNINGHEIGHT, FIELD_OFFSET(DEVMODEA, dmPanningHeight) + RTL_FIELD_SIZE(DEVMODEA, dmPanningHeight) },
26     { DM_PANNINGWIDTH, FIELD_OFFSET(DEVMODEA, dmPanningWidth) + RTL_FIELD_SIZE(DEVMODEA, dmPanningWidth) },
27     { DM_DITHERTYPE, FIELD_OFFSET(DEVMODEA, dmDitherType) + RTL_FIELD_SIZE(DEVMODEA, dmDitherType) },
28     { DM_MEDIATYPE, FIELD_OFFSET(DEVMODEA, dmMediaType) + RTL_FIELD_SIZE(DEVMODEA, dmMediaType) },
29     { DM_ICMINTENT, FIELD_OFFSET(DEVMODEA, dmICMIntent) + RTL_FIELD_SIZE(DEVMODEA, dmICMIntent) },
30     { DM_ICMMETHOD, FIELD_OFFSET(DEVMODEA, dmICMMethod) + RTL_FIELD_SIZE(DEVMODEA, dmICMMethod) },
31     { DM_DISPLAYFREQUENCY, FIELD_OFFSET(DEVMODEA, dmDisplayFrequency) + RTL_FIELD_SIZE(DEVMODEA, dmDisplayFrequency) },
32     { DM_NUP, FIELD_OFFSET(DEVMODEA, dmNup) + RTL_FIELD_SIZE(DEVMODEA, dmNup) },
33     { DM_DISPLAYFLAGS, FIELD_OFFSET(DEVMODEA, dmDisplayFlags) + RTL_FIELD_SIZE(DEVMODEA, dmDisplayFlags) },
34     { DM_PELSHEIGHT, FIELD_OFFSET(DEVMODEA, dmPelsHeight) + RTL_FIELD_SIZE(DEVMODEA, dmPelsHeight) },
35     { DM_PELSWIDTH, FIELD_OFFSET(DEVMODEA, dmPelsWidth) + RTL_FIELD_SIZE(DEVMODEA, dmPelsWidth) },
36     { DM_BITSPERPEL, FIELD_OFFSET(DEVMODEA, dmBitsPerPel) + RTL_FIELD_SIZE(DEVMODEA, dmBitsPerPel) },
37     { DM_LOGPIXELS, FIELD_OFFSET(DEVMODEA, dmLogPixels) + RTL_FIELD_SIZE(DEVMODEA, dmLogPixels) },
38     { DM_FORMNAME, FIELD_OFFSET(DEVMODEA, dmFormName) + RTL_FIELD_SIZE(DEVMODEA, dmFormName) },
39     { DM_COLLATE, FIELD_OFFSET(DEVMODEA, dmCollate) + RTL_FIELD_SIZE(DEVMODEA, dmCollate) },
40     { DM_TTOPTION, FIELD_OFFSET(DEVMODEA, dmTTOption) + RTL_FIELD_SIZE(DEVMODEA, dmTTOption) },
41     { DM_YRESOLUTION, FIELD_OFFSET(DEVMODEA, dmYResolution) + RTL_FIELD_SIZE(DEVMODEA, dmYResolution) },
42     { DM_DUPLEX, FIELD_OFFSET(DEVMODEA, dmDuplex) + RTL_FIELD_SIZE(DEVMODEA, dmDuplex) },
43     { DM_COLOR, FIELD_OFFSET(DEVMODEA, dmColor) + RTL_FIELD_SIZE(DEVMODEA, dmColor) },
44     { DM_DISPLAYFIXEDOUTPUT, FIELD_OFFSET(DEVMODEA, dmDisplayFixedOutput) + RTL_FIELD_SIZE(DEVMODEA, dmDisplayFixedOutput) },
45     { DM_DISPLAYORIENTATION, FIELD_OFFSET(DEVMODEA, dmDisplayOrientation) + RTL_FIELD_SIZE(DEVMODEA, dmDisplayOrientation) },
46     { DM_POSITION, FIELD_OFFSET(DEVMODEA, dmPosition) + RTL_FIELD_SIZE(DEVMODEA, dmPosition) },
47     { DM_PRINTQUALITY, FIELD_OFFSET(DEVMODEA, dmPrintQuality) + RTL_FIELD_SIZE(DEVMODEA, dmPrintQuality) },
48     { DM_DEFAULTSOURCE, FIELD_OFFSET(DEVMODEA, dmDefaultSource) + RTL_FIELD_SIZE(DEVMODEA, dmDefaultSource) },
49     { DM_COPIES, FIELD_OFFSET(DEVMODEA, dmCopies) + RTL_FIELD_SIZE(DEVMODEA, dmCopies) },
50     { DM_SCALE, FIELD_OFFSET(DEVMODEA, dmScale) + RTL_FIELD_SIZE(DEVMODEA, dmScale) },
51     { DM_PAPERWIDTH, FIELD_OFFSET(DEVMODEA, dmPaperWidth) + RTL_FIELD_SIZE(DEVMODEA, dmPaperWidth) },
52     { DM_PAPERLENGTH, FIELD_OFFSET(DEVMODEA, dmPaperLength) + RTL_FIELD_SIZE(DEVMODEA, dmPaperLength) },
53     { DM_PAPERSIZE, FIELD_OFFSET(DEVMODEA, dmPaperSize) + RTL_FIELD_SIZE(DEVMODEA, dmPaperSize) },
54     { DM_ORIENTATION, FIELD_OFFSET(DEVMODEA, dmOrientation) + RTL_FIELD_SIZE(DEVMODEA, dmOrientation) },
55     { 0, FIELD_OFFSET(DEVMODEA, dmFields) + RTL_FIELD_SIZE(DEVMODEA, dmFields) }
56 };
57 
58 static MINIMUM_SIZE_TABLE MinimumSizeW[] = {
59     { DM_PANNINGHEIGHT, FIELD_OFFSET(DEVMODEW, dmPanningHeight) + RTL_FIELD_SIZE(DEVMODEW, dmPanningHeight) },
60     { DM_PANNINGWIDTH, FIELD_OFFSET(DEVMODEW, dmPanningWidth) + RTL_FIELD_SIZE(DEVMODEW, dmPanningWidth) },
61     { DM_DITHERTYPE, FIELD_OFFSET(DEVMODEW, dmDitherType) + RTL_FIELD_SIZE(DEVMODEW, dmDitherType) },
62     { DM_MEDIATYPE, FIELD_OFFSET(DEVMODEW, dmMediaType) + RTL_FIELD_SIZE(DEVMODEW, dmMediaType) },
63     { DM_ICMINTENT, FIELD_OFFSET(DEVMODEW, dmICMIntent) + RTL_FIELD_SIZE(DEVMODEW, dmICMIntent) },
64     { DM_ICMMETHOD, FIELD_OFFSET(DEVMODEW, dmICMMethod) + RTL_FIELD_SIZE(DEVMODEW, dmICMMethod) },
65     { DM_DISPLAYFREQUENCY, FIELD_OFFSET(DEVMODEW, dmDisplayFrequency) + RTL_FIELD_SIZE(DEVMODEW, dmDisplayFrequency) },
66     { DM_NUP, FIELD_OFFSET(DEVMODEW, dmNup) + RTL_FIELD_SIZE(DEVMODEW, dmNup) },
67     { DM_DISPLAYFLAGS, FIELD_OFFSET(DEVMODEW, dmDisplayFlags) + RTL_FIELD_SIZE(DEVMODEW, dmDisplayFlags) },
68     { DM_PELSHEIGHT, FIELD_OFFSET(DEVMODEW, dmPelsHeight) + RTL_FIELD_SIZE(DEVMODEW, dmPelsHeight) },
69     { DM_PELSWIDTH, FIELD_OFFSET(DEVMODEW, dmPelsWidth) + RTL_FIELD_SIZE(DEVMODEW, dmPelsWidth) },
70     { DM_BITSPERPEL, FIELD_OFFSET(DEVMODEW, dmBitsPerPel) + RTL_FIELD_SIZE(DEVMODEW, dmBitsPerPel) },
71     { DM_LOGPIXELS, FIELD_OFFSET(DEVMODEW, dmLogPixels) + RTL_FIELD_SIZE(DEVMODEW, dmLogPixels) },
72     { DM_FORMNAME, FIELD_OFFSET(DEVMODEW, dmFormName) + RTL_FIELD_SIZE(DEVMODEW, dmFormName) },
73     { DM_COLLATE, FIELD_OFFSET(DEVMODEW, dmCollate) + RTL_FIELD_SIZE(DEVMODEW, dmCollate) },
74     { DM_TTOPTION, FIELD_OFFSET(DEVMODEW, dmTTOption) + RTL_FIELD_SIZE(DEVMODEW, dmTTOption) },
75     { DM_YRESOLUTION, FIELD_OFFSET(DEVMODEW, dmYResolution) + RTL_FIELD_SIZE(DEVMODEW, dmYResolution) },
76     { DM_DUPLEX, FIELD_OFFSET(DEVMODEW, dmDuplex) + RTL_FIELD_SIZE(DEVMODEW, dmDuplex) },
77     { DM_COLOR, FIELD_OFFSET(DEVMODEW, dmColor) + RTL_FIELD_SIZE(DEVMODEW, dmColor) },
78     { DM_DISPLAYFIXEDOUTPUT, FIELD_OFFSET(DEVMODEW, dmDisplayFixedOutput) + RTL_FIELD_SIZE(DEVMODEW, dmDisplayFixedOutput) },
79     { DM_DISPLAYORIENTATION, FIELD_OFFSET(DEVMODEW, dmDisplayOrientation) + RTL_FIELD_SIZE(DEVMODEW, dmDisplayOrientation) },
80     { DM_POSITION, FIELD_OFFSET(DEVMODEW, dmPosition) + RTL_FIELD_SIZE(DEVMODEW, dmPosition) },
81     { DM_PRINTQUALITY, FIELD_OFFSET(DEVMODEW, dmPrintQuality) + RTL_FIELD_SIZE(DEVMODEW, dmPrintQuality) },
82     { DM_DEFAULTSOURCE, FIELD_OFFSET(DEVMODEW, dmDefaultSource) + RTL_FIELD_SIZE(DEVMODEW, dmDefaultSource) },
83     { DM_COPIES, FIELD_OFFSET(DEVMODEW, dmCopies) + RTL_FIELD_SIZE(DEVMODEW, dmCopies) },
84     { DM_SCALE, FIELD_OFFSET(DEVMODEW, dmScale) + RTL_FIELD_SIZE(DEVMODEW, dmScale) },
85     { DM_PAPERWIDTH, FIELD_OFFSET(DEVMODEW, dmPaperWidth) + RTL_FIELD_SIZE(DEVMODEW, dmPaperWidth) },
86     { DM_PAPERLENGTH, FIELD_OFFSET(DEVMODEW, dmPaperLength) + RTL_FIELD_SIZE(DEVMODEW, dmPaperLength) },
87     { DM_PAPERSIZE, FIELD_OFFSET(DEVMODEW, dmPaperSize) + RTL_FIELD_SIZE(DEVMODEW, dmPaperSize) },
88     { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, dmOrientation) + RTL_FIELD_SIZE(DEVMODEW, dmOrientation) },
89     { 0, FIELD_OFFSET(DEVMODEW, dmFields) + RTL_FIELD_SIZE(DEVMODEW, dmFields) }
90 };
91 
92 
93 
START_TEST(IsValidDevmodeA)94 START_TEST(IsValidDevmodeA)
95 {
96     DEVMODEA DevMode;
97     PMINIMUM_SIZE_TABLE pTable = MinimumSizeA;
98 
99     // Give no Devmode at all, this has to fail without crashing.
100     SetLastError(0xDEADBEEF);
101     ok(!IsValidDevmodeA(NULL, sizeof(DEVMODEA)), "IsValidDevmodeA returns TRUE!\n");
102     ok(GetLastError() == ERROR_INVALID_DATA, "IsValidDevmodeA returns error %lu!\n", GetLastError());
103 
104     // Give a zeroed Devmode, this has to fail, because dmSize isn't set.
105     ZeroMemory(&DevMode, sizeof(DEVMODEA));
106     SetLastError(0xDEADBEEF);
107     ok(!IsValidDevmodeA(&DevMode, sizeof(DEVMODEA)), "IsValidDevmodeA returns TRUE!\n");
108     ok(GetLastError() == ERROR_INVALID_DATA, "IsValidDevmodeA returns error %lu!\n", GetLastError());
109 
110     // Now set only the dmSize member, IsValidDevmodeA should return TRUE now. The Last Error isn't touched again.
111     ZeroMemory(&DevMode, sizeof(DEVMODEA));
112     DevMode.dmSize = sizeof(DEVMODEA);
113     SetLastError(0xDEADBEEF);
114     ok(IsValidDevmodeA(&DevMode, sizeof(DEVMODEA)), "IsValidDevmodeA returns FALSE!\n");
115     ok(GetLastError() == 0xDEADBEEF, "IsValidDevmodeA returns error %lu!\n", GetLastError());
116 
117     // IsValidDevmodeA should also succeed if the DevMode appears to be larger.
118     ZeroMemory(&DevMode, sizeof(DEVMODEA));
119     DevMode.dmSize = sizeof(DEVMODEA) + 1;
120     SetLastError(0xDEADBEEF);
121     ok(IsValidDevmodeA(&DevMode, sizeof(DEVMODEA) + 1), "IsValidDevmodeA returns FALSE!\n");
122     ok(GetLastError() == 0xDEADBEEF, "IsValidDevmodeA returns error %lu!\n", GetLastError());
123 
124     // The DevmodeSize parameter may be larger than dmSize, but not the other way round!
125     ZeroMemory(&DevMode, sizeof(DEVMODEA));
126     DevMode.dmSize = sizeof(DEVMODEA);
127     SetLastError(0xDEADBEEF);
128     ok(IsValidDevmodeA(&DevMode, sizeof(DEVMODEA) + 1), "IsValidDevmodeA returns FALSE!\n");
129     ok(GetLastError() == 0xDEADBEEF, "IsValidDevmodeA returns error %lu!\n", GetLastError());
130 
131     ZeroMemory(&DevMode, sizeof(DEVMODEA));
132     DevMode.dmSize = sizeof(DEVMODEA) + 1;
133     SetLastError(0xDEADBEEF);
134     ok(!IsValidDevmodeA(&DevMode, sizeof(DEVMODEA)), "IsValidDevmodeA returns TRUE!\n");
135     ok(GetLastError() == ERROR_INVALID_DATA, "IsValidDevmodeA returns error %lu!\n", GetLastError());
136 
137     // dmDriverExtra is also taken into account.
138     ZeroMemory(&DevMode, sizeof(DEVMODEA));
139     DevMode.dmSize = sizeof(DEVMODEA);
140     DevMode.dmDriverExtra = 1;
141     SetLastError(0xDEADBEEF);
142     ok(!IsValidDevmodeA(&DevMode, sizeof(DEVMODEA)), "IsValidDevmodeA returns TRUE!\n");
143     ok(GetLastError() == ERROR_INVALID_DATA, "IsValidDevmodeA returns error %lu!\n", GetLastError());
144 
145     SetLastError(0xDEADBEEF);
146     ok(IsValidDevmodeA(&DevMode, sizeof(DEVMODEA) + 1), "IsValidDevmodeA returns FALSE!\n");
147     ok(GetLastError() == 0xDEADBEEF, "IsValidDevmodeA returns error %lu!\n", GetLastError());
148 
149     // dmSize must be a multiple of 4 if any dmDriverExtra is given.
150     for (DevMode.dmDriverExtra = 1; DevMode.dmDriverExtra <= 4; DevMode.dmDriverExtra++)
151     {
152         for (DevMode.dmSize = sizeof(DEVMODEA); DevMode.dmSize < sizeof(DEVMODEA) + 4; DevMode.dmSize++)
153         {
154             BOOL bExpected = (DevMode.dmSize % 4 == 0);
155             DWORD dwExpectedError = (bExpected ? 0xDEADBEEF : ERROR_INVALID_DATA);
156 
157             SetLastError(0xDEADBEEF);
158             ok(IsValidDevmodeA(&DevMode, DevMode.dmSize + DevMode.dmDriverExtra) == bExpected, "IsValidDevmodeA returns %d!\n", !bExpected);
159             ok(GetLastError() == dwExpectedError, "IsValidDevmodeA returns error %lu!\n", GetLastError());
160         }
161     }
162 
163     // IsValidDevmodeA also fixes missing null-terminations if the corresponding fields are used.
164     ZeroMemory(&DevMode, sizeof(DEVMODEA));
165     DevMode.dmSize = sizeof(DEVMODEA);
166     memset(DevMode.dmDeviceName, 'A', 32);
167     memset(DevMode.dmFormName, 'A', 32);
168     ok(IsValidDevmodeA(&DevMode, DevMode.dmSize), "IsValidDevmodeA returns FALSE!\n");
169     ok(DevMode.dmDeviceName[31] == '\0', "Expected dmDeviceName to be '\\0', but is '%c'\n", DevMode.dmDeviceName[31]);
170     ok(DevMode.dmFormName[31] == 'A', "Expected dmFormName to be 'A', but is '%c'\n", DevMode.dmDeviceName[31]);
171 
172     ZeroMemory(&DevMode, sizeof(DEVMODEA));
173     DevMode.dmSize = sizeof(DEVMODEA);
174     DevMode.dmFields = DM_FORMNAME;
175     memset(DevMode.dmDeviceName, 'A', 32);
176     memset(DevMode.dmFormName, 'A', 32);
177     ok(IsValidDevmodeA(&DevMode, DevMode.dmSize), "IsValidDevmodeA returns FALSE!\n");
178     ok(DevMode.dmDeviceName[31] == '\0', "Expected dmDeviceName to be '\\0', but is '%c'\n", DevMode.dmDeviceName[31]);
179     ok(DevMode.dmFormName[31] == '\0', "Expected dmFormName to be '\\0', but is '%c'\n", DevMode.dmDeviceName[31]);
180 
181     // Depending on which fields are given in dmFields, the minimum value for dmSize is different.
182     ZeroMemory(&DevMode, sizeof(DEVMODEA));
183 
184     do
185     {
186         DevMode.dmFields = pTable->dwField;
187         DevMode.dmSize = pTable->wSize;
188 
189         // This size should succeed!
190         ok(IsValidDevmodeA(&DevMode, DevMode.dmSize), "IsValidDevmodeA returns FALSE!\n");
191 
192         // One byte less should not succeed!
193         DevMode.dmSize--;
194         ok(!IsValidDevmodeA(&DevMode, DevMode.dmSize), "IsValidDevmodeA returns TRUE!\n");
195 
196         pTable++;
197     }
198     while (pTable->dwField);
199 }
200 
START_TEST(IsValidDevmodeW)201 START_TEST(IsValidDevmodeW)
202 {
203     DEVMODEW DevMode;
204     PMINIMUM_SIZE_TABLE pTable = MinimumSizeW;
205 
206     // Give no Devmode at all, this has to fail without crashing.
207     SetLastError(0xDEADBEEF);
208     ok(!IsValidDevmodeW(NULL, sizeof(DEVMODEW)), "IsValidDevmodeW returns TRUE!\n");
209     ok(GetLastError() == ERROR_INVALID_DATA, "IsValidDevmodeW returns error %lu!\n", GetLastError());
210 
211     // Give a zeroed Devmode, this has to fail, because dmSize isn't set.
212     ZeroMemory(&DevMode, sizeof(DEVMODEW));
213     SetLastError(0xDEADBEEF);
214     ok(!IsValidDevmodeW(&DevMode, sizeof(DEVMODEW)), "IsValidDevmodeW returns TRUE!\n");
215     ok(GetLastError() == ERROR_INVALID_DATA, "IsValidDevmodeW returns error %lu!\n", GetLastError());
216 
217     // Now set only the dmSize member, IsValidDevmodeW should return TRUE now. The Last Error isn't touched again.
218     ZeroMemory(&DevMode, sizeof(DEVMODEW));
219     DevMode.dmSize = sizeof(DEVMODEW);
220     SetLastError(0xDEADBEEF);
221     ok(IsValidDevmodeW(&DevMode, sizeof(DEVMODEW)), "IsValidDevmodeW returns FALSE!\n");
222     ok(GetLastError() == 0xDEADBEEF, "IsValidDevmodeW returns error %lu!\n", GetLastError());
223 
224     // IsValidDevmodeW should also succeed if the DevMode appears to be larger.
225     ZeroMemory(&DevMode, sizeof(DEVMODEW));
226     DevMode.dmSize = sizeof(DEVMODEW) + 1;
227     SetLastError(0xDEADBEEF);
228     ok(IsValidDevmodeW(&DevMode, sizeof(DEVMODEW) + 1), "IsValidDevmodeW returns FALSE!\n");
229     ok(GetLastError() == 0xDEADBEEF, "IsValidDevmodeW returns error %lu!\n", GetLastError());
230 
231     // The DevmodeSize parameter may be larger than dmSize, but not the other way round!
232     ZeroMemory(&DevMode, sizeof(DEVMODEW));
233     DevMode.dmSize = sizeof(DEVMODEW);
234     SetLastError(0xDEADBEEF);
235     ok(IsValidDevmodeW(&DevMode, sizeof(DEVMODEW) + 1), "IsValidDevmodeW returns FALSE!\n");
236     ok(GetLastError() == 0xDEADBEEF, "IsValidDevmodeW returns error %lu!\n", GetLastError());
237 
238     ZeroMemory(&DevMode, sizeof(DEVMODEW));
239     DevMode.dmSize = sizeof(DEVMODEW) + 1;
240     SetLastError(0xDEADBEEF);
241     ok(!IsValidDevmodeW(&DevMode, sizeof(DEVMODEW)), "IsValidDevmodeW returns TRUE!\n");
242     ok(GetLastError() == ERROR_INVALID_DATA, "IsValidDevmodeW returns error %lu!\n", GetLastError());
243 
244     // dmDriverExtra is also taken into account.
245     ZeroMemory(&DevMode, sizeof(DEVMODEW));
246     DevMode.dmSize = sizeof(DEVMODEW);
247     DevMode.dmDriverExtra = 1;
248     SetLastError(0xDEADBEEF);
249     ok(!IsValidDevmodeW(&DevMode, sizeof(DEVMODEW)), "IsValidDevmodeW returns TRUE!\n");
250     ok(GetLastError() == ERROR_INVALID_DATA, "IsValidDevmodeW returns error %lu!\n", GetLastError());
251 
252     SetLastError(0xDEADBEEF);
253     ok(IsValidDevmodeW(&DevMode, sizeof(DEVMODEW) + 1), "IsValidDevmodeW returns FALSE!\n");
254     ok(GetLastError() == 0xDEADBEEF, "IsValidDevmodeW returns error %lu!\n", GetLastError());
255 
256     // dmSize must be a multiple of 4 if any dmDriverExtra is given.
257     for (DevMode.dmDriverExtra = 1; DevMode.dmDriverExtra <= 4; DevMode.dmDriverExtra++)
258     {
259         for (DevMode.dmSize = sizeof(DEVMODEW); DevMode.dmSize < sizeof(DEVMODEW) + 4; DevMode.dmSize++)
260         {
261             BOOL bExpected = (DevMode.dmSize % 4 == 0);
262             DWORD dwExpectedError = (bExpected ? 0xDEADBEEF : ERROR_INVALID_DATA);
263 
264             SetLastError(0xDEADBEEF);
265             ok(IsValidDevmodeW(&DevMode, DevMode.dmSize + DevMode.dmDriverExtra) == bExpected, "IsValidDevmodeW returns %d!\n", !bExpected);
266             ok(GetLastError() == dwExpectedError, "IsValidDevmodeW returns error %lu!\n", GetLastError());
267         }
268     }
269 
270     // IsValidDevmodeW also fixes missing null-terminations if the corresponding fields are used.
271     ZeroMemory(&DevMode, sizeof(DEVMODEW));
272     DevMode.dmSize = sizeof(DEVMODEW);
273     wmemset(DevMode.dmDeviceName, L'A', 32);
274     wmemset(DevMode.dmFormName, L'A', 32);
275     ok(IsValidDevmodeW(&DevMode, DevMode.dmSize), "IsValidDevmodeW returns FALSE!\n");
276     ok(DevMode.dmDeviceName[31] == L'\0', "Expected dmDeviceName to be '\\0', but is '%C'\n", DevMode.dmDeviceName[31]);
277     ok(DevMode.dmFormName[31] == L'A', "Expected dmFormName to be 'A', but is '%C'\n", DevMode.dmDeviceName[31]);
278 
279     ZeroMemory(&DevMode, sizeof(DEVMODEW));
280     DevMode.dmSize = sizeof(DEVMODEW);
281     DevMode.dmFields = DM_FORMNAME;
282     wmemset(DevMode.dmDeviceName, L'A', 32);
283     wmemset(DevMode.dmFormName, L'A', 32);
284     ok(IsValidDevmodeW(&DevMode, DevMode.dmSize), "IsValidDevmodeW returns FALSE!\n");
285     ok(DevMode.dmDeviceName[31] == L'\0', "Expected dmDeviceName to be '\\0', but is '%C'\n", DevMode.dmDeviceName[31]);
286     ok(DevMode.dmFormName[31] == L'\0', "Expected dmFormName to be '\\0', but is '%C'\n", DevMode.dmDeviceName[31]);
287 
288     // Depending on which fields are given in dmFields, the minimum value for dmSize is different.
289     ZeroMemory(&DevMode, sizeof(DEVMODEW));
290 
291     do
292     {
293         DevMode.dmFields = pTable->dwField;
294         DevMode.dmSize = pTable->wSize;
295 
296         // This size should succeed!
297         ok(IsValidDevmodeW(&DevMode, DevMode.dmSize), "IsValidDevmodeW returns FALSE!\n");
298 
299         // One byte less should not succeed!
300         DevMode.dmSize--;
301         ok(!IsValidDevmodeW(&DevMode, DevMode.dmSize), "IsValidDevmodeW returns TRUE!\n");
302 
303         pTable++;
304     }
305     while (pTable->dwField);
306 }
307