[2/2] user32: Add a test for an invalid DEVMODE passed to ChangeDisplaySettings, make it pass under Wine
Dmitry Timoshkov
dmitry at codeweavers.com
Thu Dec 20 00:50:30 CST 2007
Hello,
the app in the bug 10799 passes an invalid DEVMODEA (dmSize == 0) to
ChangeDisplaySettings, as the test shows GdiConvertToDevmodeW fails to
convert such a DEVMODEA structure and returns NULL, I've added a test
case to see how ChangeDisplaySettingsA/W handle this case.
Changelog:
[2/2] 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,
--
1.5.3.7
More information about the wine-patches
mailing list