Skip to content

Commit 6dd9ac5

Browse files
author
Dmitry Chapyshev
committed
[USER32] We have to use the copy of DEVMODEA structure (having size expanded on dmDriverExtra) for support of extra data of the driver
svn path=/trunk/; revision=72659
1 parent 5e9b969 commit 6dd9ac5

File tree

1 file changed

+101
-64
lines changed

1 file changed

+101
-64
lines changed

reactos/win32ss/user/user32/misc/display.c

Lines changed: 101 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,10 @@ EnumDisplaySettingsExA(
191191
DWORD dwFlags)
192192
{
193193
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;
196198

197199
if (lpszDeviceName)
198200
{
@@ -204,74 +206,105 @@ EnumDisplaySettingsExA(
204206
pusDeviceName = &usDeviceName;
205207
}
206208

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)
213214
{
214-
RtlFreeUnicodeString (&usDeviceName);
215-
}
215+
if (pusDeviceName)
216+
RtlFreeUnicodeString(&usDeviceName);
216217

217-
if (!NT_SUCCESS(Status))
218-
{
219218
return FALSE;
220219
}
221220

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))
228231
{
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;
236302
}
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);
273303

274-
return TRUE;
304+
/* Free memory */
305+
RtlFreeHeap(RtlGetProcessHeap(), 0, lpExtendedDevMode);
306+
307+
return Result;
275308
}
276309

277310

@@ -285,7 +318,11 @@ EnumDisplaySettingsA(
285318
DWORD iModeNum,
286319
LPDEVMODEA lpDevMode)
287320
{
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);
289326
}
290327

291328

@@ -374,7 +411,7 @@ EnumDisplaySettingsW(
374411
LPDEVMODEW lpDevMode)
375412
{
376413
/* Fixup sizes */
377-
lpDevMode->dmSize = FIELD_OFFSET(DEVMODE, dmICMMethod);
414+
lpDevMode->dmSize = FIELD_OFFSET(DEVMODEW, dmICMMethod);
378415
lpDevMode->dmDriverExtra = 0;
379416

380417
return EnumDisplaySettingsExW(lpszDeviceName, iModeNum, lpDevMode, 0);

0 commit comments

Comments
 (0)