Author: dchapyshev
Date: Sun Sep 11 19:05:27 2016
New Revision: 72657
URL: 
http://svn.reactos.org/svn/reactos?rev=72657&view=rev
Log:
[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
Modified:
    trunk/reactos/win32ss/user/ntuser/display.c
    trunk/reactos/win32ss/user/user32/misc/display.c
Modified: trunk/reactos/win32ss/user/ntuser/display.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/displa…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/display.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/display.c [iso-8859-1] Sun Sep 11 19:05:27 2016
@@ -571,12 +571,12 @@
     _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)
     {
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 19:05:27
2016
@@ -301,7 +301,10 @@
     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 @@
         pusDeviceName = &usDeviceName;
     }
-    Status = NtUserEnumDisplaySettings(pusDeviceName, iModeNum, lpDevMode, dwFlags);
-
-    return NT_SUCCESS(Status);
+    /* Allocate memory for DEVMODEW and extra data */
+    lpExtendedDevMode = RtlAllocateHeap(RtlGetProcessHeap(),
+                                        HEAP_ZERO_MEMORY,
+                                        sizeof(DEVMODEW) + lpDevMode->dmDriverExtra);
+    if (!lpExtendedDevMode)
+        return FALSE;
+
+    /* 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 @@
     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);
 }