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