user32: Make ChangeDisplaySettingsA/W reset dmDriverExtra to 0 like XP and Vista do

Dmitry Timoshkov dmitry at codeweavers.com
Sun May 18 04:47:14 CDT 2008


Hello,

this patch fixes a regression reported in the bug 13264. It looks like NT
based Windows implementations of not Ex versions of ChangeDisplaySettings
reset dmDriverExtra to 0. According to the tests Win98 doesn't do that.
The patch should also eliminate the crash reported in the bug 12358.

The tests pass under XP SP3 and Vista SP1.

Changelog:
    user32: Make ChangeDisplaySettingsA/W reset dmDriverExtra to 0 like
    XP and Vista do.
---
 dlls/user32/sysparams.c     |    4 +++
 dlls/user32/tests/monitor.c |   53 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c
index 71e846d..b2fe627 100644
--- a/dlls/user32/sysparams.c
+++ b/dlls/user32/sysparams.c
@@ -2975,6 +2975,8 @@ HPEN SYSCOLOR_GetPen( INT index )
  */
 LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA devmode, DWORD flags )
 {
+    if (devmode) devmode->dmDriverExtra = 0;
+
     return ChangeDisplaySettingsExA(NULL,devmode,NULL,flags,NULL);
 }
 
@@ -2984,6 +2986,8 @@ LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA devmode, DWORD flags )
  */
 LONG WINAPI ChangeDisplaySettingsW( LPDEVMODEW devmode, DWORD flags )
 {
+    if (devmode) devmode->dmDriverExtra = 0;
+
     return ChangeDisplaySettingsExW(NULL,devmode,NULL,flags,NULL);
 }
 
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index a723dd1..c587d06 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -131,7 +131,9 @@ static const struct vid_mode vid_modes_test[] = {
     {  0, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT, 0},
     {640,   0, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT, 0},
 
-    {0, 0, 0, 0, DM_DISPLAYFREQUENCY, 0},
+    /* the following test succeeds under XP SP3
+    {0, 0, 0, 0, DM_DISPLAYFREQUENCY, 0}
+    */
 };
 #define vid_modes_cnt (sizeof(vid_modes_test) / sizeof(vid_modes_test[0]))
 
@@ -155,6 +157,44 @@ static void test_ChangeDisplaySettingsEx(void)
 
     width = dm.dmPelsWidth;
 
+    dm.dmDriverExtra = 1;
+    res = ChangeDisplaySettingsA(&dm, CDS_TEST);
+    ok(res == DISP_CHANGE_SUCCESSFUL,
+       "ChangeDisplaySettingsA returned %d, expected DISP_CHANGE_SUCCESSFUL\n", res);
+    ok(dm.dmDriverExtra == 0, "ChangeDisplaySettingsA didn't reset dmDriverExtra to 0\n");
+
+    /* crashes under XP SP3 for large dmDriverExtra values */
+    dm.dmDriverExtra = 1;
+    res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_TEST, NULL);
+    ok(res == DISP_CHANGE_SUCCESSFUL,
+       "ChangeDisplaySettingsExW returned %d, expected DISP_CHANGE_BADMODE\n", res);
+    ok(dm.dmDriverExtra == 1, "ChangeDisplaySettingsExA shouldn't reset dmDriverExtra to 0\n");
+
+    memset(&dmW, 0, sizeof(dmW));
+    dmW.dmSize = sizeof(dmW);
+    dmW.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
+    dmW.dmPelsWidth = dm.dmPelsWidth;
+    dmW.dmPelsHeight = dm.dmPelsHeight;
+    dmW.dmDriverExtra = 1;
+    SetLastError(0xdeadbeef);
+    res = ChangeDisplaySettingsW(&dmW, CDS_TEST);
+    if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        ok(res == DISP_CHANGE_SUCCESSFUL,
+           "ChangeDisplaySettingsW returned %d, expected DISP_CHANGE_SUCCESSFUL\n", res);
+        ok(dmW.dmDriverExtra == 0, "ChangeDisplaySettingsW didn't reset dmDriverExtra to 0\n");
+    }
+
+    /* Apparently XP treats dmDriverExtra being != 0 as an error */
+    dmW.dmDriverExtra = 1;
+    res = pChangeDisplaySettingsExW(NULL, &dmW, NULL, CDS_TEST, NULL);
+    if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        ok(res == DISP_CHANGE_SUCCESSFUL,
+           "ChangeDisplaySettingsExW returned %d, expected DISP_CHANGE_BADMODE\n", res);
+        ok(dmW.dmDriverExtra == 1, "ChangeDisplaySettingsExW shouldn't reset dmDriverExtra to 0\n");
+    }
+
     /* the following 2 tests show that dm.dmSize being 0 is invalid, but
      * ChangeDisplaySettingsExA still reports success.
      */
@@ -171,8 +211,9 @@ static void test_ChangeDisplaySettingsEx(void)
     SetLastError(0xdeadbeef);
     res = pChangeDisplaySettingsExW(NULL, &dmW, NULL, CDS_TEST, NULL);
     if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
-        ok(res == DISP_CHANGE_FAILED,
-           "ChangeDisplaySettingsExW returned %d, expected DISP_CHANGE_FAILED\n", res);
+        ok(res == DISP_CHANGE_FAILED ||
+           res == DISP_CHANGE_BADMODE /* XP SP3 */,
+           "ChangeDisplaySettingsExW returned %d, expected DISP_CHANGE_FAILED or DISP_CHANGE_BADMODE\n", res);
 
     memset(&dm, 0, sizeof(dm));
     dm.dmSize = sizeof(dm);
@@ -184,7 +225,7 @@ static void test_ChangeDisplaySettingsEx(void)
         dm.dmBitsPerPel       = vid_modes_test[i].bpp;
         dm.dmDisplayFrequency = vid_modes_test[i].freq;
         dm.dmFields           = vid_modes_test[i].fields;
-        res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_FULLSCREEN, NULL);
+        res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_TEST, NULL);
         ok(vid_modes_test[i].success ?
            (res == DISP_CHANGE_SUCCESSFUL) :
            (res == DISP_CHANGE_BADMODE || res == DISP_CHANGE_BADPARAM),
@@ -243,8 +284,8 @@ START_TEST(monitor)
 {
     init_function_pointers();
     test_enumdisplaydevices();
-    if (winetest_interactive)
-        test_ChangeDisplaySettingsEx();
+    test_ChangeDisplaySettingsEx();
+
     if (pMonitorFromPoint && pMonitorFromWindow)
         test_monitors();
     else
-- 
1.5.5.1






More information about the wine-patches mailing list