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/display.c?rev=72659&r1=72658&r2=72659&view=diff
==============================================================================
--- 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);


Reply via email to