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