dnsapi: Cast-qual warnings fix.
[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     CHAR  dllname[32];
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     ok( !res &&
288         ((GetLastError() == ERROR_PROC_NOT_FOUND) ||
289         (GetLastError() == ERROR_INVALID_PARAMETER)),
290         "returned %ld with %ld (expected '0' with: ERROR_PROC_NOT_FOUND or " \
291         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
292     if (res) DeleteMonitorA(NULL, entry->env, winetest_monitor); 
293
294    /* Test AddMonitor with real options */
295     mi2a.pDLLName = entry->dllname;
296     SetLastError(MAGIC_DEAD);
297     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
298     ok(res, "returned %ld with %ld (expected '!= 0')\n", res, GetLastError());
299
300     /* add a monitor twice */
301     SetLastError(MAGIC_DEAD);
302     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
303     /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */
304     ok( !res &&
305         ((GetLastError() == ERROR_PRINT_MONITOR_ALREADY_INSTALLED) ||
306         (GetLastError() == ERROR_ALREADY_EXISTS)), 
307         "returned %ld with %ld (expected '0' with: " \
308         "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n",
309         res, GetLastError());
310
311     DeleteMonitorA(NULL, entry->env, winetest_monitor); 
312     SetLastError(MAGIC_DEAD);
313     res = AddMonitorA(empty, 2, (LPBYTE) &mi2a);
314     ok(res, "returned %ld with %ld (expected '!= 0')\n", res, GetLastError());
315
316     /* cleanup */
317     DeleteMonitorA(NULL, entry->env, winetest_monitor);
318
319 }
320
321 /* ########################### */
322
323 static void test_DeleteMonitor(void)
324 {
325     MONITOR_INFO_2A         mi2a;
326     struct monitor_entry  * entry = NULL;
327     DWORD                   res;
328     static CHAR             empty[]   = "",
329                             bad_env[] = "bad_env";
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, empty, 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, empty);
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(empty, 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     static CHAR empty[] = "";
704
705     SetLastError(MAGIC_DEAD);
706     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
707     trace("first call returned 0x%04x, with %ld: buffer size 0x%08lx\n",
708     res, GetLastError(), cbBuf);
709
710     RETURN_ON_DEACTIVATED_SPOOLER(res)
711     ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
712         "returned %d with lasterror=%ld (expected '0' with " \
713         "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
714
715     if (!cbBuf) {
716         trace("no valid buffer size returned, skipping tests\n");
717         return;
718     }
719
720     buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
721     if (buffer == NULL)  return ;
722
723     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
724     ok( res, "expected result != 0, got %d\n", res);
725     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
726                             pcbNeeded, cbBuf);
727
728     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
729     ok( res, "expected result != 0, got %d\n", res);
730     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
731                             pcbNeeded, cbBuf);
732  
733     SetLastError(MAGIC_DEAD);
734     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
735     ok( !res , "expected result == 0, got %d\n", res);
736     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
737                             pcbNeeded, cbBuf);
738     
739     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
740         "last error set to %ld instead of ERROR_INSUFFICIENT_BUFFER\n",
741         GetLastError());
742
743 /*
744     Do not add the next test:
745     XPsp2: crash in this app, when the spooler is not running 
746     NT3.5: ERROR_INVALID_USER_BUFFER
747     win9x: ERROR_INVALID_PARAMETER
748
749     pcbNeeded = MAGIC_DEAD;
750     SetLastError(MAGIC_DEAD);
751     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
752 */
753
754     SetLastError(MAGIC_DEAD);
755     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
756     ok( (!res && RPC_X_NULL_REF_POINTER == GetLastError()) || res,
757          "expected either result == 0 and "
758          "last error == RPC_X_NULL_REF_POINTER or result != 0 "
759          "got result %d and last error == %ld\n", res, GetLastError());
760
761     SetLastError(MAGIC_DEAD);
762     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
763     ok(res || (GetLastError() == RPC_X_NULL_REF_POINTER),
764         "returned %d with %ld (expected '!=0' or '0' with " \
765         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
766  
767  
768     /* with a valid buffer, but level is too large */
769     buffer[0] = '\0';
770     SetLastError(MAGIC_DEAD);
771     res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
772
773     /* Level not checked in win9x and wine:*/
774     if((res != FALSE) && buffer[0])
775     {
776         trace("Level '2' not checked '%s'\n", buffer);
777     }
778     else
779     {
780         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
781         "returned %d with lasterror=%ld (expected '0' with " \
782         "ERROR_INVALID_LEVEL)\n", res, GetLastError());
783     }
784
785     /* printing environments are case insensitive */
786     /* "Windows 4.0" is valid for win9x and NT */
787     buffer[0] = '\0';
788     SetLastError(MAGIC_DEAD);
789     res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
790                                         buffer, cbBuf*2, &pcbNeeded);
791
792     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
793         cbBuf = pcbNeeded;
794         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
795         if (buffer == NULL)  return ;
796
797         SetLastError(MAGIC_DEAD);
798         res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
799                                         buffer, cbBuf*2, &pcbNeeded);
800     }
801
802     ok(res && buffer[0], "returned %d with " \
803         "lasterror=%ld and len=%d (expected '1' with 'len > 0')\n", 
804         res, GetLastError(), lstrlenA((char *)buffer));
805
806     buffer[0] = '\0';
807     SetLastError(MAGIC_DEAD);
808     res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
809                                         buffer, cbBuf*2, &pcbNeeded);
810
811     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
812         cbBuf = pcbNeeded;
813         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
814         if (buffer == NULL)  return ;
815
816         buffer[0] = '\0';
817         SetLastError(MAGIC_DEAD);
818         res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
819                                         buffer, cbBuf*2, &pcbNeeded);
820     }
821
822     /* "Windows NT x86" is invalid for win9x */
823     ok( (res && buffer[0]) ||
824         (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 
825         "returned %d with lasterror=%ld and len=%d (expected '!= 0' with " \
826         "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
827         res, GetLastError(), lstrlenA((char *)buffer));
828
829     /* A Setup-Programm (PDFCreator_0.8.0) use empty strings */
830     SetLastError(MAGIC_DEAD);
831     res = GetPrinterDriverDirectoryA(empty, empty, 1, buffer, cbBuf*2, &pcbNeeded);
832     ok(res, "returned %d with %ld (expected '!=0')\n", res, GetLastError() );
833
834     SetLastError(MAGIC_DEAD);
835     res = GetPrinterDriverDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
836     ok(res, "returned %d with %ld (expected '!=0')\n", res, GetLastError() );
837
838     SetLastError(MAGIC_DEAD);
839     res = GetPrinterDriverDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
840     ok(res, "returned %d with %ld (expected '!=0')\n", res, GetLastError() );
841
842     HeapFree( GetProcessHeap(), 0, buffer);
843 }
844
845 /* ##### */
846
847 static void test_GetPrintProcessorDirectory(void)
848 {
849     LPBYTE      buffer = NULL;
850     DWORD       cbBuf = 0;
851     DWORD       pcbNeeded = 0;
852     BOOL        res;
853     static CHAR empty[]          = "",
854                 invalid_env[]    = "invalid_env",
855                 invalid_server[] = "\\invalid_server";
856
857     SetLastError(0xdeadbeef);
858     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf);
859     /* The deactivated Spooler is catched here on NT3.51 */
860     RETURN_ON_DEACTIVATED_SPOOLER(res)
861     ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
862         "returned %d with %ld (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
863         res, GetLastError());
864
865     buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2);
866     if(buffer == NULL)  return;
867
868     buffer[0] = '\0';
869     SetLastError(0xdeadbeef);
870     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
871     ok(res, "returned %d with %ld (expected '!= 0')\n", res, GetLastError());
872
873     SetLastError(0xdeadbeef);
874     buffer[0] = '\0';
875     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
876     ok(res, "returned %d with %ld (expected '!= 0')\n", res, GetLastError());
877  
878     /* Buffer to small */
879     buffer[0] = '\0';
880     SetLastError(0xdeadbeef);
881     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
882     ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
883         "returned %d with %ld (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
884         res, GetLastError());
885
886 #if 0
887     /* XPsp2: the programm will crash here, when the spooler is not running  */
888     /*        GetPrinterDriverDirectory has the same bug */
889     pcbNeeded = 0;
890     SetLastError(0xdeadbeef);
891     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
892 #endif
893
894     buffer[0] = '\0';
895     SetLastError(0xdeadbeef);
896     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
897     /* NT: RPC_X_NULL_REF_POINTER, 9x: res != 0  */
898     ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER),
899         "returned %d with %ld (expected '!= 0' or '0' with " \
900         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
901
902
903     buffer[0] = '\0';
904     SetLastError(0xdeadbeef);
905     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
906     /* NT: RPC_X_NULL_REF_POINTER, 9x: res != 0  */
907     ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER),
908         "returned %d with %ld (expected '!= 0' or '0' with " \
909         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
910
911  
912     /* with a valid buffer, but level is invalid */
913     buffer[0] = '\0';
914     SetLastError(0xdeadbeef);
915     res = GetPrintProcessorDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
916     if (res && buffer[0])
917     {
918         /* Level is ignored in win9x*/
919         trace("invalid level (2) was ignored\n");
920     }
921     else
922     {
923         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
924             "returned %d with %ld (expected '0' with ERROR_INVALID_LEVEL)\n",
925             res, GetLastError());
926     }
927
928     /* Empty environment is the same as the default environment */
929     buffer[0] = '\0';
930     SetLastError(0xdeadbeef);
931     res = GetPrintProcessorDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
932     ok(res, "returned %d with %ld (expected '!= 0')\n", res, GetLastError());
933
934     /* "Windows 4.0" is valid for win9x and NT */
935     buffer[0] = '\0';
936     SetLastError(0xdeadbeef);
937     res = GetPrintProcessorDirectoryA(NULL, env_win9x_case, 1, buffer, cbBuf*2, &pcbNeeded);
938     ok(res, "returned %d with %ld (expected '!= 0')\n", res, GetLastError());
939
940
941     /* "Windows NT x86" is invalid for win9x */
942     buffer[0] = '\0';
943     SetLastError(0xdeadbeef);
944     res = GetPrintProcessorDirectoryA(NULL, env_x86, 1, buffer, cbBuf*2, &pcbNeeded);
945     ok( res || (GetLastError() == ERROR_INVALID_ENVIRONMENT), 
946         "returned %d with %ld (expected '!= 0' or '0' with " \
947         "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
948
949     /* invalid on all Systems */
950     buffer[0] = '\0';
951     SetLastError(0xdeadbeef);
952     res = GetPrintProcessorDirectoryA(NULL, invalid_env, 1, buffer, cbBuf*2, &pcbNeeded);
953     ok( !res && (GetLastError() == ERROR_INVALID_ENVIRONMENT), 
954         "returned %d with %ld (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
955         res, GetLastError());
956
957     /* Empty servername is the same as the local computer */
958     buffer[0] = '\0';
959     SetLastError(0xdeadbeef);
960     res = GetPrintProcessorDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
961     ok(res, "returned %d with %ld (expected '!= 0')\n", res, GetLastError());
962
963     /* invalid on all Systems */
964     buffer[0] = '\0';
965     SetLastError(0xdeadbeef);
966     res = GetPrintProcessorDirectoryA(invalid_server, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
967     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 
968         "returned %d with %ld (expected '0' with ERROR_INVALID_PARAMETER)\n",
969         res, GetLastError());
970
971     HeapFree(GetProcessHeap(), 0, buffer);
972 }
973
974 /* ##### */
975
976 static void test_OpenPrinter(void)
977 {
978     PRINTER_DEFAULTSA   defaults;
979     HANDLE              hprinter;
980     LPSTR               default_printer;
981     DWORD               res;
982     DWORD               size;
983     CHAR                buffer[DEFAULT_PRINTER_SIZE];
984     LPSTR               ptr;
985     static CHAR         empty[]        = "",
986                         illegal_name[] = "illegal,name";
987
988     SetLastError(MAGIC_DEAD);
989     res = OpenPrinter(NULL, NULL, NULL);    
990     /* The deactivated Spooler is catched here on NT3.51 */
991     RETURN_ON_DEACTIVATED_SPOOLER(res)
992     ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
993         "returned %ld with %ld (expected '0' with ERROR_INVALID_PARAMETER)\n",
994         res, GetLastError());
995
996
997     /* Get Handle for the local Printserver (NT only)*/
998     hprinter = (HANDLE) MAGIC_DEAD;
999     SetLastError(MAGIC_DEAD);
1000     res = OpenPrinter(NULL, &hprinter, NULL);
1001     /* The deactivated Spooler is catched here on XPsp2 */
1002     RETURN_ON_DEACTIVATED_SPOOLER(res)
1003     ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1004         "returned %ld with %ld (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1005         res, GetLastError());
1006     if(res) {
1007         ClosePrinter(hprinter);
1008
1009         defaults.pDatatype=NULL;
1010         defaults.pDevMode=NULL;
1011
1012         defaults.DesiredAccess=0;
1013         hprinter = (HANDLE) MAGIC_DEAD;
1014         SetLastError(MAGIC_DEAD);
1015         res = OpenPrinter(NULL, &hprinter, &defaults);
1016         ok(res, "returned %ld with %ld (expected '!=0')\n", res, GetLastError());
1017         if (res) ClosePrinter(hprinter);
1018
1019         defaults.DesiredAccess=-1;
1020         hprinter = (HANDLE) MAGIC_DEAD;
1021         SetLastError(MAGIC_DEAD);
1022         res = OpenPrinter(NULL, &hprinter, &defaults);
1023         todo_wine {
1024         ok(!res && GetLastError() == ERROR_ACCESS_DENIED,
1025             "returned %ld with %ld (expected '0' with ERROR_ACCESS_DENIED)\n", 
1026             res, GetLastError());
1027         }
1028         if (res) ClosePrinter(hprinter);
1029
1030     }
1031
1032     size = sizeof(buffer) - 3 ;
1033     ptr = buffer;
1034     ptr[0] = '\\';
1035     ptr++;
1036     ptr[0] = '\\';
1037     ptr++;
1038     if (GetComputerNameA(ptr, &size)) {
1039
1040         hprinter = (HANDLE) MAGIC_DEAD;
1041         SetLastError(MAGIC_DEAD);
1042         res = OpenPrinter(buffer, &hprinter, NULL);
1043         todo_wine {
1044         ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1045             "returned %ld with %ld (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1046             res, GetLastError());
1047         }
1048         if(res) ClosePrinter(hprinter);
1049     }
1050
1051     /* Invalid Printername */
1052     hprinter = (HANDLE) MAGIC_DEAD;
1053     SetLastError(MAGIC_DEAD);
1054     res = OpenPrinter(illegal_name, &hprinter, NULL);
1055     ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
1056                 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1057        "returned %ld with %ld (expected '0' with: ERROR_INVALID_PARAMETER or" \
1058        "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1059     if(res) ClosePrinter(hprinter);
1060
1061     hprinter = (HANDLE) MAGIC_DEAD;
1062     SetLastError(MAGIC_DEAD);
1063     res = OpenPrinter(empty, &hprinter, NULL);
1064     /* NT: ERROR_INVALID_PRINTER_NAME,  9x: ERROR_INVALID_PARAMETER */
1065     ok( !res &&
1066         ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
1067         (GetLastError() == ERROR_INVALID_PARAMETER) ),
1068         "returned %ld with %ld (expected '0' with: ERROR_INVALID_PRINTER_NAME" \
1069         " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1070     if(res) ClosePrinter(hprinter);
1071
1072
1073     /* Get Handle for the default Printer */
1074     if ((default_printer = find_default_printer()))
1075     {
1076         hprinter = (HANDLE) MAGIC_DEAD;
1077         SetLastError(MAGIC_DEAD);
1078         res = OpenPrinter(default_printer, &hprinter, NULL);
1079         if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
1080         {
1081             trace("The Service 'Spooler' is required for '%s'\n", default_printer);
1082             return;
1083         }
1084         ok(res, "returned %ld with %ld (expected '!=0')\n", res, GetLastError());
1085         if(res) ClosePrinter(hprinter);
1086
1087         SetLastError(MAGIC_DEAD);
1088         res = OpenPrinter(default_printer, NULL, NULL);
1089         /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1090         ok(res || (GetLastError() == ERROR_INVALID_PARAMETER),
1091             "returned %ld with %ld (expected '!=0' or '0' with " \
1092             "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1093
1094         defaults.pDatatype=NULL;
1095         defaults.pDevMode=NULL;
1096         defaults.DesiredAccess=0;
1097
1098         hprinter = (HANDLE) MAGIC_DEAD;
1099         SetLastError(MAGIC_DEAD);
1100         res = OpenPrinter(default_printer, &hprinter, &defaults);
1101         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1102             "returned %ld with %ld (expected '!=0' or '0' with " \
1103             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1104         if(res) ClosePrinter(hprinter);
1105
1106         defaults.pDatatype = empty;
1107
1108         hprinter = (HANDLE) MAGIC_DEAD;
1109         SetLastError(MAGIC_DEAD);
1110         res = OpenPrinter(default_printer, &hprinter, &defaults);
1111         /* stop here, when a remote Printserver has no RPC-Service running */
1112         RETURN_ON_DEACTIVATED_SPOOLER(res)
1113         ok(res || ((GetLastError() == ERROR_INVALID_DATATYPE) ||
1114                    (GetLastError() == ERROR_ACCESS_DENIED)),
1115             "returned %ld with %ld (expected '!=0' or '0' with: " \
1116             "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1117             res, GetLastError());
1118         if(res) ClosePrinter(hprinter);
1119
1120
1121         defaults.pDatatype=NULL;
1122         defaults.DesiredAccess=PRINTER_ACCESS_USE;
1123
1124         hprinter = (HANDLE) MAGIC_DEAD;
1125         SetLastError(MAGIC_DEAD);
1126         res = OpenPrinter(default_printer, &hprinter, &defaults);
1127         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1128             "returned %ld with %ld (expected '!=0' or '0' with " \
1129             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1130         if(res) ClosePrinter(hprinter);
1131
1132
1133         defaults.DesiredAccess=PRINTER_ALL_ACCESS;
1134         hprinter = (HANDLE) MAGIC_DEAD;
1135         SetLastError(MAGIC_DEAD);
1136         res = OpenPrinter(default_printer, &hprinter, &defaults);
1137         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1138             "returned %ld with %ld (expected '!=0' or '0' with " \
1139             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1140         if(res) ClosePrinter(hprinter);
1141     }
1142
1143 }
1144
1145
1146 static void test_SetDefaultPrinter(void)
1147 {
1148     DWORD   res;
1149     LPSTR   default_printer;
1150     DWORD   size = DEFAULT_PRINTER_SIZE;
1151     CHAR    buffer[DEFAULT_PRINTER_SIZE];
1152     CHAR    org_value[DEFAULT_PRINTER_SIZE];
1153
1154
1155     if (!pSetDefaultPrinterA)  return;
1156         /* only supported on win2k and above */
1157
1158     default_printer = find_default_printer();
1159
1160     /* backup the original value */
1161     org_value[0] = '\0';
1162     SetLastError(MAGIC_DEAD);
1163     res = GetProfileStringA("windows", "device", NULL, org_value, size);
1164
1165     /* first part: with the default Printer */
1166     SetLastError(MAGIC_DEAD);
1167     res = pSetDefaultPrinterA("no_printer_with_this_name");
1168
1169     RETURN_ON_DEACTIVATED_SPOOLER(res)
1170     /* spooler is running or we have no spooler here*/
1171
1172     /* Not implemented in wine */
1173     if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
1174         trace("SetDefaultPrinterA() not implemented yet.\n");
1175         return;
1176     }
1177
1178     ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1179         "returned %ld with %ld (expected '0' with " \
1180         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1181
1182     WriteProfileStringA("windows", "device", org_value);
1183     SetLastError(MAGIC_DEAD);
1184     res = pSetDefaultPrinterA("");
1185     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1186         "returned %ld with %ld (expected '!=0' or '0' with " \
1187         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1188
1189     WriteProfileStringA("windows", "device", org_value);
1190     SetLastError(MAGIC_DEAD);
1191     res = pSetDefaultPrinterA(NULL);
1192     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1193         "returned %ld with %ld (expected '!=0' or '0' with " \
1194         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1195
1196     WriteProfileStringA("windows", "device", org_value);
1197     SetLastError(MAGIC_DEAD);
1198     res = pSetDefaultPrinterA(default_printer);
1199     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1200         "returned %ld with %ld (expected '!=0' or '0' with " \
1201         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1202
1203
1204     /* second part: always without a default Printer */
1205     WriteProfileStringA("windows", "device", NULL);    
1206     SetLastError(MAGIC_DEAD);
1207     res = pSetDefaultPrinterA("no_printer_with_this_name");
1208
1209     ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1210         "returned %ld with %ld (expected '0' with " \
1211         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1212
1213     WriteProfileStringA("windows", "device", NULL);    
1214     SetLastError(MAGIC_DEAD);
1215     res = pSetDefaultPrinterA("");
1216     /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
1217     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1218          "returned %ld with %ld (expected '!=0' or '0' with " \
1219          "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1220
1221     WriteProfileStringA("windows", "device", NULL);    
1222     SetLastError(MAGIC_DEAD);
1223     res = pSetDefaultPrinterA(NULL);
1224     /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
1225     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1226         "returned %ld with %ld (expected '!=0' or '0' with " \
1227         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1228
1229     WriteProfileStringA("windows", "device", NULL);    
1230     SetLastError(MAGIC_DEAD);
1231     res = pSetDefaultPrinterA(default_printer);
1232     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1233         "returned %ld with %ld (expected '!=0' or '0' with " \
1234         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1235
1236     /* restore the original value */
1237     res = pSetDefaultPrinterA(default_printer);          /* the nice way */
1238     WriteProfileStringA("windows", "device", org_value); /* the old way */
1239
1240     buffer[0] = '\0';
1241     SetLastError(MAGIC_DEAD);
1242     res = GetProfileStringA("windows", "device", NULL, buffer, size);
1243     ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value);
1244
1245 }
1246
1247 static void test_GetPrinterDriver(void)
1248 {
1249     LPSTR default_printer;
1250     HANDLE hprn;
1251     BOOL ret;
1252     BYTE *buf;
1253     INT level;
1254     DWORD needed, filled;
1255
1256     default_printer = find_default_printer();
1257     if (!default_printer)
1258     {
1259         trace("There is no default printer installed, skiping the test\n");
1260         return;
1261     }
1262
1263     hprn = 0;
1264     ret = OpenPrinter(default_printer, &hprn, NULL);
1265     if (!ret)
1266     {
1267         trace("There is no printers installed, skiping the test\n");
1268         return;
1269     }
1270     ok(hprn != 0, "wrong hprn %p\n", hprn);
1271
1272     for (level = -1; level <= 7; level++)
1273     {
1274         SetLastError(0xdeadbeef);
1275         needed = (DWORD)-1;
1276         ret = GetPrinterDriver(hprn, NULL, level, NULL, 0, &needed);
1277         ok(!ret, "level %d: GetPrinterDriver should fail\n", level);
1278         if (level >= 1 && level <= 6)
1279         {
1280             /* Not all levels are supported on all Windows-Versions */
1281             if(GetLastError() == ERROR_INVALID_LEVEL) continue;
1282             ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %ld\n", GetLastError());
1283             ok(needed > 0,"not expected needed buffer size %ld\n", needed);
1284         }
1285         else
1286         {
1287             /* ERROR_OUTOFMEMORY found on win9x */
1288             ok( ((GetLastError() == ERROR_INVALID_LEVEL) ||
1289                  (GetLastError() == ERROR_OUTOFMEMORY)),
1290                 "%d: returned %d with %ld (expected '0' with: " \
1291                 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
1292                 level, ret, GetLastError());
1293             /* needed is modified in win9x. The modified Value depends on the
1294                default Printer. testing for "needed == (DWORD)-1" will fail */
1295             continue;
1296         }
1297
1298         buf = HeapAlloc(GetProcessHeap(), 0, needed);
1299
1300         SetLastError(0xdeadbeef);
1301         filled = -1;
1302         ret = GetPrinterDriver(hprn, NULL, level, buf, needed, &filled);
1303         ok(ret, "level %d: GetPrinterDriver error %ld\n", level, GetLastError());
1304         ok(needed == filled, "needed %ld != filled %ld\n", needed, filled);
1305
1306         if (level == 2)
1307         {
1308             DRIVER_INFO_2 *di_2 = (DRIVER_INFO_2 *)buf;
1309             DWORD calculated = sizeof(*di_2);
1310
1311             /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
1312                NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k and above(Usermode): 3  */
1313             ok((di_2->cVersion >= 0 && di_2->cVersion <= 3) ||
1314                 (di_2->cVersion == 0x0400), "di_2->cVersion = %ld\n", di_2->cVersion);
1315             ok(di_2->pName != NULL, "not expected NULL ptr\n");
1316             ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n");
1317             ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n");
1318             ok(di_2->pDataFile != NULL, "not expected NULL ptr\n");
1319             ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n");
1320
1321             trace("cVersion %ld\n", di_2->cVersion);
1322             trace("pName %s\n", di_2->pName);
1323             calculated += strlen(di_2->pName) + 1;
1324             trace("pEnvironment %s\n", di_2->pEnvironment);
1325             calculated += strlen(di_2->pEnvironment) + 1;
1326             trace("pDriverPath %s\n", di_2->pDriverPath);
1327             calculated += strlen(di_2->pDriverPath) + 1;
1328             trace("pDataFile %s\n", di_2->pDataFile);
1329             calculated += strlen(di_2->pDataFile) + 1;
1330             trace("pConfigFile %s\n", di_2->pConfigFile);
1331             calculated += strlen(di_2->pConfigFile) + 1;
1332
1333             /* XP allocates memory for both ANSI and unicode names */
1334             ok(filled >= calculated,"calculated %ld != filled %ld\n", calculated, filled);
1335         }
1336
1337         HeapFree(GetProcessHeap(), 0, buf);
1338     }
1339
1340     SetLastError(0xdeadbeef);
1341     ret = ClosePrinter(hprn);
1342     ok(ret, "ClosePrinter error %ld\n", GetLastError());
1343 }
1344
1345 static void test_DEVMODE(const DEVMODE *dm, LONG dmSize, LPCSTR exp_prn_name)
1346 {
1347     /* On NT3.51, some fields in DEVMODE are empty/zero
1348       (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
1349        We skip the Tests on this Platform */
1350     if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) {
1351     /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
1352         ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1),
1353             "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName);
1354         ok(dm->dmSize + dm->dmDriverExtra == dmSize,
1355             "%u != %ld\n", dm->dmSize + dm->dmDriverExtra, dmSize);
1356     }
1357     trace("dmFields %08lx\n", dm->dmFields);
1358 }
1359
1360 static void test_DocumentProperties(void)
1361 {
1362     LPSTR default_printer;
1363     HANDLE hprn;
1364     LONG dm_size, ret;
1365     DEVMODE *dm;
1366
1367     default_printer = find_default_printer();
1368     if (!default_printer)
1369     {
1370         trace("There is no default printer installed, skiping the test\n");
1371         return;
1372     }
1373
1374     hprn = 0;
1375     ret = OpenPrinter(default_printer, &hprn, NULL);
1376     if (!ret)
1377     {
1378         trace("There is no printers installed, skiping the test\n");
1379         return;
1380     }
1381     ok(hprn != 0, "wrong hprn %p\n", hprn);
1382
1383     dm_size = DocumentProperties(0, hprn, NULL, NULL, NULL, 0);
1384     trace("DEVMODE required size %ld\n", dm_size);
1385     ok(dm_size >= sizeof(DEVMODE), "unexpected DocumentProperties ret value %ld\n", dm_size);
1386
1387     dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
1388
1389     ret = DocumentProperties(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
1390     ok(ret == IDOK, "DocumentProperties ret value %ld != expected IDOK\n", ret);
1391
1392     test_DEVMODE(dm, dm_size, default_printer);
1393
1394     HeapFree(GetProcessHeap(), 0, dm);
1395
1396     SetLastError(0xdeadbeef);
1397     ret = ClosePrinter(hprn);
1398     ok(ret, "ClosePrinter error %ld\n", GetLastError());
1399 }
1400
1401 START_TEST(info)
1402 {
1403     LPSTR   default_printer;
1404
1405     hwinspool = GetModuleHandleA("winspool.drv");
1406     pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
1407     pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
1408
1409     default_printer = find_default_printer();
1410
1411     test_AddMonitor();
1412     test_DeleteMonitor();
1413     test_DocumentProperties();
1414     test_EnumForms(NULL);
1415     if (default_printer) test_EnumForms(default_printer);
1416     test_EnumMonitors(); 
1417     test_GetDefaultPrinter();
1418     test_GetPrinterDriverDirectory();
1419     test_GetPrintProcessorDirectory();
1420     test_OpenPrinter();
1421     test_GetPrinterDriver();
1422     test_SetDefaultPrinter();
1423 }