kernel32: Add more tests for getting/setting a named pipe's state.
[wine] / dlls / comdlg32 / tests / printdlg.c
1 /* 
2  * Unit test suite for comdlg32 API functions: printer dialogs
3  *
4  * Copyright 2006-2007 Detlef Riekenberg
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  */
21
22 #include <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "objbase.h"
30
31 #include "cderr.h"
32 #include "commdlg.h"
33
34 #include "wine/test.h"
35
36 /* ########################### */
37
38 static HMODULE  hcomdlg32;
39 static HRESULT (WINAPI * pPrintDlgExA)(LPPRINTDLGEXA);
40 static HRESULT (WINAPI * pPrintDlgExW)(LPPRINTDLGEXW);
41
42 /* ########################### */
43
44 static const CHAR emptyA[] = "";
45 static const CHAR PrinterPortsA[] = "PrinterPorts";
46
47 /* ########################### */
48
49 static LPCSTR load_functions(void)
50 {
51     LPCSTR  ptr;
52
53     ptr = "comdlg32.dll";
54     hcomdlg32 = GetModuleHandleA(ptr);
55
56     ptr = "PrintDlgExA";
57     pPrintDlgExA = (void *) GetProcAddress(hcomdlg32, ptr);
58     if (!pPrintDlgExA) return ptr;
59
60     ptr = "PrintDlgExW";
61     pPrintDlgExW = (void *) GetProcAddress(hcomdlg32, ptr);
62     if (!pPrintDlgExW) return ptr;
63
64     return NULL;
65
66 }
67
68 /* ########################### */
69
70 static void test_PageSetupDlgA(void)
71 {
72     LPPAGESETUPDLGA pDlg;
73     DWORD res;
74
75     pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PAGESETUPDLGA)) * 2);
76     if (!pDlg) return;
77
78     SetLastError(0xdeadbeef);
79     res = PageSetupDlgA(NULL);
80     ok( !res && (CommDlgExtendedError() == CDERR_INITIALIZATION),
81         "returned %u with %u and 0x%x (expected '0' and "
82         "CDERR_INITIALIZATION)\n", res, GetLastError(), CommDlgExtendedError());
83
84     ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
85     pDlg->lStructSize = sizeof(PAGESETUPDLGA) -1;
86     SetLastError(0xdeadbeef);
87     res = PageSetupDlgA(pDlg);
88     ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
89         "returned %u with %u and 0x%x (expected '0' and "
90         "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
91
92     ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
93     pDlg->lStructSize = sizeof(PAGESETUPDLGA) +1;
94     pDlg->Flags = PSD_RETURNDEFAULT;
95     SetLastError(0xdeadbeef);
96     res = PageSetupDlgA(pDlg);
97     ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
98         "returned %u with %u and 0x%x (expected '0' and CDERR_STRUCTSIZE)\n",
99         res, GetLastError(), CommDlgExtendedError());
100
101
102     ZeroMemory(pDlg, sizeof(PAGESETUPDLGA));
103     pDlg->lStructSize = sizeof(PAGESETUPDLGA);
104     pDlg->Flags = PSD_RETURNDEFAULT | PSD_NOWARNING;
105     SetLastError(0xdeadbeef);
106     res = PageSetupDlgA(pDlg);
107     ok( res || (CommDlgExtendedError() == PDERR_NODEFAULTPRN),
108         "returned %u with %u and 0x%x (expected '!= 0' or '0' and "
109         "PDERR_NODEFAULTPRN)\n", res, GetLastError(), CommDlgExtendedError());
110
111     if (!res && (CommDlgExtendedError() == PDERR_NODEFAULTPRN)) {
112         skip("No printer configured.\n");
113         HeapFree(GetProcessHeap(), 0, pDlg);
114         return;
115     }
116
117     ok( pDlg->hDevMode && pDlg->hDevNames,
118         "got %p and %p (expected '!= NULL' for both)\n",
119         pDlg->hDevMode, pDlg->hDevNames);
120
121     GlobalFree(pDlg->hDevMode);
122     GlobalFree(pDlg->hDevNames);
123
124     HeapFree(GetProcessHeap(), 0, pDlg);
125
126 }
127
128 /* ########################### */
129
130 static void test_PrintDlgA(void)
131 {
132     DWORD       res;
133     LPPRINTDLGA pDlg;
134     DEVNAMES    *pDevNames;
135     LPCSTR driver;
136     LPCSTR device;
137     LPCSTR port;
138     CHAR   buffer[MAX_PATH];
139     LPSTR  ptr;
140
141
142     pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PRINTDLGA)) * 2);
143     if (!pDlg) return;
144
145
146     /* will crash with unpatched wine */
147     SetLastError(0xdeadbeef);
148     res = PrintDlgA(NULL);
149     ok( !res && (CommDlgExtendedError() == CDERR_INITIALIZATION),
150         "returned %d with 0x%x and 0x%x (expected '0' and "
151         "CDERR_INITIALIZATION)\n", res, GetLastError(), CommDlgExtendedError());
152
153     ZeroMemory(pDlg, sizeof(PRINTDLGA));
154     pDlg->lStructSize = sizeof(PRINTDLGA) - 1;
155     SetLastError(0xdeadbeef);
156     res = PrintDlgA(pDlg);
157     ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
158         "returned %d with 0x%x and 0x%x (expected '0' and "
159         "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
160
161     ZeroMemory(pDlg, sizeof(PRINTDLGA));
162     pDlg->lStructSize = sizeof(PRINTDLGA) + 1;
163     pDlg->Flags = PD_RETURNDEFAULT;
164     SetLastError(0xdeadbeef);
165     res = PrintDlgA(pDlg);
166     ok( !res && (CommDlgExtendedError() == CDERR_STRUCTSIZE),
167         "returned %u with %u and 0x%x (expected '0' and "
168         "CDERR_STRUCTSIZE)\n", res, GetLastError(), CommDlgExtendedError());
169
170
171     ZeroMemory(pDlg, sizeof(PRINTDLGA));
172     pDlg->lStructSize = sizeof(PRINTDLGA);
173     pDlg->Flags = PD_RETURNDEFAULT;
174     SetLastError(0xdeadbeef);
175     res = PrintDlgA(pDlg);
176     ok( res || (CommDlgExtendedError() == PDERR_NODEFAULTPRN),
177         "returned %d with 0x%x and 0x%x (expected '!= 0' or '0' and "
178         "PDERR_NODEFAULTPRN)\n", res, GetLastError(), CommDlgExtendedError());
179
180     if (!res && (CommDlgExtendedError() == PDERR_NODEFAULTPRN)) {
181         skip("No printer configured.\n");
182         HeapFree(GetProcessHeap(), 0, pDlg);
183         return;
184     }
185
186     ok(pDlg->hDevNames != NULL, "(expected '!= NULL')\n");
187     pDevNames = GlobalLock(pDlg->hDevNames);
188     ok(pDevNames != NULL, "(expected '!= NULL')\n");
189
190     if (pDevNames) {
191         ok(pDevNames->wDriverOffset, "(expected '!= 0' for wDriverOffset)\n");
192         ok(pDevNames->wDeviceOffset, "(expected '!= 0' for wDeviceOffset)\n");
193         ok(pDevNames->wOutputOffset, "(expected '!= 0' for wOutputOffset)\n");
194         ok(pDevNames->wDefault == DN_DEFAULTPRN, "got 0x%x (expected DN_DEFAULTPRN)\n", pDevNames->wDefault);
195
196         driver = (LPCSTR)pDevNames + pDevNames->wDriverOffset;
197         device = (LPCSTR)pDevNames + pDevNames->wDeviceOffset;
198         port = (LPCSTR)pDevNames + pDevNames->wOutputOffset;
199         trace("driver '%s' device '%s' port '%s'\n", driver, device, port);
200
201         /* The Driver Entry does not include a Path */
202         ptr = strrchr(driver, '\\');
203         todo_wine {
204         ok( ptr == NULL, "got %p for '%s' (expected NULL for a simple name)\n", ptr, driver);
205         }
206
207         /* The Driver Entry does not have an extension (fixed to ".drv") */
208         ptr = strrchr(driver, '.');
209         todo_wine {
210         ok( ptr == NULL, "got %p for '%s' (expected NULL for no extension)\n", ptr, driver);
211         }
212
213
214         buffer[0] = '\0';
215         SetLastError(0xdeadbeef);
216         res = GetProfileStringA(PrinterPortsA, device, emptyA, buffer, sizeof(buffer));
217         ptr = strchr(buffer, ',');
218         ok( (res > 1) && (ptr != NULL),
219             "got %u with %u and %p for '%s' (expected '>1' and '!= NULL')\n",
220             res, GetLastError(), ptr, buffer);
221
222         if (ptr) ptr[0] = '\0';
223         todo_wine {
224         ok( lstrcmpiA(driver, buffer) == 0,
225             "got driver '%s' (expected '%s')\n", driver, buffer);
226         }
227
228     }
229
230     GlobalUnlock(pDlg->hDevNames);
231
232     GlobalFree(pDlg->hDevMode);
233     GlobalFree(pDlg->hDevNames);
234     HeapFree(GetProcessHeap(), 0, pDlg);
235
236 }
237
238 /* ########################### */
239
240 static void test_PrintDlgExW(void)
241 {
242     LPPRINTDLGEXW pDlg;
243     HRESULT res;
244
245     /* Set CommDlgExtendedError != 0 */
246     PrintDlg(NULL);
247     SetLastError(0xdeadbeef);
248     res = pPrintDlgExW(NULL);
249     ok( (res == E_INVALIDARG),
250         "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
251         res, GetLastError(), CommDlgExtendedError());
252
253
254     pDlg = HeapAlloc(GetProcessHeap(), 0, (sizeof(PRINTDLGEXW)) + 8);
255     if (!pDlg) return;
256
257     /* lStructSize must be exact */
258     ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
259     pDlg->lStructSize = sizeof(PRINTDLGEXW) - 1;
260     PrintDlg(NULL);
261     SetLastError(0xdeadbeef);
262     res = pPrintDlgExW(pDlg);
263     ok( (res == E_INVALIDARG),
264         "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
265         res, GetLastError(), CommDlgExtendedError());
266
267
268     ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
269     pDlg->lStructSize = sizeof(PRINTDLGEXW) + 1;
270     PrintDlg(NULL);
271     SetLastError(0xdeadbeef);
272     res = pPrintDlgExW(pDlg);
273     ok( (res == E_INVALIDARG),
274         "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
275         res, GetLastError(), CommDlgExtendedError());
276
277
278     ZeroMemory(pDlg, sizeof(PRINTDLGEXW));
279     pDlg->lStructSize = sizeof(PRINTDLGEXW);
280     SetLastError(0xdeadbeef);
281     res = pPrintDlgExW(pDlg);
282     ok( (res == E_HANDLE),
283         "got 0x%x with %u and %u (expected 'E_HANDLE')\n",
284         res, GetLastError(), CommDlgExtendedError());
285
286
287     HeapFree(GetProcessHeap(), 0, pDlg);
288     return;
289
290 }
291
292 static BOOL abort_proc_called = FALSE;
293 static BOOL CALLBACK abort_proc(HDC hdc, int error) { return abort_proc_called = TRUE; }
294 static void test_abort_proc(void)
295 {
296     HDC print_dc;
297     RECT rect = {0, 0, 100, 100};
298     DOCINFOA doc_info = {0};
299     PRINTDLGA pd = {0};
300     char filename[MAX_PATH];
301
302     if (!GetTempFileNameA(".", "prn", 0, filename))
303     {
304         skip("Failed to create a temporary file name\n");
305         return;
306     }
307
308     pd.lStructSize = sizeof(pd);
309     pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE;
310     pd.nFromPage = 1;
311     pd.nToPage = 1;
312     pd.nCopies = 1;
313
314     if (!PrintDlgA(&pd))
315     {
316         skip("No default printer available.\n");
317         ok(DeleteFileA(filename), "Failed to delete temporary file\n");
318         return;
319     }
320
321     ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n");
322     if (!(print_dc = pd.hDC))
323     {
324         ok(DeleteFileA(filename), "Failed to delete temporary file\n");
325         return;
326     }
327
328     ok(SetAbortProc(print_dc, abort_proc) > 0, "SetAbortProc failed\n");
329     ok(!abort_proc_called, "AbortProc got called unexpectedly by SetAbortProc.\n");
330     abort_proc_called = FALSE;
331
332     doc_info.cbSize = sizeof(doc_info);
333     doc_info.lpszDocName = "Some document";
334     doc_info.lpszOutput = filename;
335
336     ok(StartDocA(print_dc, &doc_info) > 0, "StartDocA failed\n");
337     ok(abort_proc_called, "AbortProc didn't get called by StartDoc.\n");
338     abort_proc_called = FALSE;
339
340     ok(StartPage(print_dc) > 0, "StartPage failed\n");
341     ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n");
342     abort_proc_called = FALSE;
343
344     ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n");
345     ok(!abort_proc_called, "AbortProc got called unexpectedly by StretchBlt.\n");
346     abort_proc_called = FALSE;
347
348     ok(EndPage(print_dc) > 0, "EndPage failed\n");
349     ok(!abort_proc_called, "AbortProc got called unexpectedly by EndPage.\n");
350     abort_proc_called = FALSE;
351
352     ok(EndDoc(print_dc) > 0, "EndDoc failed\n");
353     ok(!abort_proc_called, "AbortProc got called unexpectedly by EndDoc.\n");
354     abort_proc_called = FALSE;
355
356     ok(DeleteDC(print_dc), "DeleteDC failed\n");
357     ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n");
358     abort_proc_called = FALSE;
359
360     ok(DeleteFileA(filename), "Failed to delete temporary file\n");
361 }
362
363 /* ########################### */
364
365 START_TEST(printdlg)
366 {
367     LPCSTR  ptr;
368
369     ptr = load_functions();
370
371     test_PageSetupDlgA();
372     test_PrintDlgA();
373     test_abort_proc();
374
375     /* PrintDlgEx not present before w2k */
376     if (ptr) {
377         skip("%s\n", ptr);
378         return;
379     }
380
381     test_PrintDlgExW();
382 }