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