diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index 1ab5e43aefd..0065801d904 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) +BOOL WINAPI IsValidDevmodeW(PDEVMODEW dm, SIZE_T size) { - FIXME("(%p,%ld): stub\n", pDevMode, 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 03a2e3cd32a..f102bb11d9e 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 d9e8f404cdc..4c170b861ef 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