Dmitry Timoshkov : winspool: Implement IsValidDevmodeW.

Alexandre Julliard julliard at winehq.org
Wed Oct 16 16:59:29 CDT 2019


Module: wine
Branch: master
Commit: bd7ba264b65fed67a68c9c06c7686af8c192b2a5
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=bd7ba264b65fed67a68c9c06c7686af8c192b2a5

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Mon Oct  7 10:59:41 2019 +0800

winspool: Implement IsValidDevmodeW.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winspool.drv/info.c       | 58 ++++++++++++++++++++++++++++++----
 dlls/winspool.drv/tests/info.c | 70 ++++++++++++++++++++++++++++--------------
 include/winspool.h             |  3 ++
 3 files changed, 102 insertions(+), 29 deletions(-)

diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 1ab5e43aef..0065801d90 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -104,6 +104,9 @@
 #undef UnionRect
 #endif
 
+#define NONAMELESSSTRUCT
+#define NONAMELESSUNION
+
 #include "wine/library.h"
 #include "windef.h"
 #include "winbase.h"
@@ -2449,7 +2452,7 @@ LONG WINAPI DocumentPropertiesW(HWND hWnd, HANDLE hPrinter,
  * Validate a DEVMODE structure and fix errors if possible.
  *
  */
-BOOL WINAPI IsValidDevmodeA(PDEVMODEA *pDevMode, SIZE_T size)
+BOOL WINAPI IsValidDevmodeA(PDEVMODEA pDevMode, SIZE_T size)
 {
     FIXME("(%p,%ld): stub\n", pDevMode, size);
 
@@ -2465,12 +2468,55 @@ BOOL WINAPI IsValidDevmodeA(PDEVMODEA *pDevMode, SIZE_T size)
  * Validate a DEVMODE structure and fix errors if possible.
  *
  */
-BOOL WINAPI IsValidDevmodeW(PDEVMODEW *pDevMode, SIZE_T size)
-{
-    FIXME("(%p,%ld): stub\n", pDevMode, size);
+BOOL WINAPI IsValidDevmodeW(PDEVMODEW dm, SIZE_T size)
+{
+    static const struct
+    {
+        DWORD flag;
+        SIZE_T size;
+    } map[] =
+    {
+#define F_SIZE(field) FIELD_OFFSET(DEVMODEW, field) + sizeof(dm->field)
+        { DM_ORIENTATION, F_SIZE(u1.s1.dmOrientation) },
+        { DM_PAPERSIZE, F_SIZE(u1.s1.dmPaperSize) },
+        { DM_PAPERLENGTH, F_SIZE(u1.s1.dmPaperLength) },
+        { DM_PAPERWIDTH, F_SIZE(u1.s1.dmPaperWidth) },
+        { DM_SCALE, F_SIZE(u1.s1.dmScale) },
+        { DM_COPIES, F_SIZE(u1.s1.dmCopies) },
+        { DM_DEFAULTSOURCE, F_SIZE(u1.s1.dmDefaultSource) },
+        { DM_PRINTQUALITY, F_SIZE(u1.s1.dmPrintQuality) },
+        { DM_POSITION, F_SIZE(u1.s2.dmPosition) },
+        { DM_DISPLAYORIENTATION, F_SIZE(u1.s2.dmDisplayOrientation) },
+        { DM_DISPLAYFIXEDOUTPUT, F_SIZE(u1.s2.dmDisplayFixedOutput) },
+        { DM_COLOR, F_SIZE(dmColor) },
+        { DM_DUPLEX, F_SIZE(dmDuplex) },
+        { DM_YRESOLUTION, F_SIZE(dmYResolution) },
+        { DM_TTOPTION, F_SIZE(dmTTOption) },
+        { DM_COLLATE, F_SIZE(dmCollate) },
+        { DM_FORMNAME, F_SIZE(dmFormName) },
+        { DM_LOGPIXELS, F_SIZE(dmLogPixels) },
+        { DM_BITSPERPEL, F_SIZE(dmBitsPerPel) },
+        { DM_PELSWIDTH, F_SIZE(dmPelsWidth) },
+        { DM_PELSHEIGHT, F_SIZE(dmPelsHeight) },
+        { DM_DISPLAYFLAGS, F_SIZE(u2.dmDisplayFlags) },
+        { DM_NUP, F_SIZE(u2.dmNup) },
+        { DM_DISPLAYFREQUENCY, F_SIZE(dmDisplayFrequency) },
+        { DM_ICMMETHOD, F_SIZE(dmICMMethod) },
+        { DM_ICMINTENT, F_SIZE(dmICMIntent) },
+        { DM_MEDIATYPE, F_SIZE(dmMediaType) },
+        { DM_DITHERTYPE, F_SIZE(dmDitherType) },
+        { DM_PANNINGWIDTH, F_SIZE(dmPanningWidth) },
+        { DM_PANNINGHEIGHT, F_SIZE(dmPanningHeight) }
+#undef F_SIZE
+    };
+    int i;
 
-    if(!pDevMode)
-        return FALSE;
+    if (!dm) return FALSE;
+    if (size < FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(dm->dmFields)) return FALSE;
+
+    for (i = 0; i < ARRAY_SIZE(map); i++)
+        if ((dm->dmFields & map[i].flag) && size < map[i].size)
+            return FALSE;
 
     return TRUE;
 }
diff --git a/dlls/winspool.drv/tests/info.c b/dlls/winspool.drv/tests/info.c
index 03a2e3cd32..f102bb11d9 100644
--- a/dlls/winspool.drv/tests/info.c
+++ b/dlls/winspool.drv/tests/info.c
@@ -75,8 +75,6 @@ static BOOL  (WINAPI * pGetPrinterDriverW)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD,
 static BOOL  (WINAPI * pGetPrinterW)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
 static BOOL  (WINAPI * pSetDefaultPrinterA)(LPCSTR);
 static DWORD (WINAPI * pXcvDataW)(HANDLE, LPCWSTR, PBYTE, DWORD, PBYTE, DWORD, PDWORD, PDWORD);
-static BOOL  (WINAPI * pIsValidDevmodeW)(PDEVMODEW, SIZE_T);
-
 
 /* ################################ */
 
@@ -2905,26 +2903,6 @@ static void test_DeviceCapabilities(void)
     GlobalFree(prn_dlg.hDevNames);
 }
 
-static void test_IsValidDevmodeW(void)
-{
-    BOOL br;
-
-    if (!pIsValidDevmodeW)
-    {
-        win_skip("IsValidDevmodeW not implemented.\n");
-        return;
-    }
-
-    br = pIsValidDevmodeW(NULL, 0);
-    ok(br == FALSE, "Got %d\n", br);
-
-    br = pIsValidDevmodeW(NULL, 1);
-    ok(br == FALSE, "Got %d\n", br);
-
-    br = pIsValidDevmodeW(NULL, sizeof(DEVMODEW));
-    ok(br == FALSE, "Got %d\n", br);
-}
-
 static void test_OpenPrinter_defaults(void)
 {
     HANDLE printer;
@@ -3044,6 +3022,53 @@ todo_wine
     ClosePrinter( printer );
 }
 
+static void test_IsValidDevmodeW(void)
+{
+    static const struct
+    {
+        DWORD dmFields;
+        WORD dmSize;
+        BOOL ret;
+    } test[] =
+    {
+        { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 0, FALSE },
+        { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 1, FALSE },
+        { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 2, FALSE },
+        { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 3, FALSE },
+        { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 4, TRUE },
+
+        { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 0, FALSE },
+        { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 1, FALSE },
+        { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 2, TRUE },
+
+        { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 0, FALSE },
+        { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 1, FALSE },
+        { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 2, FALSE },
+        { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 3, FALSE },
+        { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 4, TRUE },
+
+    };
+    DEVMODEW dm;
+    int i;
+    BOOL ret;
+
+    ret = IsValidDevmodeW(NULL, 0);
+    ok(!ret, "got %d\n", ret);
+
+    ret = IsValidDevmodeW(NULL, sizeof(DEVMODEW));
+    ok(!ret, "got %d\n", ret);
+
+    memset(&dm, 0, sizeof(dm));
+
+    for (i = 0; i < ARRAY_SIZE(test); i++)
+    {
+        dm.dmSize = test[i].dmSize;
+        dm.dmFields = test[i].dmFields;
+        ret = IsValidDevmodeW(&dm, dm.dmSize);
+        ok(ret == test[i].ret, "%d: got %d\n", i, ret);
+    }
+}
+
 START_TEST(info)
 {
     hwinspool = LoadLibraryA("winspool.drv");
@@ -3055,7 +3080,6 @@ START_TEST(info)
     pGetPrinterW = (void *) GetProcAddress(hwinspool, "GetPrinterW");
     pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
     pXcvDataW = (void *) GetProcAddress(hwinspool, "XcvDataW");
-    pIsValidDevmodeW = (void *) GetProcAddress(hwinspool, "IsValidDevmodeW");
 
     on_win9x = check_win9x();
     if (on_win9x)
diff --git a/include/winspool.h b/include/winspool.h
index d9e8f404cd..4c170b861e 100644
--- a/include/winspool.h
+++ b/include/winspool.h
@@ -1761,6 +1761,9 @@ BOOL WINAPI XcvDataW(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData,
     DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData,
     PDWORD pcbOutputNeeded, PDWORD pdwStatus);
 
+BOOL WINAPI IsValidDevmodeA(PDEVMODEA pDevMode, SIZE_T size);
+BOOL WINAPI IsValidDevmodeW(PDEVMODEW pDevMode, SIZE_T size);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif




More information about the wine-cvs mailing list