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