[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
This commit is contained in:
Dmitry Chapyshev 2016-09-11 19:05:27 +00:00
parent 0ec1c73cbf
commit 35d777891f
2 changed files with 58 additions and 6 deletions

View file

@ -571,12 +571,12 @@ NtUserEnumDisplaySettings(
_SEH2_TRY
{
ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
ProbeForRead(lpDevMode, sizeof(DEVMODEW), sizeof(UCHAR));
cbSize = lpDevMode->dmSize;
cbExtra = lpDevMode->dmDriverExtra;
ProbeForWrite(lpDevMode, cbSize + cbExtra, 1);
ProbeForWrite(lpDevMode, cbSize + cbExtra, sizeof(UCHAR));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{

View file

@ -301,7 +301,10 @@ EnumDisplaySettingsExW(
DWORD dwFlags)
{
NTSTATUS Status;
UNICODE_STRING usDeviceName, *pusDeviceName = NULL;
UNICODE_STRING usDeviceName;
PUNICODE_STRING pusDeviceName = NULL;
LPDEVMODEW lpExtendedDevMode;
BOOL Result = FALSE;
if (lpszDeviceName)
{
@ -309,9 +312,54 @@ EnumDisplaySettingsExW(
pusDeviceName = &usDeviceName;
}
Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, lpDevMode, dwFlags);
/* Allocate memory for DEVMODEW and extra data */
lpExtendedDevMode = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(DEVMODEW) + lpDevMode->dmDriverExtra);
if (!lpExtendedDevMode)
return FALSE;
return NT_SUCCESS(Status);
/* Initialize structure fields */
lpExtendedDevMode->dmSize = sizeof(DEVMODEW);
lpExtendedDevMode->dmDriverExtra = lpDevMode->dmDriverExtra;
Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, lpExtendedDevMode, dwFlags);
if (NT_SUCCESS(Status))
{
/* Store old structure size */
WORD OldSize = lpDevMode->dmSize;
/* Copy general data */
RtlCopyMemory(lpDevMode, lpExtendedDevMode, OldSize);
/* Restore old size */
lpDevMode->dmSize = OldSize;
/* Extra data presented? */
if (lpDevMode->dmDriverExtra && lpExtendedDevMode->dmDriverExtra)
{
/* We choose the smallest size */
if (lpDevMode->dmDriverExtra > lpExtendedDevMode->dmDriverExtra)
lpDevMode->dmDriverExtra = lpExtendedDevMode->dmDriverExtra;
/* Copy extra data */
RtlCopyMemory(lpDevMode + OldSize, lpExtendedDevMode + 1, lpDevMode->dmDriverExtra);
}
/* If the size of source structure is less, than used, we clean unsupported flags */
if (OldSize < FIELD_OFFSET(DEVMODEW, dmPanningHeight))
lpDevMode->dmFields &= ~DM_PANNINGHEIGHT;
if (OldSize < FIELD_OFFSET(DEVMODEW, dmPanningWidth))
lpDevMode->dmFields &= ~DM_PANNINGWIDTH;
Result = TRUE;
}
/* Free memory */
RtlFreeHeap(RtlGetProcessHeap(), 0, lpExtendedDevMode);
return Result;
}
@ -325,7 +373,11 @@ EnumDisplaySettingsW(
DWORD iModeNum,
LPDEVMODEW lpDevMode)
{
return EnumDisplaySettingsExW ( lpszDeviceName, iModeNum, lpDevMode, 0 );
/* Fixup sizes */
lpDevMode->dmSize = FIELD_OFFSET(DEVMODE, dmICMMethod);
lpDevMode->dmDriverExtra = 0;
return EnumDisplaySettingsExW(lpszDeviceName, iModeNum, lpDevMode, 0);
}