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