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