Dmitry Timoshkov : user32: Add a test for an invalid DEVMODE passed to ChangeDisplaySettings, make it pass under Wine.

Alexandre Julliard julliard at winehq.org
Thu Dec 20 06:21:45 CST 2007


Module: wine
Branch: master
Commit: 78718a41c7304cde78275a6e6d706bd7565eeca8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=78718a41c7304cde78275a6e6d706bd7565eeca8

Author: Dmitry Timoshkov <dmitry at codeweavers.com>
Date:   Thu Dec 20 14:50:30 2007 +0800

user32: Add a test for an invalid DEVMODE passed to ChangeDisplaySettings, make it pass under Wine.

---

 dlls/user32/sysparams.c     |    9 +++++++--
 dlls/user32/tests/monitor.c |   33 +++++++++++++++++++++++++++++++--
 dlls/winex11.drv/settings.c |    4 ++++
 3 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c
index dd44639..8cd2dcb 100644
--- a/dlls/user32/sysparams.c
+++ b/dlls/user32/sysparams.c
@@ -2999,8 +2999,13 @@ LONG WINAPI ChangeDisplaySettingsExA( LPCSTR devname, LPDEVMODEA devmode, HWND h
         DEVMODEW *devmodeW;
 
         devmodeW = GdiConvertToDevmodeW(devmode);
-        ret = ChangeDisplaySettingsExW(nameW.Buffer, devmodeW, hwnd, flags, lparam);
-        HeapFree(GetProcessHeap(), 0, devmodeW);
+        if (devmodeW)
+        {
+            ret = ChangeDisplaySettingsExW(nameW.Buffer, devmodeW, hwnd, flags, lparam);
+            HeapFree(GetProcessHeap(), 0, devmodeW);
+        }
+        else
+            ret = DISP_CHANGE_SUCCESSFUL;
     }
     else
     {
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index 14acdf5..a723dd1 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -25,6 +25,7 @@
 
 static HMODULE hdll;
 static LONG (WINAPI *pChangeDisplaySettingsExA)(LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID);
+static LONG (WINAPI *pChangeDisplaySettingsExW)(LPCWSTR, LPDEVMODEW, HWND, DWORD, LPVOID);
 static BOOL (WINAPI *pEnumDisplayDevicesA)(LPCSTR,DWORD,LPDISPLAY_DEVICEA,DWORD);
 static BOOL (WINAPI *pEnumDisplayMonitors)(HDC,LPRECT,MONITORENUMPROC,LPARAM);
 static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
@@ -41,6 +42,7 @@ static void init_function_pointers(void)
       trace("GetProcAddress(%s) failed\n", #func);
 
     GET_PROC(ChangeDisplaySettingsExA)
+    GET_PROC(ChangeDisplaySettingsExW)
     GET_PROC(EnumDisplayDevicesA)
     GET_PROC(EnumDisplayMonitors)
     GET_PROC(GetMonitorInfoA)
@@ -113,7 +115,7 @@ struct vid_mode
     LONG success;
 };
 
-static struct vid_mode vid_modes_test[] = {
+static const struct vid_mode vid_modes_test[] = {
     {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY, 1},
     {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT |                 DM_DISPLAYFREQUENCY, 1},
     {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL                      , 1},
@@ -135,7 +137,9 @@ static struct vid_mode vid_modes_test[] = {
 
 static void test_ChangeDisplaySettingsEx(void)
 {
-    DEVMODE dm;
+    DEVMODEA dm;
+    DEVMODEW dmW;
+    DWORD width;
     LONG res;
     int i;
 
@@ -145,6 +149,31 @@ static void test_ChangeDisplaySettingsEx(void)
         return;
     }
 
+    SetLastError(0xdeadbeef);
+    res = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+    ok(res, "EnumDisplaySettings error %u\n", GetLastError());
+
+    width = dm.dmPelsWidth;
+
+    /* the following 2 tests show that dm.dmSize being 0 is invalid, but
+     * ChangeDisplaySettingsExA still reports success.
+     */
+    memset(&dm, 0, sizeof(dm));
+    dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
+    dm.dmPelsWidth = width;
+    res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_TEST, NULL);
+    ok(res == DISP_CHANGE_SUCCESSFUL,
+       "ChangeDisplaySettingsExA returned %d, expected DISP_CHANGE_SUCCESSFUL\n", res);
+
+    memset(&dmW, 0, sizeof(dmW));
+    dmW.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
+    dmW.dmPelsWidth = width;
+    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);
+
     memset(&dm, 0, sizeof(dm));
     dm.dmSize = sizeof(dm);
 
diff --git a/dlls/winex11.drv/settings.c b/dlls/winex11.drv/settings.c
index ada827e..373562b 100644
--- a/dlls/winex11.drv/settings.c
+++ b/dlls/winex11.drv/settings.c
@@ -358,6 +358,10 @@ LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
     TRACE("flags=%s\n",_CDS_flags(flags));
     if (devmode)
     {
+        /* this is the minimal dmSize that XP accepts */
+        if (devmode->dmSize < FIELD_OFFSET(DEVMODEW, dmFields))
+            return DISP_CHANGE_FAILED;
+
         TRACE("DM_fields=%s\n",_DM_fields(devmode->dmFields));
         TRACE("width=%d height=%d bpp=%d freq=%d (%s)\n",
               devmode->dmPelsWidth,devmode->dmPelsHeight,




More information about the wine-cvs mailing list