winspool.drv/tests: Win64 printf format warning fixes.
[wine] / dlls / winspool.drv / tests / info.c
1 /*
2  * Copyright (C) 2003, 2004 Stefan Leichter
3  * Copyright (C) 2005, 2006 Detlef Riekenberg
4  * Copyright (C) 2006 Dmitry Timoshkov
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 #include <stdarg.h>
22
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "winspool.h"
31
32 #define MAGIC_DEAD  0xdeadbeef
33 #define DEFAULT_PRINTER_SIZE 1000
34
35 static CHAR does_not_exist_dll[]= "does_not_exists.dll";
36 static CHAR empty[]             = "";
37 static CHAR env_x86[]           = "Windows NT x86";
38 static CHAR env_win9x_case[]    = "windowS 4.0";
39 static CHAR illegal_name[]      = "illegal,name";
40 static CHAR invalid_env[]       = "invalid_env";
41 static CHAR invalid_server[]    = "\\invalid_server";
42 static CHAR version_dll[]       = "version.dll";
43 static CHAR winetest_monitor[]  = "winetest";
44
45 static HANDLE  hwinspool;
46 static FARPROC pGetDefaultPrinterA;
47 static FARPROC pSetDefaultPrinterA;
48
49 struct monitor_entry {
50     LPSTR  env;
51     CHAR  dllname[32];
52 };
53
54 /* report common behavior only once */
55 static DWORD report_deactivated_spooler = 1;
56 #define RETURN_ON_DEACTIVATED_SPOOLER(res) \
57     if((res == 0) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE)) \
58     { \
59         if(report_deactivated_spooler > 0) { \
60             report_deactivated_spooler--; \
61             trace("The Service 'Spooler' is required for many test\n"); \
62         } \
63         return; \
64     }
65
66
67 static LPSTR find_default_printer(VOID)
68 {
69     static  LPSTR   default_printer = NULL;
70     static  char    buffer[DEFAULT_PRINTER_SIZE];
71     DWORD   needed;
72     DWORD   res;
73     LPSTR   ptr;
74
75     if ((default_printer == NULL) && (pGetDefaultPrinterA))
76     {
77         /* w2k and above */
78         needed = sizeof(buffer);
79         res = pGetDefaultPrinterA(buffer, &needed);
80         if(res)  default_printer = buffer;
81         trace("default_printer: '%s'\n", default_printer);
82     }
83     if (default_printer == NULL)
84     {
85         HKEY hwindows;
86         DWORD   type;
87         /* NT 3.x and above */
88         if (RegOpenKeyEx(HKEY_CURRENT_USER, 
89                         "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
90                         0, KEY_QUERY_VALUE, &hwindows) == NO_ERROR) {
91
92             needed = sizeof(buffer);
93             if (RegQueryValueEx(hwindows, "device", NULL, 
94                                 &type, (LPBYTE)buffer, &needed) == NO_ERROR) {
95
96                 ptr = strchr(buffer, ',');
97                 if (ptr) {
98                     ptr[0] = '\0';
99                     default_printer = buffer;
100                 }
101             }
102             RegCloseKey(hwindows);
103         }
104         trace("default_printer: '%s'\n", default_printer);
105     }
106     if (default_printer == NULL)
107     {
108         /* win9x */
109         needed = sizeof(buffer);
110         res = GetProfileStringA("windows", "device", "*", buffer, needed);
111         if(res) {
112             ptr = strchr(buffer, ',');
113             if (ptr) {
114                 ptr[0] = '\0';
115                 default_printer = buffer;
116             }
117         }
118         trace("default_printer: '%s'\n", default_printer);
119     }
120     return default_printer;
121 }
122
123
124 static struct monitor_entry * find_installed_monitor(void)
125 {
126     MONITOR_INFO_2A mi2a; 
127     static struct  monitor_entry * entry = NULL;
128     DWORD   num_tests;
129     DWORD   i = 0;
130
131     static struct monitor_entry  monitor_table[] = {
132         {env_win9x_case, "localspl.dll"},
133         {env_x86,        "localspl.dll"},
134         {env_win9x_case, "localmon.dll"},
135         {env_x86,        "localmon.dll"},
136         {env_win9x_case, "tcpmon.dll"},
137         {env_x86,        "tcpmon.dll"},
138         {env_win9x_case, "usbmon.dll"},
139         {env_x86,        "usbmon.dll"},
140         {env_win9x_case, "mspp32.dll"},
141         {env_x86,        "win32spl.dll"},
142         {env_x86,        "redmonnt.dll"},
143         {env_x86,        "redmon35.dll"},
144         {env_win9x_case, "redmon95.dll"},
145         {env_x86,        "pdfcmnnt.dll"},
146         {env_win9x_case, "pdfcmn95.dll"},
147     };
148
149     if (entry) return entry;
150
151     num_tests = (sizeof(monitor_table)/sizeof(struct monitor_entry));
152
153     /* cleanup */
154     DeleteMonitorA(NULL, env_x86, winetest_monitor);
155     DeleteMonitorA(NULL, env_win9x_case, winetest_monitor);
156
157     /* find a usable monitor from the table */    
158     mi2a.pName = winetest_monitor;
159     while ((entry == NULL) && (i < num_tests)) {
160         entry = &monitor_table[i];
161         i++;
162         mi2a.pEnvironment = entry->env;
163         mi2a.pDLLName = entry->dllname;
164
165         if (AddMonitorA(NULL, 2, (LPBYTE) &mi2a)) {
166             /* we got one */
167             trace("using '%s', '%s'\n", entry->env, entry->dllname);
168             DeleteMonitorA(NULL, entry->env, winetest_monitor);
169         }
170         else
171         {
172             entry = NULL;
173         }
174     }
175     return entry;
176 }
177
178 /* ########################### */
179
180
181 static void test_AddMonitor(void)
182 {
183     MONITOR_INFO_2A mi2a; 
184     struct  monitor_entry * entry = NULL;
185     DWORD   res;
186
187     entry = find_installed_monitor();
188
189     SetLastError(MAGIC_DEAD);
190     res = AddMonitorA(NULL, 1, NULL);
191     ok(!res && (GetLastError() == ERROR_INVALID_LEVEL), 
192         "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
193         res, GetLastError());
194
195     SetLastError(MAGIC_DEAD);
196     res = AddMonitorA(NULL, 3, NULL);
197     ok(!res && (GetLastError() == ERROR_INVALID_LEVEL), 
198         "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
199         res, GetLastError());
200
201 #if 0
202     /* This test crash with win9x on vmware (works with win9x on qemu 0.8.1) */
203     SetLastError(MAGIC_DEAD);
204     res = AddMonitorA(NULL, 2, NULL);
205     /* NT: unchanged,  9x: ERROR_PRIVILEGE_NOT_HELD */
206     ok(!res &&
207         ((GetLastError() == MAGIC_DEAD) ||
208          (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 
209         "returned %d with %d (expected '0' with: MAGIC_DEAD or " \
210         "ERROR_PRIVILEGE_NOT_HELD)\n", res, GetLastError());
211 #endif
212
213     ZeroMemory(&mi2a, sizeof(MONITOR_INFO_2A));
214     SetLastError(MAGIC_DEAD);
215     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
216     RETURN_ON_DEACTIVATED_SPOOLER(res)
217
218     if (!res && (GetLastError() == ERROR_ACCESS_DENIED)) {
219         trace("skip tests (ACCESS_DENIED)\n");
220         return;
221     }
222
223     /* NT: ERROR_INVALID_PARAMETER,  9x: ERROR_INVALID_ENVIRONMENT */
224     ok(!res && ((GetLastError() == ERROR_INVALID_PARAMETER) ||
225                 (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 
226         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
227         "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
228
229     if (!entry) {
230         trace("No usable Monitor found: Skip tests\n");
231         return;
232     }
233
234 #if 0
235     /* The Test is deactivated, because when mi2a.pName is NULL, the subkey
236        HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM
237        or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì
238        is created on win9x and we do not want to hit this bug here. */
239
240     mi2a.pEnvironment = entry->env;
241     SetLastError(MAGIC_DEAD);
242     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
243     /* NT: ERROR_INVALID_PARAMETER,  9x: ERROR_PRIVILEGE_NOT_HELD */
244 #endif
245
246     mi2a.pEnvironment = entry->env;
247     mi2a.pName = empty;
248     SetLastError(MAGIC_DEAD);
249     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
250     /* NT: ERROR_INVALID_PARAMETER,  9x: ERROR_PRIVILEGE_NOT_HELD */
251     ok( !res &&
252         ((GetLastError() == ERROR_INVALID_PARAMETER) ||
253          (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 
254         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
255         "ERROR_PRIVILEGE_NOT_HELD)\n",
256         res, GetLastError());
257
258     mi2a.pName = winetest_monitor;
259     SetLastError(MAGIC_DEAD);
260     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
261     /* NT: ERROR_INVALID_PARAMETER,  9x: ERROR_PRIVILEGE_NOT_HELD */
262     ok( !res &&
263         ((GetLastError() == ERROR_INVALID_PARAMETER) ||
264          (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 
265         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
266         "ERROR_PRIVILEGE_NOT_HELD)\n",
267         res, GetLastError());
268
269     mi2a.pDLLName = empty;
270     SetLastError(MAGIC_DEAD);
271     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
272     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
273         "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
274         res, GetLastError());
275
276     mi2a.pDLLName = does_not_exist_dll;
277     SetLastError(MAGIC_DEAD);
278     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
279     /* NT: ERROR_MOD_NOT_FOUND,  9x: ERROR_INVALID_PARAMETER */
280     ok( !res &&
281         ((GetLastError() == ERROR_MOD_NOT_FOUND) ||
282         (GetLastError() == ERROR_INVALID_PARAMETER)),
283         "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or " \
284         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
285
286     mi2a.pDLLName = version_dll;
287     SetLastError(MAGIC_DEAD);
288     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
289     /* NT: ERROR_PROC_NOT_FOUND,  9x: ERROR_INVALID_PARAMETER */
290     ok( !res &&
291         ((GetLastError() == ERROR_PROC_NOT_FOUND) ||
292         (GetLastError() == ERROR_INVALID_PARAMETER)),
293         "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or " \
294         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
295     if (res) DeleteMonitorA(NULL, entry->env, winetest_monitor); 
296
297    /* Test AddMonitor with real options */
298     mi2a.pDLLName = entry->dllname;
299     SetLastError(MAGIC_DEAD);
300     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
301     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
302
303     /* add a monitor twice */
304     SetLastError(MAGIC_DEAD);
305     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
306     /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */
307     ok( !res &&
308         ((GetLastError() == ERROR_PRINT_MONITOR_ALREADY_INSTALLED) ||
309         (GetLastError() == ERROR_ALREADY_EXISTS)), 
310         "returned %d with %d (expected '0' with: " \
311         "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n",
312         res, GetLastError());
313
314     DeleteMonitorA(NULL, entry->env, winetest_monitor); 
315     SetLastError(MAGIC_DEAD);
316     res = AddMonitorA(empty, 2, (LPBYTE) &mi2a);
317     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
318
319     /* cleanup */
320     DeleteMonitorA(NULL, entry->env, winetest_monitor);
321
322 }
323
324 /* ########################### */
325
326 static void test_DeleteMonitor(void)
327 {
328     MONITOR_INFO_2A         mi2a;
329     struct monitor_entry  * entry = NULL;
330     DWORD                   res;
331
332
333     entry = find_installed_monitor();
334
335     if (!entry) {
336         trace("No usable Monitor found: Skip tests\n");
337         return;
338     }
339
340     mi2a.pName = winetest_monitor;
341     mi2a.pEnvironment = entry->env;
342     mi2a.pDLLName = entry->dllname;
343
344     /* Testing DeleteMonitor with real options */
345     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
346
347     SetLastError(MAGIC_DEAD);
348     res = DeleteMonitorA(NULL, entry->env, winetest_monitor);
349     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
350
351     /* Delete the Monitor twice */
352     SetLastError(MAGIC_DEAD);
353     res = DeleteMonitorA(NULL, entry->env, winetest_monitor);
354     /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
355     ok( !res &&
356         ((GetLastError() == ERROR_UNKNOWN_PRINT_MONITOR) ||
357         (GetLastError() == ERROR_INVALID_PARAMETER)), 
358         "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR" \
359         " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
360
361     /* the environment */
362     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
363     SetLastError(MAGIC_DEAD);
364     res = DeleteMonitorA(NULL, NULL, winetest_monitor);
365     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
366
367     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
368     SetLastError(MAGIC_DEAD);
369     res = DeleteMonitorA(NULL, empty, winetest_monitor);
370     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
371
372     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
373     SetLastError(MAGIC_DEAD);
374     res = DeleteMonitorA(NULL, invalid_env, winetest_monitor);
375     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
376
377     /* the monitor-name */
378     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
379     SetLastError(MAGIC_DEAD);
380     res = DeleteMonitorA(NULL, entry->env, NULL);
381     /* NT: ERROR_INVALID_PARAMETER (87),  9x: ERROR_INVALID_NAME (123)*/
382     ok( !res &&
383         ((GetLastError() == ERROR_INVALID_PARAMETER) ||
384         (GetLastError() == ERROR_INVALID_NAME)),
385         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
386         "ERROR_INVALID_NAME)\n", res, GetLastError());
387
388     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
389     SetLastError(MAGIC_DEAD);
390     res = DeleteMonitorA(NULL, entry->env, empty);
391     /* NT: ERROR_INVALID_PARAMETER (87),  9x: ERROR_INVALID_NAME (123)*/
392     ok( !res && 
393         ((GetLastError() == ERROR_INVALID_PARAMETER) ||
394         (GetLastError() == ERROR_INVALID_NAME)),
395         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
396         "ERROR_INVALID_NAME)\n", res, GetLastError());
397
398     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
399     SetLastError(MAGIC_DEAD);
400     res = DeleteMonitorA(empty, entry->env, winetest_monitor);
401     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
402
403     /* cleanup */
404     DeleteMonitorA(NULL, entry->env, winetest_monitor);
405 }
406
407 /* ######## */
408
409 static void test_EnumForms(LPSTR pName)
410 {
411     DWORD   res;
412     HANDLE  hprinter = 0;
413     LPBYTE  buffer;
414     DWORD   cbBuf;
415     DWORD   pcbNeeded;
416     DWORD   pcReturned;
417     DWORD   level;
418   
419
420     res = OpenPrinter(pName, &hprinter, NULL);
421     RETURN_ON_DEACTIVATED_SPOOLER(res)
422     if (!res || !hprinter)
423     {
424         /* Open the local Prinserver is not supported on win9x */
425         if (pName) trace("Failed to open '%s', skiping the test\n", pName);
426         return;
427     }
428
429     /* valid levels are 1 and 2 */
430     for(level = 0; level < 4; level++) {
431         cbBuf = 0xdeadbeef;
432         pcReturned = 0xdeadbeef;
433         SetLastError(0xdeadbeef);
434         res = EnumFormsA(hprinter, level, NULL, 0, &cbBuf, &pcReturned);
435        
436         /* EnumForms is not implemented in win9x */
437         if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
438
439         /* EnumForms for the Server not implemented on all NT-Versions */
440         if (!res && (GetLastError() == ERROR_INVALID_HANDLE) && !pName) continue;
441
442         /* Level 2 for EnumForms is not supported on all systems */
443         if (!res && (GetLastError() == ERROR_INVALID_LEVEL) && (level == 2)) continue;
444
445         /* use only a short test, when we test with an invalid level */
446         if(!level || (level > 2)) {
447             ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
448                 (res && (pcReturned == 0)),
449                 "(%d) returned %d with %d and 0x%08x (expected '0' with " \
450                 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
451                 level, res, GetLastError(), pcReturned);
452             continue;
453         }        
454
455         ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
456             "(%d) returned %d with %d (expected '0' with " \
457             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
458
459         buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
460         if (buffer == NULL) continue;
461
462         SetLastError(0xdeadbeef);
463         res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
464         ok(res, "(%d) returned %d with %d (expected '!=0')\n",
465                 level, res, GetLastError());
466         /* We can dump the returned Data here */
467
468
469         SetLastError(0xdeadbeef);
470         res = EnumFormsA(hprinter, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
471         ok( res, "(%d) returned %d with %d (expected '!=0')\n",
472             level, res, GetLastError());
473
474         SetLastError(0xdeadbeef);
475         res = EnumFormsA(hprinter, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
476         ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
477             "(%d) returned %d with %d (expected '0' with " \
478             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
479
480
481         SetLastError(0xdeadbeef);
482         res = EnumFormsA(hprinter, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
483         ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) ,
484             "(%d) returned %d with %d (expected '0' with "\
485             "ERROR_INVALID_USER_BUFFER)\n", level, res, GetLastError());
486
487
488         SetLastError(0xdeadbeef);
489         res = EnumFormsA(hprinter, level, buffer, cbBuf, NULL, &pcReturned);
490         ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
491             "(%d) returned %d with %d (expected '0' with "\
492             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
493
494         SetLastError(0xdeadbeef);
495         res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, NULL);
496         ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
497             "(%d) returned %d with %d (expected '0' with "\
498             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
499
500         SetLastError(0xdeadbeef);
501         res = EnumFormsA(0, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
502         ok( !res && (GetLastError() == ERROR_INVALID_HANDLE) ,
503             "(%d) returned %d with %d (expected '0' with "\
504             "ERROR_INVALID_HANDLE)\n", level, res, GetLastError());
505
506         HeapFree(GetProcessHeap(), 0, buffer);
507     } /* for(level ... */
508
509     ClosePrinter(hprinter);
510 }
511
512 /* ########################### */
513
514 static void test_EnumMonitors(void)
515 {
516     DWORD   res;
517     LPBYTE  buffer;
518     DWORD   cbBuf;
519     DWORD   pcbNeeded;
520     DWORD   pcReturned;
521     DWORD   level;
522
523     /* valid levels are 1 and 2 */
524     for(level = 0; level < 4; level++) {
525         cbBuf = MAGIC_DEAD;
526         pcReturned = MAGIC_DEAD;
527         SetLastError(MAGIC_DEAD);
528         res = EnumMonitorsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
529
530         RETURN_ON_DEACTIVATED_SPOOLER(res)
531
532         /* not implemented yet in wine */
533         if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
534
535
536         /* use only a short test, when we test with an invalid level */
537         if(!level || (level > 2)) {
538             ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
539                 (res && (pcReturned == 0)),
540                 "(%d) returned %d with %d and 0x%08x (expected '0' with " \
541                 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
542                 level, res, GetLastError(), pcReturned);
543             continue;
544         }        
545
546         /* Level 2 is not supported on win9x */
547         if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
548             trace("Level %d not supported, skipping tests\n", level);
549             continue;
550         }
551
552         ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
553             "(%d) returned %d with %d (expected '0' with " \
554             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
555
556         if (!cbBuf) {
557             trace("no valid buffer size returned, skipping tests\n");
558             continue;
559         }
560
561         buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
562         if (buffer == NULL) continue;
563
564         SetLastError(MAGIC_DEAD);
565         pcbNeeded = MAGIC_DEAD;
566         res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
567         ok(res, "(%d) returned %d with %d (expected '!=0')\n",
568                 level, res, GetLastError());
569         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n",
570                 level, pcbNeeded, cbBuf);
571         /* We can validate the returned Data with the Registry here */
572
573
574         SetLastError(MAGIC_DEAD);
575         pcReturned = MAGIC_DEAD;
576         pcbNeeded = MAGIC_DEAD;
577         res = EnumMonitorsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
578         ok(res, "(%d) returned %d with %d (expected '!=0')\n", level,
579                 res, GetLastError());
580         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
581                 pcbNeeded, cbBuf);
582
583         SetLastError(MAGIC_DEAD);
584         pcbNeeded = MAGIC_DEAD;
585         res = EnumMonitorsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
586         ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
587             "(%d) returned %d with %d (expected '0' with " \
588             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
589
590         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
591                 pcbNeeded, cbBuf);
592
593 /*
594       Do not add the next test:
595       w2k+:  RPC_X_NULL_REF_POINTER 
596       NT3.5: ERROR_INVALID_USER_BUFFER
597       win9x: crash in winspool.drv
598
599       res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
600 */
601
602         SetLastError(MAGIC_DEAD);
603         pcbNeeded = MAGIC_DEAD;
604         pcReturned = MAGIC_DEAD;
605         res = EnumMonitorsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
606         ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
607             "(%d) returned %d with %d (expected '!=0' or '0' with "\
608             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
609
610         pcbNeeded = MAGIC_DEAD;
611         pcReturned = MAGIC_DEAD;
612         SetLastError(MAGIC_DEAD);
613         res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
614         ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
615             "(%d) returned %d with %d (expected '!=0' or '0' with "\
616             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
617
618         HeapFree(GetProcessHeap(), 0, buffer);
619     } /* for(level ... */
620 }
621
622
623 static void test_GetDefaultPrinter(void)
624 {
625     BOOL    retval;
626     DWORD   exact = DEFAULT_PRINTER_SIZE;
627     DWORD   size;
628     char    buffer[DEFAULT_PRINTER_SIZE];
629
630     if (!pGetDefaultPrinterA)  return;
631         /* only supported on NT like OSes starting with win2k */
632
633     SetLastError(ERROR_SUCCESS);
634     retval = pGetDefaultPrinterA(buffer, &exact);
635     if (!retval || !exact || !strlen(buffer) ||
636         (ERROR_SUCCESS != GetLastError())) {
637         if ((ERROR_FILE_NOT_FOUND == GetLastError()) ||
638             (ERROR_INVALID_NAME == GetLastError()))
639             trace("this test requires a default printer to be set\n");
640         else {
641                 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
642                 "function returned %s\n"
643                 "last error 0x%08x\n"
644                 "returned buffer size 0x%08x\n"
645                 "returned buffer content %s\n",
646                 retval ? "true" : "false", GetLastError(), exact, buffer);
647         }
648         return;
649     }
650     SetLastError(ERROR_SUCCESS);
651     retval = pGetDefaultPrinterA(NULL, NULL); 
652     ok( !retval, "function result wrong! False expected\n");
653     ok( ERROR_INVALID_PARAMETER == GetLastError(),
654         "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
655         GetLastError());
656
657     SetLastError(ERROR_SUCCESS);
658     retval = pGetDefaultPrinterA(buffer, NULL); 
659     ok( !retval, "function result wrong! False expected\n");
660     ok( ERROR_INVALID_PARAMETER == GetLastError(),
661         "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
662         GetLastError());
663
664     SetLastError(ERROR_SUCCESS);
665     size = 0;
666     retval = pGetDefaultPrinterA(NULL, &size); 
667     ok( !retval, "function result wrong! False expected\n");
668     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
669         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
670         GetLastError());
671     ok( size == exact, "Parameter size wrong! %d expected got %d\n",
672         exact, size);
673
674     SetLastError(ERROR_SUCCESS);
675     size = DEFAULT_PRINTER_SIZE;
676     retval = pGetDefaultPrinterA(NULL, &size); 
677     ok( !retval, "function result wrong! False expected\n");
678     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
679         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
680         GetLastError());
681     ok( size == exact, "Parameter size wrong! %d expected got %d\n",
682         exact, size);
683
684     size = 0;
685     retval = pGetDefaultPrinterA(buffer, &size); 
686     ok( !retval, "function result wrong! False expected\n");
687     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
688         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
689         GetLastError());
690     ok( size == exact, "Parameter size wrong! %d expected got %d\n",
691         exact, size);
692
693     size = exact;
694     retval = pGetDefaultPrinterA(buffer, &size); 
695     ok( retval, "function result wrong! True expected\n");
696     ok( size == exact, "Parameter size wrong! %d expected got %d\n",
697         exact, size);
698 }
699
700 static void test_GetPrinterDriverDirectory(void)
701 {
702     LPBYTE      buffer = NULL;
703     DWORD       cbBuf = 0, pcbNeeded = 0;
704     BOOL        res;
705
706
707     SetLastError(MAGIC_DEAD);
708     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
709     trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
710     res, GetLastError(), cbBuf);
711
712     RETURN_ON_DEACTIVATED_SPOOLER(res)
713     ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
714         "returned %d with lasterror=%d (expected '0' with " \
715         "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
716
717     if (!cbBuf) {
718         trace("no valid buffer size returned, skipping tests\n");
719         return;
720     }
721
722     buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
723     if (buffer == NULL)  return ;
724
725     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
726     ok( res, "expected result != 0, got %d\n", res);
727     ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
728                             pcbNeeded, cbBuf);
729
730     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
731     ok( res, "expected result != 0, got %d\n", res);
732     ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
733                             pcbNeeded, cbBuf);
734  
735     SetLastError(MAGIC_DEAD);
736     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
737     ok( !res , "expected result == 0, got %d\n", res);
738     ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
739                             pcbNeeded, cbBuf);
740     
741     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
742         "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
743         GetLastError());
744
745 /*
746     Do not add the next test:
747     XPsp2: crash in this app, when the spooler is not running 
748     NT3.5: ERROR_INVALID_USER_BUFFER
749     win9x: ERROR_INVALID_PARAMETER
750
751     pcbNeeded = MAGIC_DEAD;
752     SetLastError(MAGIC_DEAD);
753     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
754 */
755
756     SetLastError(MAGIC_DEAD);
757     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
758     ok( (!res && RPC_X_NULL_REF_POINTER == GetLastError()) || res,
759          "expected either result == 0 and "
760          "last error == RPC_X_NULL_REF_POINTER or result != 0 "
761          "got result %d and last error == %d\n", res, GetLastError());
762
763     SetLastError(MAGIC_DEAD);
764     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
765     ok(res || (GetLastError() == RPC_X_NULL_REF_POINTER),
766         "returned %d with %d (expected '!=0' or '0' with " \
767         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
768  
769  
770     /* with a valid buffer, but level is too large */
771     buffer[0] = '\0';
772     SetLastError(MAGIC_DEAD);
773     res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
774
775     /* Level not checked in win9x and wine:*/
776     if((res != FALSE) && buffer[0])
777     {
778         trace("Level '2' not checked '%s'\n", buffer);
779     }
780     else
781     {
782         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
783         "returned %d with lasterror=%d (expected '0' with " \
784         "ERROR_INVALID_LEVEL)\n", res, GetLastError());
785     }
786
787     /* printing environments are case insensitive */
788     /* "Windows 4.0" is valid for win9x and NT */
789     buffer[0] = '\0';
790     SetLastError(MAGIC_DEAD);
791     res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
792                                         buffer, cbBuf*2, &pcbNeeded);
793
794     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
795         cbBuf = pcbNeeded;
796         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
797         if (buffer == NULL)  return ;
798
799         SetLastError(MAGIC_DEAD);
800         res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
801                                         buffer, cbBuf*2, &pcbNeeded);
802     }
803
804     ok(res && buffer[0], "returned %d with " \
805         "lasterror=%d and len=%d (expected '1' with 'len > 0')\n", 
806         res, GetLastError(), lstrlenA((char *)buffer));
807
808     buffer[0] = '\0';
809     SetLastError(MAGIC_DEAD);
810     res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
811                                         buffer, cbBuf*2, &pcbNeeded);
812
813     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
814         cbBuf = pcbNeeded;
815         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
816         if (buffer == NULL)  return ;
817
818         buffer[0] = '\0';
819         SetLastError(MAGIC_DEAD);
820         res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
821                                         buffer, cbBuf*2, &pcbNeeded);
822     }
823
824     /* "Windows NT x86" is invalid for win9x */
825     ok( (res && buffer[0]) ||
826         (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 
827         "returned %d with lasterror=%d and len=%d (expected '!= 0' with " \
828         "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
829         res, GetLastError(), lstrlenA((char *)buffer));
830
831     /* A Setup-Programm (PDFCreator_0.8.0) use empty strings */
832     SetLastError(MAGIC_DEAD);
833     res = GetPrinterDriverDirectoryA(empty, empty, 1, buffer, cbBuf*2, &pcbNeeded);
834     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
835
836     SetLastError(MAGIC_DEAD);
837     res = GetPrinterDriverDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
838     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
839
840     SetLastError(MAGIC_DEAD);
841     res = GetPrinterDriverDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
842     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
843
844     HeapFree( GetProcessHeap(), 0, buffer);
845 }
846
847 /* ##### */
848
849 static void test_GetPrintProcessorDirectory(void)
850 {
851     LPBYTE      buffer = NULL;
852     DWORD       cbBuf = 0;
853     DWORD       pcbNeeded = 0;
854     BOOL        res;
855
856
857     SetLastError(0xdeadbeef);
858     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf);
859     /* The deactivated Spooler is catched here on NT3.51 */
860     RETURN_ON_DEACTIVATED_SPOOLER(res)
861     ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
862         "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
863         res, GetLastError());
864
865     buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2);
866     if(buffer == NULL)  return;
867
868     buffer[0] = '\0';
869     SetLastError(0xdeadbeef);
870     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
871     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
872
873     SetLastError(0xdeadbeef);
874     buffer[0] = '\0';
875     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
876     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
877  
878     /* Buffer to small */
879     buffer[0] = '\0';
880     SetLastError(0xdeadbeef);
881     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
882     ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
883         "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
884         res, GetLastError());
885
886 #if 0
887     /* XPsp2: the programm will crash here, when the spooler is not running  */
888     /*        GetPrinterDriverDirectory has the same bug */
889     pcbNeeded = 0;
890     SetLastError(0xdeadbeef);
891     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
892 #endif
893
894     buffer[0] = '\0';
895     SetLastError(0xdeadbeef);
896     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
897     /* NT: RPC_X_NULL_REF_POINTER, 9x: res != 0  */
898     ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER),
899         "returned %d with %d (expected '!= 0' or '0' with " \
900         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
901
902
903     buffer[0] = '\0';
904     SetLastError(0xdeadbeef);
905     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
906     /* NT: RPC_X_NULL_REF_POINTER, 9x: res != 0  */
907     ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER),
908         "returned %d with %d (expected '!= 0' or '0' with " \
909         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
910
911  
912     /* with a valid buffer, but level is invalid */
913     buffer[0] = '\0';
914     SetLastError(0xdeadbeef);
915     res = GetPrintProcessorDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
916     if (res && buffer[0])
917     {
918         /* Level is ignored in win9x*/
919         trace("invalid level (2) was ignored\n");
920     }
921     else
922     {
923         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
924             "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
925             res, GetLastError());
926     }
927
928     /* Empty environment is the same as the default environment */
929     buffer[0] = '\0';
930     SetLastError(0xdeadbeef);
931     res = GetPrintProcessorDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
932     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
933
934     /* "Windows 4.0" is valid for win9x and NT */
935     buffer[0] = '\0';
936     SetLastError(0xdeadbeef);
937     res = GetPrintProcessorDirectoryA(NULL, env_win9x_case, 1, buffer, cbBuf*2, &pcbNeeded);
938     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
939
940
941     /* "Windows NT x86" is invalid for win9x */
942     buffer[0] = '\0';
943     SetLastError(0xdeadbeef);
944     res = GetPrintProcessorDirectoryA(NULL, env_x86, 1, buffer, cbBuf*2, &pcbNeeded);
945     ok( res || (GetLastError() == ERROR_INVALID_ENVIRONMENT), 
946         "returned %d with %d (expected '!= 0' or '0' with " \
947         "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
948
949     /* invalid on all Systems */
950     buffer[0] = '\0';
951     SetLastError(0xdeadbeef);
952     res = GetPrintProcessorDirectoryA(NULL, invalid_env, 1, buffer, cbBuf*2, &pcbNeeded);
953     ok( !res && (GetLastError() == ERROR_INVALID_ENVIRONMENT), 
954         "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
955         res, GetLastError());
956
957     /* Empty servername is the same as the local computer */
958     buffer[0] = '\0';
959     SetLastError(0xdeadbeef);
960     res = GetPrintProcessorDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
961     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
962
963     /* invalid on all Systems */
964     buffer[0] = '\0';
965     SetLastError(0xdeadbeef);
966     res = GetPrintProcessorDirectoryA(invalid_server, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
967     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 
968         "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
969         res, GetLastError());
970
971     HeapFree(GetProcessHeap(), 0, buffer);
972 }
973
974 /* ##### */
975
976 static void test_OpenPrinter(void)
977 {
978     PRINTER_DEFAULTSA   defaults;
979     HANDLE              hprinter;
980     LPSTR               default_printer;
981     DWORD               res;
982     DWORD               size;
983     CHAR                buffer[DEFAULT_PRINTER_SIZE];
984     LPSTR               ptr;
985
986
987     SetLastError(MAGIC_DEAD);
988     res = OpenPrinter(NULL, NULL, NULL);    
989     /* The deactivated Spooler is catched here on NT3.51 */
990     RETURN_ON_DEACTIVATED_SPOOLER(res)
991     ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
992         "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
993         res, GetLastError());
994
995
996     /* Get Handle for the local Printserver (NT only)*/
997     hprinter = (HANDLE) MAGIC_DEAD;
998     SetLastError(MAGIC_DEAD);
999     res = OpenPrinter(NULL, &hprinter, NULL);
1000     /* The deactivated Spooler is catched here on XPsp2 */
1001     RETURN_ON_DEACTIVATED_SPOOLER(res)
1002     ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1003         "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1004         res, GetLastError());
1005     if(res) {
1006         ClosePrinter(hprinter);
1007
1008         defaults.pDatatype=NULL;
1009         defaults.pDevMode=NULL;
1010
1011         defaults.DesiredAccess=0;
1012         hprinter = (HANDLE) MAGIC_DEAD;
1013         SetLastError(MAGIC_DEAD);
1014         res = OpenPrinter(NULL, &hprinter, &defaults);
1015         ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1016         if (res) ClosePrinter(hprinter);
1017
1018         defaults.DesiredAccess=-1;
1019         hprinter = (HANDLE) MAGIC_DEAD;
1020         SetLastError(MAGIC_DEAD);
1021         res = OpenPrinter(NULL, &hprinter, &defaults);
1022         todo_wine {
1023         ok(!res && GetLastError() == ERROR_ACCESS_DENIED,
1024             "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n", 
1025             res, GetLastError());
1026         }
1027         if (res) ClosePrinter(hprinter);
1028
1029     }
1030
1031     size = sizeof(buffer) - 3 ;
1032     ptr = buffer;
1033     ptr[0] = '\\';
1034     ptr++;
1035     ptr[0] = '\\';
1036     ptr++;
1037     if (GetComputerNameA(ptr, &size)) {
1038
1039         hprinter = (HANDLE) MAGIC_DEAD;
1040         SetLastError(MAGIC_DEAD);
1041         res = OpenPrinter(buffer, &hprinter, NULL);
1042         todo_wine {
1043         ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1044             "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1045             res, GetLastError());
1046         }
1047         if(res) ClosePrinter(hprinter);
1048     }
1049
1050     /* Invalid Printername */
1051     hprinter = (HANDLE) MAGIC_DEAD;
1052     SetLastError(MAGIC_DEAD);
1053     res = OpenPrinter(illegal_name, &hprinter, NULL);
1054     ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
1055                 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1056        "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or" \
1057        "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1058     if(res) ClosePrinter(hprinter);
1059
1060     hprinter = (HANDLE) MAGIC_DEAD;
1061     SetLastError(MAGIC_DEAD);
1062     res = OpenPrinter(empty, &hprinter, NULL);
1063     /* NT: ERROR_INVALID_PRINTER_NAME,  9x: ERROR_INVALID_PARAMETER */
1064     ok( !res &&
1065         ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
1066         (GetLastError() == ERROR_INVALID_PARAMETER) ),
1067         "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME" \
1068         " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1069     if(res) ClosePrinter(hprinter);
1070
1071
1072     /* Get Handle for the default Printer */
1073     if ((default_printer = find_default_printer()))
1074     {
1075         hprinter = (HANDLE) MAGIC_DEAD;
1076         SetLastError(MAGIC_DEAD);
1077         res = OpenPrinter(default_printer, &hprinter, NULL);
1078         if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
1079         {
1080             trace("The Service 'Spooler' is required for '%s'\n", default_printer);
1081             return;
1082         }
1083         ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1084         if(res) ClosePrinter(hprinter);
1085
1086         SetLastError(MAGIC_DEAD);
1087         res = OpenPrinter(default_printer, NULL, NULL);
1088         /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1089         ok(res || (GetLastError() == ERROR_INVALID_PARAMETER),
1090             "returned %d with %d (expected '!=0' or '0' with " \
1091             "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1092
1093         defaults.pDatatype=NULL;
1094         defaults.pDevMode=NULL;
1095         defaults.DesiredAccess=0;
1096
1097         hprinter = (HANDLE) MAGIC_DEAD;
1098         SetLastError(MAGIC_DEAD);
1099         res = OpenPrinter(default_printer, &hprinter, &defaults);
1100         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1101             "returned %d with %d (expected '!=0' or '0' with " \
1102             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1103         if(res) ClosePrinter(hprinter);
1104
1105         defaults.pDatatype = empty;
1106
1107         hprinter = (HANDLE) MAGIC_DEAD;
1108         SetLastError(MAGIC_DEAD);
1109         res = OpenPrinter(default_printer, &hprinter, &defaults);
1110         /* stop here, when a remote Printserver has no RPC-Service running */
1111         RETURN_ON_DEACTIVATED_SPOOLER(res)
1112         ok(res || ((GetLastError() == ERROR_INVALID_DATATYPE) ||
1113                    (GetLastError() == ERROR_ACCESS_DENIED)),
1114             "returned %d with %d (expected '!=0' or '0' with: " \
1115             "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1116             res, GetLastError());
1117         if(res) ClosePrinter(hprinter);
1118
1119
1120         defaults.pDatatype=NULL;
1121         defaults.DesiredAccess=PRINTER_ACCESS_USE;
1122
1123         hprinter = (HANDLE) MAGIC_DEAD;
1124         SetLastError(MAGIC_DEAD);
1125         res = OpenPrinter(default_printer, &hprinter, &defaults);
1126         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1127             "returned %d with %d (expected '!=0' or '0' with " \
1128             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1129         if(res) ClosePrinter(hprinter);
1130
1131
1132         defaults.DesiredAccess=PRINTER_ALL_ACCESS;
1133         hprinter = (HANDLE) MAGIC_DEAD;
1134         SetLastError(MAGIC_DEAD);
1135         res = OpenPrinter(default_printer, &hprinter, &defaults);
1136         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1137             "returned %d with %d (expected '!=0' or '0' with " \
1138             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1139         if(res) ClosePrinter(hprinter);
1140     }
1141
1142 }
1143
1144
1145 static void test_SetDefaultPrinter(void)
1146 {
1147     DWORD   res;
1148     LPSTR   default_printer;
1149     DWORD   size = DEFAULT_PRINTER_SIZE;
1150     CHAR    buffer[DEFAULT_PRINTER_SIZE];
1151     CHAR    org_value[DEFAULT_PRINTER_SIZE];
1152
1153
1154     if (!pSetDefaultPrinterA)  return;
1155         /* only supported on win2k and above */
1156
1157     default_printer = find_default_printer();
1158
1159     /* backup the original value */
1160     org_value[0] = '\0';
1161     SetLastError(MAGIC_DEAD);
1162     res = GetProfileStringA("windows", "device", NULL, org_value, size);
1163
1164     /* first part: with the default Printer */
1165     SetLastError(MAGIC_DEAD);
1166     res = pSetDefaultPrinterA("no_printer_with_this_name");
1167
1168     RETURN_ON_DEACTIVATED_SPOOLER(res)
1169     /* spooler is running or we have no spooler here*/
1170
1171     /* Not implemented in wine */
1172     if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
1173         trace("SetDefaultPrinterA() not implemented yet.\n");
1174         return;
1175     }
1176
1177     ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1178         "returned %d with %d (expected '0' with " \
1179         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1180
1181     WriteProfileStringA("windows", "device", org_value);
1182     SetLastError(MAGIC_DEAD);
1183     res = pSetDefaultPrinterA("");
1184     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1185         "returned %d with %d (expected '!=0' or '0' with " \
1186         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1187
1188     WriteProfileStringA("windows", "device", org_value);
1189     SetLastError(MAGIC_DEAD);
1190     res = pSetDefaultPrinterA(NULL);
1191     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1192         "returned %d with %d (expected '!=0' or '0' with " \
1193         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1194
1195     WriteProfileStringA("windows", "device", org_value);
1196     SetLastError(MAGIC_DEAD);
1197     res = pSetDefaultPrinterA(default_printer);
1198     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1199         "returned %d with %d (expected '!=0' or '0' with " \
1200         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1201
1202
1203     /* second part: always without a default Printer */
1204     WriteProfileStringA("windows", "device", NULL);    
1205     SetLastError(MAGIC_DEAD);
1206     res = pSetDefaultPrinterA("no_printer_with_this_name");
1207
1208     ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1209         "returned %d with %d (expected '0' with " \
1210         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1211
1212     WriteProfileStringA("windows", "device", NULL);    
1213     SetLastError(MAGIC_DEAD);
1214     res = pSetDefaultPrinterA("");
1215     /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
1216     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1217          "returned %d with %d (expected '!=0' or '0' with " \
1218          "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1219
1220     WriteProfileStringA("windows", "device", NULL);    
1221     SetLastError(MAGIC_DEAD);
1222     res = pSetDefaultPrinterA(NULL);
1223     /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
1224     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1225         "returned %d with %d (expected '!=0' or '0' with " \
1226         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1227
1228     WriteProfileStringA("windows", "device", NULL);    
1229     SetLastError(MAGIC_DEAD);
1230     res = pSetDefaultPrinterA(default_printer);
1231     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1232         "returned %d with %d (expected '!=0' or '0' with " \
1233         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1234
1235     /* restore the original value */
1236     res = pSetDefaultPrinterA(default_printer);          /* the nice way */
1237     WriteProfileStringA("windows", "device", org_value); /* the old way */
1238
1239     buffer[0] = '\0';
1240     SetLastError(MAGIC_DEAD);
1241     res = GetProfileStringA("windows", "device", NULL, buffer, size);
1242     ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value);
1243
1244 }
1245
1246 static void test_GetPrinterDriver(void)
1247 {
1248     LPSTR default_printer;
1249     HANDLE hprn;
1250     BOOL ret;
1251     BYTE *buf;
1252     INT level;
1253     DWORD needed, filled;
1254
1255     default_printer = find_default_printer();
1256     if (!default_printer)
1257     {
1258         trace("There is no default printer installed, skiping the test\n");
1259         return;
1260     }
1261
1262     hprn = 0;
1263     ret = OpenPrinter(default_printer, &hprn, NULL);
1264     if (!ret)
1265     {
1266         trace("There is no printers installed, skiping the test\n");
1267         return;
1268     }
1269     ok(hprn != 0, "wrong hprn %p\n", hprn);
1270
1271     for (level = -1; level <= 7; level++)
1272     {
1273         SetLastError(0xdeadbeef);
1274         needed = (DWORD)-1;
1275         ret = GetPrinterDriver(hprn, NULL, level, NULL, 0, &needed);
1276         ok(!ret, "level %d: GetPrinterDriver should fail\n", level);
1277         if (level >= 1 && level <= 6)
1278         {
1279             /* Not all levels are supported on all Windows-Versions */
1280             if(GetLastError() == ERROR_INVALID_LEVEL) continue;
1281             ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
1282             ok(needed > 0,"not expected needed buffer size %d\n", needed);
1283         }
1284         else
1285         {
1286             /* ERROR_OUTOFMEMORY found on win9x */
1287             ok( ((GetLastError() == ERROR_INVALID_LEVEL) ||
1288                  (GetLastError() == ERROR_OUTOFMEMORY)),
1289                 "%d: returned %d with %d (expected '0' with: " \
1290                 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
1291                 level, ret, GetLastError());
1292             /* needed is modified in win9x. The modified Value depends on the
1293                default Printer. testing for "needed == (DWORD)-1" will fail */
1294             continue;
1295         }
1296
1297         buf = HeapAlloc(GetProcessHeap(), 0, needed);
1298
1299         SetLastError(0xdeadbeef);
1300         filled = -1;
1301         ret = GetPrinterDriver(hprn, NULL, level, buf, needed, &filled);
1302         ok(ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
1303         ok(needed == filled, "needed %d != filled %d\n", needed, filled);
1304
1305         if (level == 2)
1306         {
1307             DRIVER_INFO_2 *di_2 = (DRIVER_INFO_2 *)buf;
1308             DWORD calculated = sizeof(*di_2);
1309
1310             /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
1311                NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k and above(Usermode): 3  */
1312             ok((di_2->cVersion >= 0 && di_2->cVersion <= 3) ||
1313                 (di_2->cVersion == 0x0400), "di_2->cVersion = %d\n", di_2->cVersion);
1314             ok(di_2->pName != NULL, "not expected NULL ptr\n");
1315             ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n");
1316             ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n");
1317             ok(di_2->pDataFile != NULL, "not expected NULL ptr\n");
1318             ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n");
1319
1320             trace("cVersion %d\n", di_2->cVersion);
1321             trace("pName %s\n", di_2->pName);
1322             calculated += strlen(di_2->pName) + 1;
1323             trace("pEnvironment %s\n", di_2->pEnvironment);
1324             calculated += strlen(di_2->pEnvironment) + 1;
1325             trace("pDriverPath %s\n", di_2->pDriverPath);
1326             calculated += strlen(di_2->pDriverPath) + 1;
1327             trace("pDataFile %s\n", di_2->pDataFile);
1328             calculated += strlen(di_2->pDataFile) + 1;
1329             trace("pConfigFile %s\n", di_2->pConfigFile);
1330             calculated += strlen(di_2->pConfigFile) + 1;
1331
1332             /* XP allocates memory for both ANSI and unicode names */
1333             ok(filled >= calculated,"calculated %d != filled %d\n", calculated, filled);
1334         }
1335
1336         HeapFree(GetProcessHeap(), 0, buf);
1337     }
1338
1339     SetLastError(0xdeadbeef);
1340     ret = ClosePrinter(hprn);
1341     ok(ret, "ClosePrinter error %d\n", GetLastError());
1342 }
1343
1344 static void test_DEVMODE(const DEVMODE *dm, LONG dmSize, LPCSTR exp_prn_name)
1345 {
1346     /* On NT3.51, some fields in DEVMODE are empty/zero
1347       (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
1348        We skip the Tests on this Platform */
1349     if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) {
1350     /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
1351         ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1),
1352             "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName);
1353         ok(dm->dmSize + dm->dmDriverExtra == dmSize,
1354             "%u != %d\n", dm->dmSize + dm->dmDriverExtra, dmSize);
1355     }
1356     trace("dmFields %08x\n", dm->dmFields);
1357 }
1358
1359 static void test_DocumentProperties(void)
1360 {
1361     LPSTR default_printer;
1362     HANDLE hprn;
1363     LONG dm_size, ret;
1364     DEVMODE *dm;
1365
1366     default_printer = find_default_printer();
1367     if (!default_printer)
1368     {
1369         trace("There is no default printer installed, skiping the test\n");
1370         return;
1371     }
1372
1373     hprn = 0;
1374     ret = OpenPrinter(default_printer, &hprn, NULL);
1375     if (!ret)
1376     {
1377         trace("There is no printers installed, skiping the test\n");
1378         return;
1379     }
1380     ok(hprn != 0, "wrong hprn %p\n", hprn);
1381
1382     dm_size = DocumentProperties(0, hprn, NULL, NULL, NULL, 0);
1383     trace("DEVMODE required size %d\n", dm_size);
1384     ok(dm_size >= sizeof(DEVMODE), "unexpected DocumentProperties ret value %d\n", dm_size);
1385
1386     dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
1387
1388     ret = DocumentProperties(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
1389     ok(ret == IDOK, "DocumentProperties ret value %d != expected IDOK\n", ret);
1390
1391     test_DEVMODE(dm, dm_size, default_printer);
1392
1393     HeapFree(GetProcessHeap(), 0, dm);
1394
1395     SetLastError(0xdeadbeef);
1396     ret = ClosePrinter(hprn);
1397     ok(ret, "ClosePrinter error %d\n", GetLastError());
1398 }
1399
1400 START_TEST(info)
1401 {
1402     LPSTR   default_printer;
1403
1404     hwinspool = GetModuleHandleA("winspool.drv");
1405     pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
1406     pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
1407
1408     default_printer = find_default_printer();
1409
1410     test_AddMonitor();
1411     test_DeleteMonitor();
1412     test_DocumentProperties();
1413     test_EnumForms(NULL);
1414     if (default_printer) test_EnumForms(default_printer);
1415     test_EnumMonitors(); 
1416     test_GetDefaultPrinter();
1417     test_GetPrinterDriverDirectory();
1418     test_GetPrintProcessorDirectory();
1419     test_OpenPrinter();
1420     test_GetPrinterDriver();
1421     test_SetDefaultPrinter();
1422 }