mshtml: Added beginning OnDataAvailable implementation.
[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
406 static void test_EnumMonitors(void)
407 {
408     DWORD   res;
409     LPBYTE  buffer;
410     DWORD   cbBuf;
411     DWORD   pcbNeeded;
412     DWORD   pcReturned;
413     DWORD   level;
414
415     /* valid levels are 1 and 2 */
416     for(level = 0; level < 4; level++) {
417         cbBuf = MAGIC_DEAD;
418         pcReturned = MAGIC_DEAD;
419         SetLastError(MAGIC_DEAD);
420         res = EnumMonitorsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
421
422         RETURN_ON_DEACTIVATED_SPOOLER(res)
423
424         /* not implemented yet in wine */
425         if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
426
427
428         /* use only a short test, when we test with an invalid level */
429         if(!level || (level > 2)) {
430             ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
431                 (res && (pcReturned == 0)),
432                 "(%ld) returned %ld with %ld and 0x%08lx (expected '0' with " \
433                 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
434                 level, res, GetLastError(), pcReturned);
435             continue;
436         }        
437
438         /* Level 2 is not supported on win9x */
439         if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
440             trace("Level %ld not supported, skipping tests\n", level);
441             continue;
442         }
443
444         ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
445             "(%ld) returned %ld with %ld (expected '0' with " \
446             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
447
448         if (!cbBuf) {
449             trace("no valid buffer size returned, skipping tests\n");
450             continue;
451         }
452
453         buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
454         if (buffer == NULL) continue;
455
456         SetLastError(MAGIC_DEAD);
457         pcbNeeded = MAGIC_DEAD;
458         res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
459         ok(res, "(%ld) returned %ld with %ld (expected '!=0')\n",
460                 level, res, GetLastError());
461         ok(pcbNeeded == cbBuf, "(%ld) returned %ld (expected %ld)\n",
462                 level, pcbNeeded, cbBuf);
463         /* We can validate the returned Data with the Registry here */
464
465
466         SetLastError(MAGIC_DEAD);
467         pcReturned = MAGIC_DEAD;
468         pcbNeeded = MAGIC_DEAD;
469         res = EnumMonitorsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
470         ok(res, "(%ld) returned %ld with %ld (expected '!=0')\n", level,
471                 res, GetLastError());
472         ok(pcbNeeded == cbBuf, "(%ld) returned %ld (expected %ld)\n", level,
473                 pcbNeeded, cbBuf);
474
475         SetLastError(MAGIC_DEAD);
476         pcbNeeded = MAGIC_DEAD;
477         res = EnumMonitorsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
478         ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
479             "(%ld) returned %ld with %ld (expected '0' with " \
480             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
481
482         ok(pcbNeeded == cbBuf, "(%ld) returned %ld (expected %ld)\n", level,
483                 pcbNeeded, cbBuf);
484
485 /*
486       Do not add the next test:
487       w2k+:  RPC_X_NULL_REF_POINTER 
488       NT3.5: ERROR_INVALID_USER_BUFFER
489       win9x: crash in winspool.drv
490
491       res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
492 */
493
494         SetLastError(MAGIC_DEAD);
495         pcbNeeded = MAGIC_DEAD;
496         pcReturned = MAGIC_DEAD;
497         res = EnumMonitorsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
498         ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
499             "(%ld) returned %ld with %ld (expected '!=0' or '0' with "\
500             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
501
502         pcbNeeded = MAGIC_DEAD;
503         pcReturned = MAGIC_DEAD;
504         SetLastError(MAGIC_DEAD);
505         res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
506         ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
507             "(%ld) returned %ld with %ld (expected '!=0' or '0' with "\
508             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
509
510         HeapFree(GetProcessHeap(), 0, buffer);
511     } /* for(level ... */
512 }
513
514
515 static void test_GetDefaultPrinter(void)
516 {
517     BOOL    retval;
518     DWORD   exact = DEFAULT_PRINTER_SIZE;
519     DWORD   size;
520     char    buffer[DEFAULT_PRINTER_SIZE];
521
522     if (!pGetDefaultPrinterA)  return;
523         /* only supported on NT like OSes starting with win2k */
524
525     SetLastError(ERROR_SUCCESS);
526     retval = pGetDefaultPrinterA(buffer, &exact);
527     if (!retval || !exact || !strlen(buffer) ||
528         (ERROR_SUCCESS != GetLastError())) {
529         if ((ERROR_FILE_NOT_FOUND == GetLastError()) ||
530             (ERROR_INVALID_NAME == GetLastError()))
531             trace("this test requires a default printer to be set\n");
532         else {
533                 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
534                 "function returned %s\n"
535                 "last error 0x%08lx\n"
536                 "returned buffer size 0x%08lx\n"
537                 "returned buffer content %s\n",
538                 retval ? "true" : "false", GetLastError(), exact, buffer);
539         }
540         return;
541     }
542     SetLastError(ERROR_SUCCESS);
543     retval = pGetDefaultPrinterA(NULL, NULL); 
544     ok( !retval, "function result wrong! False expected\n");
545     ok( ERROR_INVALID_PARAMETER == GetLastError(),
546         "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08lx\n",
547         GetLastError());
548
549     SetLastError(ERROR_SUCCESS);
550     retval = pGetDefaultPrinterA(buffer, NULL); 
551     ok( !retval, "function result wrong! False expected\n");
552     ok( ERROR_INVALID_PARAMETER == GetLastError(),
553         "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08lx\n",
554         GetLastError());
555
556     SetLastError(ERROR_SUCCESS);
557     size = 0;
558     retval = pGetDefaultPrinterA(NULL, &size); 
559     ok( !retval, "function result wrong! False expected\n");
560     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
561         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
562         GetLastError());
563     ok( size == exact, "Parameter size wrong! %ld expected got %ld\n",
564         exact, size);
565
566     SetLastError(ERROR_SUCCESS);
567     size = DEFAULT_PRINTER_SIZE;
568     retval = pGetDefaultPrinterA(NULL, &size); 
569     ok( !retval, "function result wrong! False expected\n");
570     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
571         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
572         GetLastError());
573     ok( size == exact, "Parameter size wrong! %ld expected got %ld\n",
574         exact, size);
575
576     size = 0;
577     retval = pGetDefaultPrinterA(buffer, &size); 
578     ok( !retval, "function result wrong! False expected\n");
579     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
580         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
581         GetLastError());
582     ok( size == exact, "Parameter size wrong! %ld expected got %ld\n",
583         exact, size);
584
585     size = exact;
586     retval = pGetDefaultPrinterA(buffer, &size); 
587     ok( retval, "function result wrong! True expected\n");
588     ok( size == exact, "Parameter size wrong! %ld expected got %ld\n",
589         exact, size);
590 }
591
592 static void test_GetPrinterDriverDirectory(void)
593 {
594     LPBYTE buffer = NULL;
595     DWORD  cbBuf = 0, pcbNeeded = 0;
596     BOOL   res;
597
598     SetLastError(MAGIC_DEAD);
599     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
600     trace("first call returned 0x%04x, with %ld: buffer size 0x%08lx\n",
601     res, GetLastError(), cbBuf);
602
603     RETURN_ON_DEACTIVATED_SPOOLER(res)
604     ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
605         "returned %d with lasterror=%ld (expected '0' with " \
606         "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
607
608     if (!cbBuf) {
609         trace("no valid buffer size returned, skipping tests\n");
610         return;
611     }
612
613     buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
614     if (buffer == NULL)  return ;
615
616     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
617     ok( res, "expected result != 0, got %d\n", res);
618     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
619                             pcbNeeded, cbBuf);
620
621     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
622     ok( res, "expected result != 0, got %d\n", res);
623     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
624                             pcbNeeded, cbBuf);
625  
626     SetLastError(MAGIC_DEAD);
627     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
628     ok( !res , "expected result == 0, got %d\n", res);
629     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
630                             pcbNeeded, cbBuf);
631     
632     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
633         "last error set to %ld instead of ERROR_INSUFFICIENT_BUFFER\n",
634         GetLastError());
635
636 /*
637     Do not add the next test:
638     XPsp2: crash in this app, when the spooler is not running 
639     NT3.5: ERROR_INVALID_USER_BUFFER
640     win9x: ERROR_INVALID_PARAMETER
641
642     pcbNeeded = MAGIC_DEAD;
643     SetLastError(MAGIC_DEAD);
644     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
645 */
646
647     SetLastError(MAGIC_DEAD);
648     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
649     ok( (!res && RPC_X_NULL_REF_POINTER == GetLastError()) || res,
650          "expected either result == 0 and "
651          "last error == RPC_X_NULL_REF_POINTER or result != 0 "
652          "got result %d and last error == %ld\n", res, GetLastError());
653
654     SetLastError(MAGIC_DEAD);
655     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
656     ok(res || (GetLastError() == RPC_X_NULL_REF_POINTER),
657         "returned %d with %ld (expected '!=0' or '0' with " \
658         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
659  
660  
661     /* with a valid buffer, but level is too large */
662     buffer[0] = '\0';
663     SetLastError(MAGIC_DEAD);
664     res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
665
666     /* Level not checked in win9x and wine:*/
667     if((res != FALSE) && buffer[0])
668     {
669         trace("Level '2' not checked '%s'\n", buffer);
670     }
671     else
672     {
673         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
674         "returned %d with lasterror=%ld (expected '0' with " \
675         "ERROR_INVALID_LEVEL)\n", res, GetLastError());
676     }
677
678     /* printing environments are case insensitive */
679     /* "Windows 4.0" is valid for win9x and NT */
680     buffer[0] = '\0';
681     SetLastError(MAGIC_DEAD);
682     res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
683                                         buffer, cbBuf*2, &pcbNeeded);
684
685     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
686         cbBuf = pcbNeeded;
687         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
688         if (buffer == NULL)  return ;
689
690         SetLastError(MAGIC_DEAD);
691         res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
692                                         buffer, cbBuf*2, &pcbNeeded);
693     }
694
695     ok(res && buffer[0], "returned %d with " \
696         "lasterror=%ld and len=%d (expected '1' with 'len > 0')\n", 
697         res, GetLastError(), lstrlenA((char *)buffer));
698
699     buffer[0] = '\0';
700     SetLastError(MAGIC_DEAD);
701     res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
702                                         buffer, cbBuf*2, &pcbNeeded);
703
704     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
705         cbBuf = pcbNeeded;
706         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
707         if (buffer == NULL)  return ;
708
709         buffer[0] = '\0';
710         SetLastError(MAGIC_DEAD);
711         res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
712                                         buffer, cbBuf*2, &pcbNeeded);
713     }
714
715     /* "Windows NT x86" is invalid for win9x */
716     ok( (res && buffer[0]) ||
717         (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 
718         "returned %d with lasterror=%ld and len=%d (expected '!= 0' with " \
719         "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
720         res, GetLastError(), lstrlenA((char *)buffer));
721
722     /* A Setup-Programm (PDFCreator_0.8.0) use empty strings */
723     SetLastError(MAGIC_DEAD);
724     res = GetPrinterDriverDirectoryA("", "", 1, buffer, cbBuf*2, &pcbNeeded);
725     ok(res, "returned %d with %ld (expected '!=0')\n", res, GetLastError() );
726
727     SetLastError(MAGIC_DEAD);
728     res = GetPrinterDriverDirectoryA(NULL, "", 1, buffer, cbBuf*2, &pcbNeeded);
729     ok(res, "returned %d with %ld (expected '!=0')\n", res, GetLastError() );
730
731     SetLastError(MAGIC_DEAD);
732     res = GetPrinterDriverDirectoryA("", NULL, 1, buffer, cbBuf*2, &pcbNeeded);
733     ok(res, "returned %d with %ld (expected '!=0')\n", res, GetLastError() );
734
735     HeapFree( GetProcessHeap(), 0, buffer);
736 }
737
738 static void test_OpenPrinter(void)
739 {
740     PRINTER_DEFAULTSA defaults;
741     HANDLE  hprinter;
742     LPSTR   default_printer;
743     DWORD   res;
744     DWORD   size;
745     CHAR    buffer[DEFAULT_PRINTER_SIZE];
746     LPSTR   ptr;
747
748     SetLastError(MAGIC_DEAD);
749     res = OpenPrinter(NULL, NULL, NULL);    
750     /* The deactivated Spooler is catched here on NT3.51 */
751     RETURN_ON_DEACTIVATED_SPOOLER(res)
752     ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
753         "returned %ld with %ld (expected '0' with ERROR_INVALID_PARAMETER)\n",
754         res, GetLastError());
755
756
757     /* Get Handle for the local Printserver (NT only)*/
758     hprinter = (HANDLE) MAGIC_DEAD;
759     SetLastError(MAGIC_DEAD);
760     res = OpenPrinter(NULL, &hprinter, NULL);
761     /* The deactivated Spooler is catched here on XPsp2 */
762     RETURN_ON_DEACTIVATED_SPOOLER(res)
763     ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
764         "returned %ld with %ld (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
765         res, GetLastError());
766     if(res) {
767         ClosePrinter(hprinter);
768
769         defaults.pDatatype=NULL;
770         defaults.pDevMode=NULL;
771
772         defaults.DesiredAccess=0;
773         hprinter = (HANDLE) MAGIC_DEAD;
774         SetLastError(MAGIC_DEAD);
775         res = OpenPrinter(NULL, &hprinter, &defaults);
776         ok(res, "returned %ld with %ld (expected '!=0')\n", res, GetLastError());
777         if (res) ClosePrinter(hprinter);
778
779         defaults.DesiredAccess=-1;
780         hprinter = (HANDLE) MAGIC_DEAD;
781         SetLastError(MAGIC_DEAD);
782         res = OpenPrinter(NULL, &hprinter, &defaults);
783         todo_wine {
784         ok(!res && GetLastError() == ERROR_ACCESS_DENIED,
785             "returned %ld with %ld (expected '0' with ERROR_ACCESS_DENIED)\n", 
786             res, GetLastError());
787         }
788         if (res) ClosePrinter(hprinter);
789
790     }
791
792     size = sizeof(buffer) - 3 ;
793     ptr = buffer;
794     ptr[0] = '\\';
795     ptr++;
796     ptr[0] = '\\';
797     ptr++;
798     if (GetComputerNameA(ptr, &size)) {
799
800         hprinter = (HANDLE) MAGIC_DEAD;
801         SetLastError(MAGIC_DEAD);
802         res = OpenPrinter(buffer, &hprinter, NULL);
803         todo_wine {
804         ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
805             "returned %ld with %ld (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
806             res, GetLastError());
807         }
808         if(res) ClosePrinter(hprinter);
809     }
810
811     /* Invalid Printername */
812     hprinter = (HANDLE) MAGIC_DEAD;
813     SetLastError(MAGIC_DEAD);
814     res = OpenPrinter("illegal,name", &hprinter, NULL);
815     ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
816                 (GetLastError() == ERROR_INVALID_PARAMETER) ),
817        "returned %ld with %ld (expected '0' with: ERROR_INVALID_PARAMETER or" \
818        "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
819     if(res) ClosePrinter(hprinter);
820
821     hprinter = (HANDLE) MAGIC_DEAD;
822     SetLastError(MAGIC_DEAD);
823     res = OpenPrinter("", &hprinter, NULL);
824     /* NT: ERROR_INVALID_PRINTER_NAME,  9x: ERROR_INVALID_PARAMETER */
825     ok( !res &&
826         ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
827         (GetLastError() == ERROR_INVALID_PARAMETER) ),
828         "returned %ld with %ld (expected '0' with: ERROR_INVALID_PRINTER_NAME" \
829         " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
830     if(res) ClosePrinter(hprinter);
831
832
833     /* Get Handle for the default Printer */
834     if ((default_printer = find_default_printer()))
835     {
836         hprinter = (HANDLE) MAGIC_DEAD;
837         SetLastError(MAGIC_DEAD);
838         res = OpenPrinter(default_printer, &hprinter, NULL);
839         if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
840         {
841             trace("The Service 'Spooler' is required for '%s'\n", default_printer);
842             return;
843         }
844         ok(res, "returned %ld with %ld (expected '!=0')\n", res, GetLastError());
845         if(res) ClosePrinter(hprinter);
846
847         SetLastError(MAGIC_DEAD);
848         res = OpenPrinter(default_printer, NULL, NULL);
849         /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
850         ok(res || (GetLastError() == ERROR_INVALID_PARAMETER),
851             "returned %ld with %ld (expected '!=0' or '0' with " \
852             "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
853
854         defaults.pDatatype=NULL;
855         defaults.pDevMode=NULL;
856         defaults.DesiredAccess=0;
857
858         hprinter = (HANDLE) MAGIC_DEAD;
859         SetLastError(MAGIC_DEAD);
860         res = OpenPrinter(default_printer, &hprinter, &defaults);
861         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
862             "returned %ld with %ld (expected '!=0' or '0' with " \
863             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
864         if(res) ClosePrinter(hprinter);
865
866         defaults.pDatatype="";
867
868         hprinter = (HANDLE) MAGIC_DEAD;
869         SetLastError(MAGIC_DEAD);
870         res = OpenPrinter(default_printer, &hprinter, &defaults);
871         /* stop here, when a remote Printserver has no RPC-Service running */
872         RETURN_ON_DEACTIVATED_SPOOLER(res)
873         ok(res || ((GetLastError() == ERROR_INVALID_DATATYPE) ||
874                    (GetLastError() == ERROR_ACCESS_DENIED)),
875             "returned %ld with %ld (expected '!=0' or '0' with: " \
876             "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
877             res, GetLastError());
878         if(res) ClosePrinter(hprinter);
879
880
881         defaults.pDatatype=NULL;
882         defaults.DesiredAccess=PRINTER_ACCESS_USE;
883
884         hprinter = (HANDLE) MAGIC_DEAD;
885         SetLastError(MAGIC_DEAD);
886         res = OpenPrinter(default_printer, &hprinter, &defaults);
887         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
888             "returned %ld with %ld (expected '!=0' or '0' with " \
889             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
890         if(res) ClosePrinter(hprinter);
891
892
893         defaults.DesiredAccess=PRINTER_ALL_ACCESS;
894         hprinter = (HANDLE) MAGIC_DEAD;
895         SetLastError(MAGIC_DEAD);
896         res = OpenPrinter(default_printer, &hprinter, &defaults);
897         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
898             "returned %ld with %ld (expected '!=0' or '0' with " \
899             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
900         if(res) ClosePrinter(hprinter);
901     }
902
903 }
904
905
906 static void test_SetDefaultPrinter(void)
907 {
908     DWORD   res;
909     LPSTR   default_printer;
910     DWORD   size = DEFAULT_PRINTER_SIZE;
911     CHAR    buffer[DEFAULT_PRINTER_SIZE];
912     CHAR    org_value[DEFAULT_PRINTER_SIZE];
913
914
915     if (!pSetDefaultPrinterA)  return;
916         /* only supported on win2k and above */
917
918     default_printer = find_default_printer();
919
920     /* backup the original value */
921     org_value[0] = '\0';
922     SetLastError(MAGIC_DEAD);
923     res = GetProfileStringA("windows", "device", NULL, org_value, size);
924
925     /* first part: with the default Printer */
926     SetLastError(MAGIC_DEAD);
927     res = pSetDefaultPrinterA("no_printer_with_this_name");
928
929     RETURN_ON_DEACTIVATED_SPOOLER(res)
930     /* spooler is running or we have no spooler here*/
931
932     /* Not implemented in wine */
933     if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
934         trace("SetDefaultPrinterA() not implemented yet.\n");
935         return;
936     }
937
938     ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
939         "returned %ld with %ld (expected '0' with " \
940         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
941
942     WriteProfileStringA("windows", "device", org_value);
943     SetLastError(MAGIC_DEAD);
944     res = pSetDefaultPrinterA("");
945     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
946         "returned %ld with %ld (expected '!=0' or '0' with " \
947         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
948
949     WriteProfileStringA("windows", "device", org_value);
950     SetLastError(MAGIC_DEAD);
951     res = pSetDefaultPrinterA(NULL);
952     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
953         "returned %ld with %ld (expected '!=0' or '0' with " \
954         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
955
956     WriteProfileStringA("windows", "device", org_value);
957     SetLastError(MAGIC_DEAD);
958     res = pSetDefaultPrinterA(default_printer);
959     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
960         "returned %ld with %ld (expected '!=0' or '0' with " \
961         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
962
963
964     /* second part: always without a default Printer */
965     WriteProfileStringA("windows", "device", NULL);    
966     SetLastError(MAGIC_DEAD);
967     res = pSetDefaultPrinterA("no_printer_with_this_name");
968
969     ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
970         "returned %ld with %ld (expected '0' with " \
971         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
972
973     WriteProfileStringA("windows", "device", NULL);    
974     SetLastError(MAGIC_DEAD);
975     res = pSetDefaultPrinterA("");
976     /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
977     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
978          "returned %ld with %ld (expected '!=0' or '0' with " \
979          "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
980
981     WriteProfileStringA("windows", "device", NULL);    
982     SetLastError(MAGIC_DEAD);
983     res = pSetDefaultPrinterA(NULL);
984     /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
985     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
986         "returned %ld with %ld (expected '!=0' or '0' with " \
987         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
988
989     WriteProfileStringA("windows", "device", NULL);    
990     SetLastError(MAGIC_DEAD);
991     res = pSetDefaultPrinterA(default_printer);
992     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
993         "returned %ld with %ld (expected '!=0' or '0' with " \
994         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
995
996     /* restore the original value */
997     res = pSetDefaultPrinterA(default_printer);          /* the nice way */
998     WriteProfileStringA("windows", "device", org_value); /* the old way */
999
1000     buffer[0] = '\0';
1001     SetLastError(MAGIC_DEAD);
1002     res = GetProfileStringA("windows", "device", NULL, buffer, size);
1003     ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value);
1004
1005 }
1006
1007 static void test_GetPrinterDriver(void)
1008 {
1009     LPSTR default_printer;
1010     HANDLE hprn;
1011     BOOL ret;
1012     BYTE *buf;
1013     INT level;
1014     DWORD needed, filled;
1015
1016     default_printer = find_default_printer();
1017     if (!default_printer)
1018     {
1019         trace("There is no default printer installed, skiping the test\n");
1020         return;
1021     }
1022
1023     hprn = 0;
1024     ret = OpenPrinter(default_printer, &hprn, NULL);
1025     if (!ret)
1026     {
1027         trace("There is no printers installed, skiping the test\n");
1028         return;
1029     }
1030     ok(hprn != 0, "wrong hprn %p\n", hprn);
1031
1032     for (level = -1; level <= 7; level++)
1033     {
1034         SetLastError(0xdeadbeef);
1035         needed = (DWORD)-1;
1036         ret = GetPrinterDriver(hprn, NULL, level, NULL, 0, &needed);
1037         ok(!ret, "level %d: GetPrinterDriver should fail\n", level);
1038         if (level >= 1 && level <= 6)
1039         {
1040             /* Not all levels are supported on all Windows-Versions */
1041             if(GetLastError() == ERROR_INVALID_LEVEL) continue;
1042             ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %ld\n", GetLastError());
1043             ok(needed > 0,"not expected needed buffer size %ld\n", needed);
1044         }
1045         else
1046         {
1047             /* ERROR_OUTOFMEMORY found on win9x */
1048             ok( ((GetLastError() == ERROR_INVALID_LEVEL) ||
1049                  (GetLastError() == ERROR_OUTOFMEMORY)),
1050                 "%d: returned %d with %ld (expected '0' with: " \
1051                 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
1052                 level, ret, GetLastError());
1053             /* needed is modified in win9x. The modified Value depends on the
1054                default Printer. testing for "needed == (DWORD)-1" will fail */
1055             continue;
1056         }
1057
1058         buf = HeapAlloc(GetProcessHeap(), 0, needed);
1059
1060         SetLastError(0xdeadbeef);
1061         filled = -1;
1062         ret = GetPrinterDriver(hprn, NULL, level, buf, needed, &filled);
1063         ok(ret, "level %d: GetPrinterDriver error %ld\n", level, GetLastError());
1064         ok(needed == filled, "needed %ld != filled %ld\n", needed, filled);
1065
1066         if (level == 2)
1067         {
1068             DRIVER_INFO_2 *di_2 = (DRIVER_INFO_2 *)buf;
1069             DWORD calculated = sizeof(*di_2);
1070
1071             /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
1072                NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k and above(Usermode): 3  */
1073             ok((di_2->cVersion >= 0 && di_2->cVersion <= 3) ||
1074                 (di_2->cVersion == 0x0400), "di_2->cVersion = %ld\n", di_2->cVersion);
1075             ok(di_2->pName != NULL, "not expected NULL ptr\n");
1076             ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n");
1077             ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n");
1078             ok(di_2->pDataFile != NULL, "not expected NULL ptr\n");
1079             ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n");
1080
1081             trace("cVersion %ld\n", di_2->cVersion);
1082             trace("pName %s\n", di_2->pName);
1083             calculated += strlen(di_2->pName) + 1;
1084             trace("pEnvironment %s\n", di_2->pEnvironment);
1085             calculated += strlen(di_2->pEnvironment) + 1;
1086             trace("pDriverPath %s\n", di_2->pDriverPath);
1087             calculated += strlen(di_2->pDriverPath) + 1;
1088             trace("pDataFile %s\n", di_2->pDataFile);
1089             calculated += strlen(di_2->pDataFile) + 1;
1090             trace("pConfigFile %s\n", di_2->pConfigFile);
1091             calculated += strlen(di_2->pConfigFile) + 1;
1092
1093             /* XP allocates memory for both ANSI and unicode names */
1094             ok(filled >= calculated,"calculated %ld != filled %ld\n", calculated, filled);
1095         }
1096
1097         HeapFree(GetProcessHeap(), 0, buf);
1098     }
1099
1100     SetLastError(0xdeadbeef);
1101     ret = ClosePrinter(hprn);
1102     ok(ret, "ClosePrinter error %ld\n", GetLastError());
1103 }
1104
1105 static void test_DEVMODE(const DEVMODE *dm, LONG dmSize, LPCSTR exp_prn_name)
1106 {
1107     /* On NT3.51, some fields in DEVMODE are empty/zero
1108       (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
1109        We skip the Tests on this Platform */
1110     if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) {
1111     /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
1112         ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1),
1113             "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName);
1114         ok(dm->dmSize + dm->dmDriverExtra == dmSize,
1115             "%u != %ld\n", dm->dmSize + dm->dmDriverExtra, dmSize);
1116     }
1117     trace("dmFields %08lx\n", dm->dmFields);
1118 }
1119
1120 static void test_DocumentProperties(void)
1121 {
1122     LPSTR default_printer;
1123     HANDLE hprn;
1124     LONG dm_size, ret;
1125     DEVMODE *dm;
1126
1127     default_printer = find_default_printer();
1128     if (!default_printer)
1129     {
1130         trace("There is no default printer installed, skiping the test\n");
1131         return;
1132     }
1133
1134     hprn = 0;
1135     ret = OpenPrinter(default_printer, &hprn, NULL);
1136     if (!ret)
1137     {
1138         trace("There is no printers installed, skiping the test\n");
1139         return;
1140     }
1141     ok(hprn != 0, "wrong hprn %p\n", hprn);
1142
1143     dm_size = DocumentProperties(0, hprn, NULL, NULL, NULL, 0);
1144     trace("DEVMODE required size %ld\n", dm_size);
1145     ok(dm_size >= sizeof(DEVMODE), "unexpected DocumentProperties ret value %ld\n", dm_size);
1146
1147     dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
1148
1149     ret = DocumentProperties(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
1150     ok(ret == IDOK, "DocumentProperties ret value %ld != expected IDOK\n", ret);
1151
1152     test_DEVMODE(dm, dm_size, default_printer);
1153
1154     HeapFree(GetProcessHeap(), 0, dm);
1155
1156     SetLastError(0xdeadbeef);
1157     ret = ClosePrinter(hprn);
1158     ok(ret, "ClosePrinter error %ld\n", GetLastError());
1159 }
1160
1161 START_TEST(info)
1162 {
1163     hwinspool = GetModuleHandleA("winspool.drv");
1164     pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
1165     pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
1166
1167     find_default_printer();
1168
1169     test_AddMonitor();
1170     test_DeleteMonitor();
1171     test_DocumentProperties();
1172     test_EnumMonitors(); 
1173     test_GetDefaultPrinter();
1174     test_GetPrinterDriverDirectory();
1175     test_OpenPrinter();
1176     test_GetPrinterDriver();
1177     test_SetDefaultPrinter();
1178 }