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