@@ -191,8 +191,10 @@ EnumDisplaySettingsExA(
191
191
DWORD dwFlags )
192
192
{
193
193
NTSTATUS Status ;
194
- UNICODE_STRING usDeviceName , * pusDeviceName = NULL ;
195
- DEVMODEW DevModeW ;
194
+ UNICODE_STRING usDeviceName ;
195
+ PUNICODE_STRING pusDeviceName = NULL ;
196
+ LPDEVMODEW lpExtendedDevMode ;
197
+ BOOL Result = FALSE;
196
198
197
199
if (lpszDeviceName )
198
200
{
@@ -204,74 +206,105 @@ EnumDisplaySettingsExA(
204
206
pusDeviceName = & usDeviceName ;
205
207
}
206
208
207
- memset (& DevModeW ,0 , sizeof (DEVMODEW ));
208
- DevModeW .dmSize = sizeof (DEVMODEW );
209
-
210
- Status = NtUserEnumDisplaySettings (pusDeviceName , iModeNum , & DevModeW , dwFlags );
211
-
212
- if (pusDeviceName )
209
+ /* Allocate memory for DEVMODEW and extra data */
210
+ lpExtendedDevMode = RtlAllocateHeap (RtlGetProcessHeap (),
211
+ HEAP_ZERO_MEMORY ,
212
+ sizeof (DEVMODEW ) + lpDevMode -> dmDriverExtra );
213
+ if (!lpExtendedDevMode )
213
214
{
214
- RtlFreeUnicodeString ( & usDeviceName );
215
- }
215
+ if ( pusDeviceName )
216
+ RtlFreeUnicodeString ( & usDeviceName );
216
217
217
- if (!NT_SUCCESS (Status ))
218
- {
219
218
return FALSE;
220
219
}
221
220
222
- #define COPYS (f ,len ) WideCharToMultiByte( CP_THREAD_ACP, 0, DevModeW.f, len, (LPSTR)lpDevMode->f, len, NULL, NULL )
223
- #define COPYN (f ) lpDevMode->f = DevModeW.f
224
- COPYS (dmDeviceName , CCHDEVICENAME );
225
- COPYN (dmSpecVersion );
226
- COPYN (dmDriverVersion );
227
- switch (lpDevMode -> dmSize )
221
+ /* Initialize structure fields */
222
+ lpExtendedDevMode -> dmSize = sizeof (DEVMODEW );
223
+ lpExtendedDevMode -> dmDriverExtra = lpDevMode -> dmDriverExtra ;
224
+
225
+ Status = NtUserEnumDisplaySettings (pusDeviceName , iModeNum , lpExtendedDevMode , dwFlags );
226
+
227
+ if (pusDeviceName )
228
+ RtlFreeUnicodeString (& usDeviceName );
229
+
230
+ if (NT_SUCCESS (Status ))
228
231
{
229
- case SIZEOF_DEVMODEA_300 :
230
- case SIZEOF_DEVMODEA_400 :
231
- case SIZEOF_DEVMODEA_500 :
232
- break ;
233
- default :
234
- lpDevMode -> dmSize = SIZEOF_DEVMODEA_300 ;
235
- break ;
232
+ /* Store old structure size */
233
+ WORD OldSize = lpDevMode -> dmSize ;
234
+
235
+ #define COPYS (f ,len ) WideCharToMultiByte(CP_THREAD_ACP, 0, lpExtendedDevMode->f, len, (LPSTR)lpDevMode->f, len, NULL, NULL)
236
+ #define COPYN (f ) lpDevMode->f = lpExtendedDevMode->f
237
+
238
+ COPYS (dmDeviceName , CCHDEVICENAME );
239
+ COPYN (dmSpecVersion );
240
+ COPYN (dmDriverVersion );
241
+ COPYN (dmDriverExtra );
242
+ COPYN (dmFields );
243
+ COPYN (dmPosition .x );
244
+ COPYN (dmPosition .y );
245
+ COPYN (dmScale );
246
+ COPYN (dmCopies );
247
+ COPYN (dmDefaultSource );
248
+ COPYN (dmPrintQuality );
249
+ COPYN (dmColor );
250
+ COPYN (dmDuplex );
251
+ COPYN (dmYResolution );
252
+ COPYN (dmTTOption );
253
+ COPYN (dmCollate );
254
+ COPYS (dmFormName ,CCHFORMNAME );
255
+ COPYN (dmLogPixels );
256
+ COPYN (dmBitsPerPel );
257
+ COPYN (dmPelsWidth );
258
+ COPYN (dmPelsHeight );
259
+ COPYN (dmDisplayFlags ); // aka dmNup
260
+ COPYN (dmDisplayFrequency );
261
+
262
+ /* we're done with 0x300 fields */
263
+ if (OldSize > SIZEOF_DEVMODEA_300 )
264
+ {
265
+ COPYN (dmICMMethod );
266
+ COPYN (dmICMIntent );
267
+ COPYN (dmMediaType );
268
+ COPYN (dmDitherType );
269
+ COPYN (dmReserved1 );
270
+ COPYN (dmReserved2 );
271
+
272
+ /* we're done with 0x400 fields */
273
+ if (OldSize > SIZEOF_DEVMODEA_400 )
274
+ {
275
+ COPYN (dmPanningWidth );
276
+ COPYN (dmPanningHeight );
277
+ }
278
+ }
279
+
280
+ /* Restore old size */
281
+ lpDevMode -> dmSize = OldSize ;
282
+
283
+ /* Extra data presented? */
284
+ if (lpDevMode -> dmDriverExtra && lpExtendedDevMode -> dmDriverExtra )
285
+ {
286
+ /* We choose the smallest size */
287
+ if (lpDevMode -> dmDriverExtra > lpExtendedDevMode -> dmDriverExtra )
288
+ lpDevMode -> dmDriverExtra = lpExtendedDevMode -> dmDriverExtra ;
289
+
290
+ /* Copy extra data */
291
+ RtlCopyMemory (lpDevMode + OldSize , lpExtendedDevMode + 1 , lpDevMode -> dmDriverExtra );
292
+ }
293
+
294
+ /* If the size of source structure is less, than used, we clean unsupported flags */
295
+ if (OldSize < FIELD_OFFSET (DEVMODEA , dmPanningHeight ))
296
+ lpDevMode -> dmFields &= ~DM_PANNINGHEIGHT ;
297
+
298
+ if (OldSize < FIELD_OFFSET (DEVMODEA , dmPanningWidth ))
299
+ lpDevMode -> dmFields &= ~DM_PANNINGWIDTH ;
300
+
301
+ Result = TRUE;
236
302
}
237
- COPYN (dmDriverExtra );
238
- COPYN (dmFields );
239
- COPYN (dmPosition .x );
240
- COPYN (dmPosition .y );
241
- COPYN (dmScale );
242
- COPYN (dmCopies );
243
- COPYN (dmDefaultSource );
244
- COPYN (dmPrintQuality );
245
- COPYN (dmColor );
246
- COPYN (dmDuplex );
247
- COPYN (dmYResolution );
248
- COPYN (dmTTOption );
249
- COPYN (dmCollate );
250
- COPYS (dmFormName ,CCHFORMNAME );
251
- COPYN (dmLogPixels );
252
- COPYN (dmBitsPerPel );
253
- COPYN (dmPelsWidth );
254
- COPYN (dmPelsHeight );
255
- COPYN (dmDisplayFlags ); // aka dmNup
256
- COPYN (dmDisplayFrequency );
257
-
258
- if (lpDevMode -> dmSize <= SIZEOF_DEVMODEW_300 )
259
- return TRUE; // we're done with 0x300 fields
260
-
261
- COPYN (dmICMMethod );
262
- COPYN (dmICMIntent );
263
- COPYN (dmMediaType );
264
- COPYN (dmDitherType );
265
- COPYN (dmReserved1 );
266
- COPYN (dmReserved2 );
267
-
268
- if (lpDevMode -> dmSize <= SIZEOF_DEVMODEW_400 )
269
- return TRUE; // we're done with 0x400 fields
270
-
271
- COPYN (dmPanningWidth );
272
- COPYN (dmPanningHeight );
273
303
274
- return TRUE;
304
+ /* Free memory */
305
+ RtlFreeHeap (RtlGetProcessHeap (), 0 , lpExtendedDevMode );
306
+
307
+ return Result ;
275
308
}
276
309
277
310
@@ -285,7 +318,11 @@ EnumDisplaySettingsA(
285
318
DWORD iModeNum ,
286
319
LPDEVMODEA lpDevMode )
287
320
{
288
- return EnumDisplaySettingsExA ( lpszDeviceName , iModeNum , lpDevMode , 0 );
321
+ /* Fixup sizes */
322
+ lpDevMode -> dmSize = FIELD_OFFSET (DEVMODEA , dmICMMethod );
323
+ lpDevMode -> dmDriverExtra = 0 ;
324
+
325
+ return EnumDisplaySettingsExA (lpszDeviceName , iModeNum , lpDevMode , 0 );
289
326
}
290
327
291
328
@@ -374,7 +411,7 @@ EnumDisplaySettingsW(
374
411
LPDEVMODEW lpDevMode )
375
412
{
376
413
/* Fixup sizes */
377
- lpDevMode -> dmSize = FIELD_OFFSET (DEVMODE , dmICMMethod );
414
+ lpDevMode -> dmSize = FIELD_OFFSET (DEVMODEW , dmICMMethod );
378
415
lpDevMode -> dmDriverExtra = 0 ;
379
416
380
417
return EnumDisplaySettingsExW (lpszDeviceName , iModeNum , lpDevMode , 0 );
0 commit comments