Author: dchapyshev
Date: Sun Sep 11 20:11:35 2016
New Revision: 72659
URL:
http://svn.reactos.org/svn/reactos?rev=72659&view=rev
Log:
[USER32] We have to use the copy of DEVMODEA structure (having size expanded on
dmDriverExtra) for support of extra data of the driver
Modified:
trunk/reactos/win32ss/user/user32/misc/display.c
Modified: trunk/reactos/win32ss/user/user32/misc/display.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/d…
==============================================================================
--- trunk/reactos/win32ss/user/user32/misc/display.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/misc/display.c [iso-8859-1] Sun Sep 11 20:11:35
2016
@@ -191,8 +191,10 @@
DWORD dwFlags)
{
NTSTATUS Status;
- UNICODE_STRING usDeviceName, *pusDeviceName = NULL;
- DEVMODEW DevModeW;
+ UNICODE_STRING usDeviceName;
+ PUNICODE_STRING pusDeviceName = NULL;
+ LPDEVMODEW lpExtendedDevMode;
+ BOOL Result = FALSE;
if (lpszDeviceName)
{
@@ -204,74 +206,105 @@
pusDeviceName = &usDeviceName;
}
- memset(&DevModeW,0, sizeof(DEVMODEW));
- DevModeW.dmSize = sizeof(DEVMODEW);
-
- Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, &DevModeW, dwFlags);
+ /* Allocate memory for DEVMODEW and extra data */
+ lpExtendedDevMode = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(DEVMODEW) + lpDevMode->dmDriverExtra);
+ if (!lpExtendedDevMode)
+ {
+ if (pusDeviceName)
+ RtlFreeUnicodeString(&usDeviceName);
+
+ return FALSE;
+ }
+
+ /* Initialize structure fields */
+ lpExtendedDevMode->dmSize = sizeof(DEVMODEW);
+ lpExtendedDevMode->dmDriverExtra = lpDevMode->dmDriverExtra;
+
+ Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, lpExtendedDevMode,
dwFlags);
if (pusDeviceName)
- {
- RtlFreeUnicodeString (&usDeviceName);
- }
-
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
-
-#define COPYS(f,len) WideCharToMultiByte( CP_THREAD_ACP, 0, DevModeW.f, len,
(LPSTR)lpDevMode->f, len, NULL, NULL )
-#define COPYN(f) lpDevMode->f = DevModeW.f
- COPYS(dmDeviceName, CCHDEVICENAME );
- COPYN(dmSpecVersion);
- COPYN(dmDriverVersion);
- switch (lpDevMode->dmSize)
- {
- case SIZEOF_DEVMODEA_300:
- case SIZEOF_DEVMODEA_400:
- case SIZEOF_DEVMODEA_500:
- break;
- default:
- lpDevMode->dmSize = SIZEOF_DEVMODEA_300;
- break;
- }
- COPYN(dmDriverExtra);
- COPYN(dmFields);
- COPYN(dmPosition.x);
- COPYN(dmPosition.y);
- COPYN(dmScale);
- COPYN(dmCopies);
- COPYN(dmDefaultSource);
- COPYN(dmPrintQuality);
- COPYN(dmColor);
- COPYN(dmDuplex);
- COPYN(dmYResolution);
- COPYN(dmTTOption);
- COPYN(dmCollate);
- COPYS(dmFormName,CCHFORMNAME);
- COPYN(dmLogPixels);
- COPYN(dmBitsPerPel);
- COPYN(dmPelsWidth);
- COPYN(dmPelsHeight);
- COPYN(dmDisplayFlags); // aka dmNup
- COPYN(dmDisplayFrequency);
-
- if (lpDevMode->dmSize <= SIZEOF_DEVMODEW_300)
- return TRUE; // we're done with 0x300 fields
-
- COPYN(dmICMMethod);
- COPYN(dmICMIntent);
- COPYN(dmMediaType);
- COPYN(dmDitherType);
- COPYN(dmReserved1);
- COPYN(dmReserved2);
-
- if (lpDevMode->dmSize <= SIZEOF_DEVMODEW_400)
- return TRUE; // we're done with 0x400 fields
-
- COPYN(dmPanningWidth);
- COPYN(dmPanningHeight);
-
- return TRUE;
+ RtlFreeUnicodeString(&usDeviceName);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* Store old structure size */
+ WORD OldSize = lpDevMode->dmSize;
+
+#define COPYS(f,len) WideCharToMultiByte(CP_THREAD_ACP, 0, lpExtendedDevMode->f, len,
(LPSTR)lpDevMode->f, len, NULL, NULL)
+#define COPYN(f) lpDevMode->f = lpExtendedDevMode->f
+
+ COPYS(dmDeviceName, CCHDEVICENAME);
+ COPYN(dmSpecVersion);
+ COPYN(dmDriverVersion);
+ COPYN(dmDriverExtra);
+ COPYN(dmFields);
+ COPYN(dmPosition.x);
+ COPYN(dmPosition.y);
+ COPYN(dmScale);
+ COPYN(dmCopies);
+ COPYN(dmDefaultSource);
+ COPYN(dmPrintQuality);
+ COPYN(dmColor);
+ COPYN(dmDuplex);
+ COPYN(dmYResolution);
+ COPYN(dmTTOption);
+ COPYN(dmCollate);
+ COPYS(dmFormName,CCHFORMNAME);
+ COPYN(dmLogPixels);
+ COPYN(dmBitsPerPel);
+ COPYN(dmPelsWidth);
+ COPYN(dmPelsHeight);
+ COPYN(dmDisplayFlags); // aka dmNup
+ COPYN(dmDisplayFrequency);
+
+ /* we're done with 0x300 fields */
+ if (OldSize > SIZEOF_DEVMODEA_300)
+ {
+ COPYN(dmICMMethod);
+ COPYN(dmICMIntent);
+ COPYN(dmMediaType);
+ COPYN(dmDitherType);
+ COPYN(dmReserved1);
+ COPYN(dmReserved2);
+
+ /* we're done with 0x400 fields */
+ if (OldSize > SIZEOF_DEVMODEA_400)
+ {
+ COPYN(dmPanningWidth);
+ COPYN(dmPanningHeight);
+ }
+ }
+
+ /* 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(DEVMODEA, dmPanningHeight))
+ lpDevMode->dmFields &= ~DM_PANNINGHEIGHT;
+
+ if (OldSize < FIELD_OFFSET(DEVMODEA, dmPanningWidth))
+ lpDevMode->dmFields &= ~DM_PANNINGWIDTH;
+
+ Result = TRUE;
+ }
+
+ /* Free memory */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, lpExtendedDevMode);
+
+ return Result;
}
@@ -285,7 +318,11 @@
DWORD iModeNum,
LPDEVMODEA lpDevMode)
{
- return EnumDisplaySettingsExA ( lpszDeviceName, iModeNum, lpDevMode, 0 );
+ /* Fixup sizes */
+ lpDevMode->dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod);
+ lpDevMode->dmDriverExtra = 0;
+
+ return EnumDisplaySettingsExA(lpszDeviceName, iModeNum, lpDevMode, 0);
}
@@ -374,7 +411,7 @@
LPDEVMODEW lpDevMode)
{
/* Fixup sizes */
- lpDevMode->dmSize = FIELD_OFFSET(DEVMODE, dmICMMethod);
+ lpDevMode->dmSize = FIELD_OFFSET(DEVMODEW, dmICMMethod);
lpDevMode->dmDriverExtra = 0;
return EnumDisplaySettingsExW(lpszDeviceName, iModeNum, lpDevMode, 0);