http://bugs.winehq.org/show_bug.cgi?id=19400
--- Comment #15 from Nate Eldredge nate@thatsmathematics.com 2009-11-10 18:36:36 --- Okay, so to summarize, there are three issues.
1. PSDRV_ExtDeviceMode is declared as CDECL, but MS KB says it should be CALLBACK (because it should be called through a pointer of type LPFNDEVMODE) and qwp.exe seems to expect this too. I think they are right and this is a wine bug. I'd submit a patch but I'm not sure of exactly the right way to update the specs file, or if any other changes are needed. (If nobody else does this I'll attach a patch anyway, just for posterity and so that people can run this application.)
2. qwp.exe calls ExtDeviceMode with lpszDevice == NULL and dwMode == 0, expecting to get the size of a buffer for a DEVMODE. This looks like a bug in qwp since this behavior is nowhere documented to work; you are supposed to pass a device name for lpszDevice. This can be worked around in wine either by having it fill in an appropriate device name somehow (e.g. environment variable) or just by having it return an arbitrary "large enough" size. Someone with a Windows box might test what Windows does (sample code at http://support.microsoft.com/kb/112641 could be adapted), and if we can understand it we could try to match its undocumented behavior.
3. Meaning of the first two arguments to ExtDeviceMode is in question.
MSDN (http://msdn.microsoft.com/en-us/library/aa506558.aspx) says: LONG ExtDeviceMode(IN HWND hWnd, IN HANDLE hInst, [...]). Arguments described as:
hWnd Handle to the parent window for the printer-configuration property sheet. hInst Not used. Handle to the module instance of the device driver.
KB (http://support.microsoft.com/kb/112641) says ExtDeviceMode(hWnd, hDriver, [...]). hDriver is a value returned by LoadLibrary().
Wine has PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, [...])
FWIW, qwp calls ExtDeviceMode from two places. The first time it does:
ExtDeviceMode(0, 0x7db40000, [...])
where 0x7db40000 is a value returned from GetModuleHandleA. This is maybe consistent with the MSDN definition.
The second time it does:
ExtDeviceMode("WINEPS.DRV", 0, [...])
which really doesn't make much sense at all.
On the other hand, qwp seems to work fine with the wine code as it is. So maybe it is not worth fixing what isn't broken, if we don't understand how it ought to be anyway.