Skip to content

Commit 35d7778

Browse files
author
Dmitry Chapyshev
committed
[USER32] We have to use the copy of DEVMODEW structure (having size expanded on dmDriverExtra) for support of extra data of the driver
* Fixes 16 tests for EnumDisplaySettings svn path=/trunk/; revision=72657
1 parent 0ec1c73 commit 35d7778

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

reactos/win32ss/user/ntuser/display.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,12 +571,12 @@ NtUserEnumDisplaySettings(
571571

572572
_SEH2_TRY
573573
{
574-
ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
574+
ProbeForRead(lpDevMode, sizeof(DEVMODEW), sizeof(UCHAR));
575575

576576
cbSize = lpDevMode->dmSize;
577577
cbExtra = lpDevMode->dmDriverExtra;
578578

579-
ProbeForWrite(lpDevMode, cbSize + cbExtra, 1);
579+
ProbeForWrite(lpDevMode, cbSize + cbExtra, sizeof(UCHAR));
580580
}
581581
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
582582
{

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

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,17 +301,65 @@ EnumDisplaySettingsExW(
301301
DWORD dwFlags)
302302
{
303303
NTSTATUS Status;
304-
UNICODE_STRING usDeviceName, *pusDeviceName = NULL;
304+
UNICODE_STRING usDeviceName;
305+
PUNICODE_STRING pusDeviceName = NULL;
306+
LPDEVMODEW lpExtendedDevMode;
307+
BOOL Result = FALSE;
305308

306309
if (lpszDeviceName)
307310
{
308311
RtlInitUnicodeString(&usDeviceName, lpszDeviceName);
309312
pusDeviceName = &usDeviceName;
310313
}
311314

312-
Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, lpDevMode, dwFlags);
315+
/* Allocate memory for DEVMODEW and extra data */
316+
lpExtendedDevMode = RtlAllocateHeap(RtlGetProcessHeap(),
317+
HEAP_ZERO_MEMORY,
318+
sizeof(DEVMODEW) + lpDevMode->dmDriverExtra);
319+
if (!lpExtendedDevMode)
320+
return FALSE;
321+
322+
/* Initialize structure fields */
323+
lpExtendedDevMode->dmSize = sizeof(DEVMODEW);
324+
lpExtendedDevMode->dmDriverExtra = lpDevMode->dmDriverExtra;
325+
326+
Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, lpExtendedDevMode, dwFlags);
327+
if (NT_SUCCESS(Status))
328+
{
329+
/* Store old structure size */
330+
WORD OldSize = lpDevMode->dmSize;
331+
332+
/* Copy general data */
333+
RtlCopyMemory(lpDevMode, lpExtendedDevMode, OldSize);
334+
335+
/* Restore old size */
336+
lpDevMode->dmSize = OldSize;
337+
338+
/* Extra data presented? */
339+
if (lpDevMode->dmDriverExtra && lpExtendedDevMode->dmDriverExtra)
340+
{
341+
/* We choose the smallest size */
342+
if (lpDevMode->dmDriverExtra > lpExtendedDevMode->dmDriverExtra)
343+
lpDevMode->dmDriverExtra = lpExtendedDevMode->dmDriverExtra;
313344

314-
return NT_SUCCESS(Status);
345+
/* Copy extra data */
346+
RtlCopyMemory(lpDevMode + OldSize, lpExtendedDevMode + 1, lpDevMode->dmDriverExtra);
347+
}
348+
349+
/* If the size of source structure is less, than used, we clean unsupported flags */
350+
if (OldSize < FIELD_OFFSET(DEVMODEW, dmPanningHeight))
351+
lpDevMode->dmFields &= ~DM_PANNINGHEIGHT;
352+
353+
if (OldSize < FIELD_OFFSET(DEVMODEW, dmPanningWidth))
354+
lpDevMode->dmFields &= ~DM_PANNINGWIDTH;
355+
356+
Result = TRUE;
357+
}
358+
359+
/* Free memory */
360+
RtlFreeHeap(RtlGetProcessHeap(), 0, lpExtendedDevMode);
361+
362+
return Result;
315363
}
316364

317365

@@ -325,7 +373,11 @@ EnumDisplaySettingsW(
325373
DWORD iModeNum,
326374
LPDEVMODEW lpDevMode)
327375
{
328-
return EnumDisplaySettingsExW ( lpszDeviceName, iModeNum, lpDevMode, 0 );
376+
/* Fixup sizes */
377+
lpDevMode->dmSize = FIELD_OFFSET(DEVMODE, dmICMMethod);
378+
lpDevMode->dmDriverExtra = 0;
379+
380+
return EnumDisplaySettingsExW(lpszDeviceName, iModeNum, lpDevMode, 0);
329381
}
330382

331383

0 commit comments

Comments
 (0)