Release 1.5.29.
[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 #include <assert.h>
23
24 #define NONAMELESSSTRUCT
25 #define NONAMELESSUNION
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "wingdi.h"
31 #include "winnls.h"
32 #include "winuser.h"
33 #include "winreg.h"
34 #include "winspool.h"
35 #include "commdlg.h"
36 #include "wine/test.h"
37
38 #define MAGIC_DEAD  0xdeadbeef
39 #define DEFAULT_PRINTER_SIZE 1000
40
41 static CHAR defaultspooldirectory[] = "DefaultSpoolDirectory";
42 static CHAR does_not_exist_dll[]= "does_not_exist.dll";
43 static CHAR does_not_exist[]    = "does_not_exist";
44 static CHAR empty[]             = "";
45 static CHAR env_x64[]           = "Windows x64";
46 static CHAR env_x86[]           = "Windows NT x86";
47 static CHAR env_win9x_case[]    = "windowS 4.0";
48 static CHAR illegal_name[]      = "illegal,name";
49 static CHAR invalid_env[]       = "invalid_env";
50 static CHAR LocalPortA[]        = "Local Port";
51 static CHAR portname_com1[]     = "COM1:";
52 static CHAR portname_file[]     = "FILE:";
53 static CHAR portname_lpt1[]     = "LPT1:";
54 static CHAR server_does_not_exist[] = "\\\\does_not_exist";
55 static CHAR version_dll[]       = "version.dll";
56 static CHAR winetest[]          = "winetest";
57 static CHAR xcv_localport[]     = ",XcvMonitor Local Port";
58
59 static WCHAR cmd_MonitorUIW[] = {'M','o','n','i','t','o','r','U','I',0};
60 static WCHAR cmd_PortIsValidW[] = {'P','o','r','t','I','s','V','a','l','i','d',0};
61 static WCHAR emptyW[] = {0};
62
63 static WCHAR portname_com1W[] = {'C','O','M','1',':',0};
64 static WCHAR portname_com2W[] = {'C','O','M','2',':',0};
65 static WCHAR portname_fileW[] = {'F','I','L','E',':',0};
66 static WCHAR portname_lpt1W[] = {'L','P','T','1',':',0};
67 static WCHAR portname_lpt2W[] = {'L','P','T','2',':',0};
68
69 static HANDLE  hwinspool;
70 static BOOL  (WINAPI * pAddPortExA)(LPSTR, DWORD, LPBYTE, LPSTR);
71 static BOOL  (WINAPI * pEnumPrinterDriversW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
72 static BOOL  (WINAPI * pGetDefaultPrinterA)(LPSTR, LPDWORD);
73 static DWORD (WINAPI * pGetPrinterDataExA)(HANDLE, LPCSTR, LPCSTR, LPDWORD, LPBYTE, DWORD, LPDWORD);
74 static BOOL  (WINAPI * pGetPrinterDriverW)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
75 static BOOL  (WINAPI * pGetPrinterW)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
76 static BOOL  (WINAPI * pSetDefaultPrinterA)(LPCSTR);
77 static DWORD (WINAPI * pXcvDataW)(HANDLE, LPCWSTR, PBYTE, DWORD, PBYTE, DWORD, PDWORD, PDWORD);
78 static BOOL  (WINAPI * pIsValidDevmodeW)(PDEVMODEW, SIZE_T);
79
80
81 /* ################################ */
82
83 struct monitor_entry {
84     LPSTR  env;
85     CHAR  dllname[32];
86 };
87
88 static LPSTR default_printer = NULL;
89 static LPSTR local_server = NULL;
90 static LPSTR tempdirA = NULL;
91 static LPSTR tempfileA = NULL;
92 static LPWSTR tempdirW = NULL;
93 static LPWSTR tempfileW = NULL;
94
95 static BOOL is_spooler_deactivated(DWORD res, DWORD lasterror)
96 {
97     if (!res && lasterror == RPC_S_SERVER_UNAVAILABLE)
98     {
99         static int deactivated_spooler_reported = 0;
100         if (!deactivated_spooler_reported)
101         {
102             deactivated_spooler_reported = 1;
103             skip("The service 'Spooler' is required for many tests\n");
104         }
105         return TRUE;
106     }
107     return FALSE;
108 }
109
110 static BOOL is_access_denied(DWORD res, DWORD lasterror)
111 {
112     if (!res && lasterror == ERROR_ACCESS_DENIED)
113     {
114         static int access_denied_reported = 0;
115         if (!access_denied_reported)
116         {
117             access_denied_reported = 1;
118             skip("More access rights are required for many tests\n");
119         }
120         return TRUE;
121     }
122     return FALSE;
123 }
124
125 static BOOL on_win9x = FALSE;
126
127 static BOOL check_win9x(void)
128 {
129     if (pGetPrinterW)
130     {
131         SetLastError(0xdeadbeef);
132         pGetPrinterW(NULL, 0, NULL, 0, NULL);
133         return (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED);
134     }
135     else
136     {
137         return TRUE;
138     }
139 }
140
141 static void find_default_printer(VOID)
142 {
143     static  char    buffer[DEFAULT_PRINTER_SIZE];
144     DWORD   needed;
145     DWORD   res;
146     LPSTR   ptr;
147
148     if ((default_printer == NULL) && (pGetDefaultPrinterA))
149     {
150         /* w2k and above */
151         needed = sizeof(buffer);
152         res = pGetDefaultPrinterA(buffer, &needed);
153         if(res)  default_printer = buffer;
154         trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
155     }
156     if (default_printer == NULL)
157     {
158         HKEY hwindows;
159         DWORD   type;
160         /* NT 3.x and above */
161         if (RegOpenKeyEx(HKEY_CURRENT_USER, 
162                         "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
163                         0, KEY_QUERY_VALUE, &hwindows) == NO_ERROR) {
164
165             needed = sizeof(buffer);
166             if (RegQueryValueEx(hwindows, "device", NULL, 
167                                 &type, (LPBYTE)buffer, &needed) == NO_ERROR) {
168
169                 ptr = strchr(buffer, ',');
170                 if (ptr) {
171                     ptr[0] = '\0';
172                     default_printer = buffer;
173                 }
174             }
175             RegCloseKey(hwindows);
176         }
177         trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
178     }
179     if (default_printer == NULL)
180     {
181         /* win9x */
182         needed = sizeof(buffer);
183         res = GetProfileStringA("windows", "device", "*", buffer, needed);
184         if(res) {
185             ptr = strchr(buffer, ',');
186             if (ptr) {
187                 ptr[0] = '\0';
188                 default_printer = buffer;
189             }
190         }
191         trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
192     }
193 }
194
195
196 static struct monitor_entry * find_installed_monitor(void)
197 {
198     MONITOR_INFO_2A mi2a; 
199     static struct  monitor_entry * entry = NULL;
200     DWORD   num_tests;
201     DWORD   i = 0;
202
203     static struct monitor_entry  monitor_table[] = {
204         {env_win9x_case, "localspl.dll"},
205         {env_x86,        "localspl.dll"},
206         {env_x64,        "localspl.dll"},
207         {env_win9x_case, "localmon.dll"},
208         {env_x86,        "localmon.dll"},
209         {env_win9x_case, "tcpmon.dll"},
210         {env_x86,        "tcpmon.dll"},
211         {env_win9x_case, "usbmon.dll"},
212         {env_x86,        "usbmon.dll"},
213         {env_win9x_case, "mspp32.dll"},
214         {env_x86,        "win32spl.dll"},
215         {env_x86,        "redmonnt.dll"},
216         {env_x86,        "redmon35.dll"},
217         {env_win9x_case, "redmon95.dll"},
218         {env_x86,        "pdfcmnnt.dll"},
219         {env_win9x_case, "pdfcmn95.dll"},
220     };
221
222     if (entry) return entry;
223
224     num_tests = (sizeof(monitor_table)/sizeof(struct monitor_entry));
225
226     /* cleanup */
227     DeleteMonitorA(NULL, env_x64, winetest);
228     DeleteMonitorA(NULL, env_x86, winetest);
229     DeleteMonitorA(NULL, env_win9x_case, winetest);
230
231     /* find a usable monitor from the table */
232     mi2a.pName = winetest;
233     while ((entry == NULL) && (i < num_tests)) {
234         entry = &monitor_table[i];
235         i++;
236         mi2a.pEnvironment = entry->env;
237         mi2a.pDLLName = entry->dllname;
238
239         if (AddMonitorA(NULL, 2, (LPBYTE) &mi2a)) {
240             /* we got one */
241             trace("using '%s', '%s'\n", entry->env, entry->dllname);
242             DeleteMonitorA(NULL, entry->env, winetest);
243         }
244         else
245         {
246             entry = NULL;
247         }
248     }
249     return entry;
250 }
251
252
253 /* ########################### */
254
255 static void find_local_server(VOID)
256 {
257     static  char    buffer[MAX_PATH];
258     DWORD   res;
259     DWORD   size;
260
261     size = sizeof(buffer) - 3 ;
262     buffer[0] = '\\';
263     buffer[1] = '\\';
264     buffer[2] = '\0';
265
266     SetLastError(0xdeadbeef);
267     res = GetComputerNameA(&buffer[2], &size);
268     trace("returned %d with %d and %d: '%s'\n", res, GetLastError(), size, buffer);
269
270     ok( res != 0, "returned %d with %d and %d: '%s' (expected '!= 0')\n",
271         res, GetLastError(), size, buffer);
272
273     if (res) local_server = buffer;
274 }
275
276 /* ########################### */
277
278 static void find_tempfile(VOID)
279 {
280     static CHAR buffer_dirA[MAX_PATH];
281     static CHAR buffer_fileA[MAX_PATH];
282     static WCHAR buffer_dirW[MAX_PATH];
283     static WCHAR buffer_fileW[MAX_PATH];
284     DWORD   res;
285     int     resint;
286
287     memset(buffer_dirA, 0, MAX_PATH - 1);
288     buffer_dirA[MAX_PATH - 1] = '\0';
289     SetLastError(0xdeadbeef);
290     res = GetTempPathA(MAX_PATH, buffer_dirA);
291     ok(res, "returned %u with %u and '%s' (expected '!= 0')\n", res, GetLastError(), buffer_dirA);
292     if (res == 0) return;
293
294     memset(buffer_fileA, 0, MAX_PATH - 1);
295     buffer_fileA[MAX_PATH - 1] = '\0';
296     SetLastError(0xdeadbeef);
297     res = GetTempFileNameA(buffer_dirA, winetest, 0, buffer_fileA);
298     ok(res, "returned %u with %u and '%s' (expected '!= 0')\n", res, GetLastError(), buffer_fileA);
299     if (res == 0) return;
300
301     SetLastError(0xdeadbeef);
302     resint = MultiByteToWideChar(CP_ACP, 0, buffer_dirA, -1, buffer_dirW, MAX_PATH);
303     ok(res, "returned %u with %u (expected '!= 0')\n", resint, GetLastError());
304     if (resint == 0) return;
305
306     SetLastError(0xdeadbeef);
307     resint = MultiByteToWideChar(CP_ACP, 0, buffer_fileA, -1, buffer_fileW, MAX_PATH);
308     ok(res, "returned %u with %u (expected '!= 0')\n", resint, GetLastError());
309     if (resint == 0) return;
310
311     tempdirA  = buffer_dirA;
312     tempfileA = buffer_fileA;
313     tempdirW  = buffer_dirW;
314     tempfileW = buffer_fileW;
315     trace("tempfile: '%s'\n", tempfileA);
316 }
317
318 /* ########################### */
319
320 static void test_AddMonitor(void)
321 {
322     MONITOR_INFO_2A mi2a; 
323     struct  monitor_entry * entry = NULL;
324     DWORD   res;
325
326     entry = find_installed_monitor();
327
328     SetLastError(MAGIC_DEAD);
329     res = AddMonitorA(NULL, 1, NULL);
330     ok(!res && (GetLastError() == ERROR_INVALID_LEVEL), 
331         "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
332         res, GetLastError());
333
334     SetLastError(MAGIC_DEAD);
335     res = AddMonitorA(NULL, 3, NULL);
336     ok(!res && (GetLastError() == ERROR_INVALID_LEVEL), 
337         "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
338         res, GetLastError());
339
340     if (0)
341     {
342     /* This test crashes win9x on vmware (works with win9x on qemu 0.8.1) */
343     SetLastError(MAGIC_DEAD);
344     res = AddMonitorA(NULL, 2, NULL);
345     /* NT: unchanged,  9x: ERROR_PRIVILEGE_NOT_HELD */
346     ok(!res &&
347         ((GetLastError() == MAGIC_DEAD) ||
348          (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 
349         "returned %d with %d (expected '0' with: MAGIC_DEAD or "
350         "ERROR_PRIVILEGE_NOT_HELD)\n", res, GetLastError());
351     }
352
353     ZeroMemory(&mi2a, sizeof(MONITOR_INFO_2A));
354     SetLastError(MAGIC_DEAD);
355     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
356     if (is_spooler_deactivated(res, GetLastError())) return;
357     if (is_access_denied(res, GetLastError())) return;
358
359     /* NT: ERROR_INVALID_PARAMETER,  9x: ERROR_INVALID_ENVIRONMENT */
360     ok(!res && ((GetLastError() == ERROR_INVALID_PARAMETER) ||
361                 (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 
362         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
363         "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
364
365     if (!entry) {
366         skip("No usable Monitor found\n");
367         return;
368     }
369
370     if (0)
371     {
372     /* The test is deactivated, because when mi2a.pName is NULL, the subkey
373        HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM
374        or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì
375        is created on win9x and we do not want to hit this bug here. */
376
377     mi2a.pEnvironment = entry->env;
378     SetLastError(MAGIC_DEAD);
379     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
380     ok(res, "AddMonitor error %d\n", GetLastError());
381     /* NT: ERROR_INVALID_PARAMETER,  9x: ERROR_PRIVILEGE_NOT_HELD */
382     }
383
384     mi2a.pEnvironment = entry->env;
385     mi2a.pName = empty;
386     SetLastError(MAGIC_DEAD);
387     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
388     /* NT: ERROR_INVALID_PARAMETER,  9x: ERROR_PRIVILEGE_NOT_HELD */
389     ok( !res &&
390         ((GetLastError() == ERROR_INVALID_PARAMETER) ||
391          (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 
392         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
393         "ERROR_PRIVILEGE_NOT_HELD)\n",
394         res, GetLastError());
395
396     mi2a.pName = winetest;
397     SetLastError(MAGIC_DEAD);
398     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
399     /* NT: ERROR_INVALID_PARAMETER,  9x: ERROR_PRIVILEGE_NOT_HELD */
400     ok( !res &&
401         ((GetLastError() == ERROR_INVALID_PARAMETER) ||
402          (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 
403         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
404         "ERROR_PRIVILEGE_NOT_HELD)\n",
405         res, GetLastError());
406
407     mi2a.pDLLName = empty;
408     SetLastError(MAGIC_DEAD);
409     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
410     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
411         "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
412         res, GetLastError());
413
414     mi2a.pDLLName = does_not_exist_dll;
415     SetLastError(MAGIC_DEAD);
416     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
417     /* NT: ERROR_MOD_NOT_FOUND,  9x: ERROR_INVALID_PARAMETER */
418     ok( !res &&
419         ((GetLastError() == ERROR_MOD_NOT_FOUND) ||
420         (GetLastError() == ERROR_INVALID_PARAMETER)),
421         "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or "
422         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
423
424     mi2a.pDLLName = version_dll;
425     SetLastError(MAGIC_DEAD);
426     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
427     /* NT: ERROR_PROC_NOT_FOUND,  9x: ERROR_INVALID_PARAMETER */
428     ok( !res &&
429         ((GetLastError() == ERROR_PROC_NOT_FOUND) ||
430         (GetLastError() == ERROR_INVALID_PARAMETER)),
431         "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or "
432         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
433     if (res) DeleteMonitorA(NULL, entry->env, winetest);
434
435    /* Test AddMonitor with real options */
436     mi2a.pDLLName = entry->dllname;
437     SetLastError(MAGIC_DEAD);
438     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
439     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
440
441     /* add a monitor twice */
442     SetLastError(MAGIC_DEAD);
443     res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
444     /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */
445     ok( !res &&
446         ((GetLastError() == ERROR_PRINT_MONITOR_ALREADY_INSTALLED) ||
447         (GetLastError() == ERROR_ALREADY_EXISTS)), 
448         "returned %d with %d (expected '0' with: "
449         "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n",
450         res, GetLastError());
451
452     DeleteMonitorA(NULL, entry->env, winetest);
453     SetLastError(MAGIC_DEAD);
454     res = AddMonitorA(empty, 2, (LPBYTE) &mi2a);
455     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
456
457     /* cleanup */
458     DeleteMonitorA(NULL, entry->env, winetest);
459
460 }
461
462 /* ########################### */
463
464 static void test_AddPort(void)
465 {
466     DWORD   res;
467
468     SetLastError(0xdeadbeef);
469     res = AddPortA(NULL, 0, NULL);
470     if (is_spooler_deactivated(res, GetLastError())) return;
471     /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
472     ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) || 
473                  (GetLastError() == ERROR_INVALID_PARAMETER)),
474         "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
475         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
476
477
478     SetLastError(0xdeadbeef);
479     res = AddPortA(NULL, 0, empty);
480     /* Allowed only for (Printer-)Administrators */
481     if (is_access_denied(res, GetLastError())) return;
482
483     /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
484     ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 
485                  (GetLastError() == ERROR_INVALID_PARAMETER)),
486         "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
487         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
488
489
490     SetLastError(0xdeadbeef);
491     res = AddPortA(NULL, 0, does_not_exist);
492     /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
493     ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 
494                  (GetLastError() == ERROR_INVALID_PARAMETER)),
495         "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
496         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
497
498 }
499
500 /* ########################### */
501
502 static void test_AddPortEx(void)
503 {
504     PORT_INFO_2A pi;
505     DWORD   res;
506
507
508     if (!pAddPortExA) {
509         win_skip("AddPortEx not supported\n");
510         return;
511     }
512
513     /* start test with a clean system */
514     DeletePortA(NULL, 0, tempfileA);
515
516     pi.pPortName = tempfileA;
517     SetLastError(0xdeadbeef);
518     res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
519     if (is_spooler_deactivated(res, GetLastError())) return;
520
521     /* Allowed only for (Printer-)Administrators.
522        W2K+XP: ERROR_INVALID_PARAMETER  */
523     if (!res && (GetLastError() == ERROR_INVALID_PARAMETER)) {
524         skip("ACCESS_DENIED (ERROR_INVALID_PARAMETER)\n");
525         return;
526     }
527     ok( res, "got %u with %u (expected '!= 0')\n", res, GetLastError());
528
529     /* add a port that already exists */
530     SetLastError(0xdeadbeef);
531     res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
532     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
533         "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
534         res, GetLastError());
535     DeletePortA(NULL, 0, tempfileA);
536
537
538     /* the Monitorname must match */
539     SetLastError(0xdeadbeef);
540     res = pAddPortExA(NULL, 1, (LPBYTE) &pi, NULL);
541     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
542         "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
543         res, GetLastError());
544     if (res) DeletePortA(NULL, 0, tempfileA);
545
546     SetLastError(0xdeadbeef);
547     res = pAddPortExA(NULL, 1, (LPBYTE) &pi, empty);
548     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
549         "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
550         res, GetLastError());
551     if (res) DeletePortA(NULL, 0, tempfileA);
552
553     SetLastError(0xdeadbeef);
554     res = pAddPortExA(NULL, 1, (LPBYTE) &pi, does_not_exist);
555     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
556         "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
557         res, GetLastError());
558     if (res) DeletePortA(NULL, 0, tempfileA);
559
560
561     /* We need a Portname */
562     SetLastError(0xdeadbeef);
563     res = pAddPortExA(NULL, 1, NULL, LocalPortA);
564     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
565         "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
566         res, GetLastError());
567
568     pi.pPortName = NULL;
569     SetLastError(0xdeadbeef);
570     res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
571     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
572         "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
573         res, GetLastError());
574     if (res) DeletePortA(NULL, 0, tempfileA);
575
576
577     /*  level 2 is documented as supported for Printmonitors,
578         but that is not supported for "Local Port" (localspl.dll) and
579         AddPortEx fails with ERROR_INVALID_LEVEL */
580
581     pi.pPortName = tempfileA;
582     pi.pMonitorName = LocalPortA;
583     pi.pDescription = winetest;
584     pi.fPortType = PORT_TYPE_WRITE;
585
586     SetLastError(0xdeadbeef);
587     res = pAddPortExA(NULL, 2, (LPBYTE) &pi, LocalPortA);
588     ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
589         "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
590         res, GetLastError());
591     if (res) DeletePortA(NULL, 0, tempfileA);
592
593
594     /* invalid levels */
595     SetLastError(0xdeadbeef);
596     res = pAddPortExA(NULL, 0, (LPBYTE) &pi, LocalPortA);
597     ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
598         "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
599         res, GetLastError());
600
601     SetLastError(0xdeadbeef);
602     res = pAddPortExA(NULL, 3, (LPBYTE) &pi, LocalPortA);
603     ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
604         "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
605         res, GetLastError());
606
607
608     /* cleanup */
609     DeletePortA(NULL, 0, tempfileA);
610
611 }
612
613 /* ########################### */
614
615 static void test_ConfigurePort(void)
616 {
617     DWORD   res;
618
619
620     SetLastError(0xdeadbeef);
621     res = ConfigurePortA(NULL, 0, NULL);
622     if (is_spooler_deactivated(res, GetLastError())) return;
623     /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
624     ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) || 
625                  (GetLastError() == ERROR_INVALID_PARAMETER)),
626         "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
627         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
628
629     SetLastError(0xdeadbeef);
630     res = ConfigurePortA(NULL, 0, empty);
631     /* Allowed only for (Printer-)Administrators */
632     if (is_access_denied(res, GetLastError())) return;
633
634     /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
635     ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 
636                  (GetLastError() == ERROR_INVALID_PARAMETER)),
637         "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
638         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
639
640
641     SetLastError(0xdeadbeef);
642     res = ConfigurePortA(NULL, 0, does_not_exist);
643     /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
644     ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 
645                  (GetLastError() == ERROR_INVALID_PARAMETER)),
646         "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
647         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
648
649
650     /*  Testing-Results:
651         - Case of Portnames is ignored 
652         - Portname without ":" => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
653         - Empty Servername (LPT1:) => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
654
655         - Port not present =>  9x: ERROR_INVALID_PARAMETER, NT:ERROR_NOT_SUPPORTED
656         - "FILE:" => 9x:Success, NT:ERROR_CANCELED
657         - Cancel ("Local Port") => ERROR_CANCELED
658         - Cancel ("Redirected Port") => Success
659     */
660     if (winetest_interactive > 0) {
661         SetLastError(0xdeadbeef);
662         res = ConfigurePortA(NULL, 0, portname_com1);
663         trace("'%s' returned %d with %d\n", portname_com1, res, GetLastError());
664
665         SetLastError(0xdeadbeef);
666         res = ConfigurePortA(NULL, 0, portname_lpt1);
667         trace("'%s' returned %d with %d\n", portname_lpt1, res, GetLastError());
668
669         SetLastError(0xdeadbeef);
670         res = ConfigurePortA(NULL, 0, portname_file);
671         trace("'%s' returned %d with %d\n", portname_file, res, GetLastError());
672     }
673 }
674
675 /* ########################### */
676
677 static void test_DeleteMonitor(void)
678 {
679     MONITOR_INFO_2A         mi2a;
680     struct monitor_entry  * entry = NULL;
681     DWORD                   res;
682
683
684     entry = find_installed_monitor();
685
686     if (!entry) {
687         skip("No usable Monitor found\n");
688         return;
689     }
690
691     mi2a.pName = winetest;
692     mi2a.pEnvironment = entry->env;
693     mi2a.pDLLName = entry->dllname;
694
695     /* Testing DeleteMonitor with real options */
696     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
697
698     SetLastError(MAGIC_DEAD);
699     res = DeleteMonitorA(NULL, entry->env, winetest);
700     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
701
702     /* Delete the Monitor twice */
703     SetLastError(MAGIC_DEAD);
704     res = DeleteMonitorA(NULL, entry->env, winetest);
705     /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
706     ok( !res &&
707         ((GetLastError() == ERROR_UNKNOWN_PRINT_MONITOR) ||
708         (GetLastError() == ERROR_INVALID_PARAMETER)), 
709         "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR"
710         " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
711
712     /* the environment */
713     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
714     SetLastError(MAGIC_DEAD);
715     res = DeleteMonitorA(NULL, NULL, winetest);
716     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
717
718     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
719     SetLastError(MAGIC_DEAD);
720     res = DeleteMonitorA(NULL, empty, winetest);
721     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
722
723     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
724     SetLastError(MAGIC_DEAD);
725     res = DeleteMonitorA(NULL, invalid_env, winetest);
726     ok( res ||
727         (!res && GetLastError() == ERROR_INVALID_ENVIRONMENT) /* Vista/W2K8 */,
728         "returned %d with %d\n", res, GetLastError());
729
730     /* the monitor-name */
731     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
732     SetLastError(MAGIC_DEAD);
733     res = DeleteMonitorA(NULL, entry->env, NULL);
734     /* NT: ERROR_INVALID_PARAMETER (87),  9x: ERROR_INVALID_NAME (123)*/
735     ok( !res &&
736         ((GetLastError() == ERROR_INVALID_PARAMETER) ||
737         (GetLastError() == ERROR_INVALID_NAME)),
738         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
739         "ERROR_INVALID_NAME)\n", res, GetLastError());
740
741     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
742     SetLastError(MAGIC_DEAD);
743     res = DeleteMonitorA(NULL, entry->env, empty);
744     /* NT: ERROR_INVALID_PARAMETER (87),  9x: ERROR_INVALID_NAME (123)*/
745     ok( !res && 
746         ((GetLastError() == ERROR_INVALID_PARAMETER) ||
747         (GetLastError() == ERROR_INVALID_NAME)),
748         "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
749         "ERROR_INVALID_NAME)\n", res, GetLastError());
750
751     AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
752     SetLastError(MAGIC_DEAD);
753     res = DeleteMonitorA(empty, entry->env, winetest);
754     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
755
756     /* cleanup */
757     DeleteMonitorA(NULL, entry->env, winetest);
758 }
759
760 /* ########################### */
761
762 static void test_DeletePort(void)
763 {
764     DWORD   res;
765
766     SetLastError(0xdeadbeef);
767     res = DeletePortA(NULL, 0, NULL);
768     if (is_spooler_deactivated(res, GetLastError())) return;
769
770     SetLastError(0xdeadbeef);
771     res = DeletePortA(NULL, 0, empty);
772     /* Allowed only for (Printer-)Administrators */
773     if (is_access_denied(res, GetLastError())) return;
774
775     /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
776     ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 
777                  (GetLastError() == ERROR_INVALID_PARAMETER)),
778         "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
779         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
780
781
782     SetLastError(0xdeadbeef);
783     res = DeletePortA(NULL, 0, does_not_exist);
784     /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
785     ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 
786                  (GetLastError() == ERROR_INVALID_PARAMETER)),
787         "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
788         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
789
790 }
791
792 /* ########################### */
793
794 static void test_EnumForms(LPSTR pName)
795 {
796     DWORD   res;
797     HANDLE  hprinter = 0;
798     LPBYTE  buffer;
799     DWORD   cbBuf;
800     DWORD   pcbNeeded;
801     DWORD   pcReturned;
802     DWORD   level;
803     UINT    i;
804     const char *formtype;
805     static const char * const formtypes[] = { "FORM_USER", "FORM_BUILTIN", "FORM_PRINTER", "FORM_flag_unknown" };
806 #define FORMTYPE_MAX 2
807     PFORM_INFO_1A pFI_1a;
808     PFORM_INFO_2A pFI_2a;
809
810     res = OpenPrinter(pName, &hprinter, NULL);
811     if (is_spooler_deactivated(res, GetLastError())) return;
812     if (!res || !hprinter)
813     {
814         /* opening the local Printserver is not supported on win9x */
815         if (pName) skip("Failed to open '%s' (not supported on win9x)\n", pName);
816         return;
817     }
818
819     /* valid levels are 1 and 2 */
820     for(level = 0; level < 4; level++) {
821         cbBuf = 0xdeadbeef;
822         pcReturned = 0xdeadbeef;
823         SetLastError(0xdeadbeef);
824         res = EnumFormsA(hprinter, level, NULL, 0, &cbBuf, &pcReturned);
825
826         /* EnumForms is not implemented on win9x */
827         if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
828
829         /* EnumForms for the server is not implemented on all NT-versions */
830         if (!res && (GetLastError() == ERROR_INVALID_HANDLE) && !pName) continue;
831
832         /* Level 2 for EnumForms is not supported on all systems */
833         if (!res && (GetLastError() == ERROR_INVALID_LEVEL) && (level == 2)) continue;
834
835         /* use only a short test when testing an invalid level */
836         if(!level || (level > 2)) {
837             ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
838                 (res && (pcReturned == 0)),
839                 "(%d) returned %d with %d and 0x%08x (expected '0' with "
840                 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
841                 level, res, GetLastError(), pcReturned);
842             continue;
843         }
844
845         ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
846             "(%d) returned %d with %d (expected '0' with "
847             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
848
849         buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
850         if (buffer == NULL) continue;
851
852         SetLastError(0xdeadbeef);
853         res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
854         ok(res, "(%d) returned %d with %d (expected '!=0')\n",
855                 level, res, GetLastError());
856
857         if (winetest_debug > 1) {
858             trace("dumping %d forms level %d\n", pcReturned, level);
859             pFI_1a = (PFORM_INFO_1A)buffer;
860             pFI_2a = (PFORM_INFO_2A)buffer;
861             for (i = 0; i < pcReturned; i++)
862             {
863                 /* first part is same in FORM_INFO_1 and FORM_INFO_2 */
864                 formtype = (pFI_1a->Flags <= FORMTYPE_MAX) ? formtypes[pFI_1a->Flags] : formtypes[3];
865                 trace("%u (%s): %.03fmm x %.03fmm, %s\n", i, pFI_1a->pName,
866                       (float)pFI_1a->Size.cx/1000, (float)pFI_1a->Size.cy/1000, formtype);
867
868                 if (level == 1) pFI_1a ++;
869                 else {
870                     /* output additional FORM_INFO_2 fields */
871                     trace("\tkeyword=%s strtype=%u muidll=%s resid=%u dispname=%s langid=%u\n",
872                           pFI_2a->pKeyword, pFI_2a->StringType, pFI_2a->pMuiDll,
873                           pFI_2a->dwResourceId, pFI_2a->pDisplayName, pFI_2a->wLangId);
874
875                     /* offset pointer pFI_1a by 1*sizeof(FORM_INFO_2A) Bytes */
876                     pFI_2a ++;
877                     pFI_1a = (PFORM_INFO_1A)pFI_2a;
878                 }
879             }
880         }
881
882         SetLastError(0xdeadbeef);
883         res = EnumFormsA(hprinter, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
884         ok( res, "(%d) returned %d with %d (expected '!=0')\n",
885             level, res, GetLastError());
886
887         SetLastError(0xdeadbeef);
888         res = EnumFormsA(hprinter, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
889         ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
890             "(%d) returned %d with %d (expected '0' with "
891             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
892
893
894         SetLastError(0xdeadbeef);
895         res = EnumFormsA(hprinter, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
896         ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) ,
897             "(%d) returned %d with %d (expected '0' with "
898             "ERROR_INVALID_USER_BUFFER)\n", level, res, GetLastError());
899
900
901         SetLastError(0xdeadbeef);
902         res = EnumFormsA(hprinter, level, buffer, cbBuf, NULL, &pcReturned);
903         ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
904             "(%d) returned %d with %d (expected '0' with "
905             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
906
907         SetLastError(0xdeadbeef);
908         res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, NULL);
909         ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
910             "(%d) returned %d with %d (expected '0' with "
911             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
912
913         SetLastError(0xdeadbeef);
914         res = EnumFormsA(0, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
915         ok( !res && (GetLastError() == ERROR_INVALID_HANDLE) ,
916             "(%d) returned %d with %d (expected '0' with "
917             "ERROR_INVALID_HANDLE)\n", level, res, GetLastError());
918
919         HeapFree(GetProcessHeap(), 0, buffer);
920     } /* for(level ... */
921
922     ClosePrinter(hprinter);
923 }
924
925 /* ########################### */
926
927 static void test_EnumMonitors(void)
928 {
929     DWORD   res;
930     LPBYTE  buffer;
931     DWORD   cbBuf;
932     DWORD   pcbNeeded;
933     DWORD   pcReturned;
934     DWORD   level;
935
936     /* valid levels are 1 and 2 */
937     for(level = 0; level < 4; level++) {
938         cbBuf = MAGIC_DEAD;
939         pcReturned = MAGIC_DEAD;
940         SetLastError(MAGIC_DEAD);
941         res = EnumMonitorsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
942         if (is_spooler_deactivated(res, GetLastError())) return;
943         /* not implemented yet in wine */
944         if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
945
946
947         /* use only a short test when testing an invalid level */
948         if(!level || (level > 2)) {
949             ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
950                 (res && (pcReturned == 0)),
951                 "(%d) returned %d with %d and 0x%08x (expected '0' with "
952                 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
953                 level, res, GetLastError(), pcReturned);
954             continue;
955         }        
956
957         /* Level 2 is not supported on win9x */
958         if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
959             skip("Level %d not supported\n", level);
960             continue;
961         }
962
963         ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
964             "(%d) returned %d with %d (expected '0' with "
965             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
966
967         if (!cbBuf) {
968             skip("no valid buffer size returned\n");
969             continue;
970         }
971
972         buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
973         if (buffer == NULL) continue;
974
975         SetLastError(MAGIC_DEAD);
976         pcbNeeded = MAGIC_DEAD;
977         res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
978         ok(res, "(%d) returned %d with %d (expected '!=0')\n",
979                 level, res, GetLastError());
980         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n",
981                 level, pcbNeeded, cbBuf);
982         /* We can validate the returned Data with the Registry here */
983
984
985         SetLastError(MAGIC_DEAD);
986         pcReturned = MAGIC_DEAD;
987         pcbNeeded = MAGIC_DEAD;
988         res = EnumMonitorsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
989         ok(res, "(%d) returned %d with %d (expected '!=0')\n", level,
990                 res, GetLastError());
991         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
992                 pcbNeeded, cbBuf);
993
994         SetLastError(MAGIC_DEAD);
995         pcbNeeded = MAGIC_DEAD;
996         res = EnumMonitorsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
997         ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
998             "(%d) returned %d with %d (expected '0' with "
999             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1000
1001         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
1002                 pcbNeeded, cbBuf);
1003
1004 /*
1005       Do not add the next test:
1006       w2k+:  RPC_X_NULL_REF_POINTER 
1007       NT3.5: ERROR_INVALID_USER_BUFFER
1008       win9x: crash in winspool.drv
1009
1010       res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1011 */
1012
1013         SetLastError(MAGIC_DEAD);
1014         pcbNeeded = MAGIC_DEAD;
1015         pcReturned = MAGIC_DEAD;
1016         res = EnumMonitorsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
1017         ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
1018             "(%d) returned %d with %d (expected '!=0' or '0' with "
1019             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1020
1021         pcbNeeded = MAGIC_DEAD;
1022         pcReturned = MAGIC_DEAD;
1023         SetLastError(MAGIC_DEAD);
1024         res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
1025         ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
1026             "(%d) returned %d with %d (expected '!=0' or '0' with "
1027             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1028
1029         HeapFree(GetProcessHeap(), 0, buffer);
1030     } /* for(level ... */
1031 }
1032
1033 /* ########################### */
1034
1035 static void test_EnumPorts(void)
1036 {
1037     DWORD   res;
1038     DWORD   level;
1039     LPBYTE  buffer;
1040     DWORD   cbBuf;
1041     DWORD   pcbNeeded;
1042     DWORD   pcReturned;
1043
1044     /* valid levels are 1 and 2 */
1045     for(level = 0; level < 4; level++) {
1046
1047         cbBuf = 0xdeadbeef;
1048         pcReturned = 0xdeadbeef;
1049         SetLastError(0xdeadbeef);
1050         res = EnumPortsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
1051         if (is_spooler_deactivated(res, GetLastError())) return;
1052
1053         /* use only a short test when testing an invalid level */
1054         if(!level || (level > 2)) {
1055             /* NT: ERROR_INVALID_LEVEL, 9x: success */
1056             ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1057                 (res && (pcReturned == 0)),
1058                 "(%d) returned %d with %d and 0x%08x (expected '0' with "
1059                 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1060                 level, res, GetLastError(), pcReturned);
1061             continue;
1062         }        
1063
1064         
1065         /* Level 2 is not supported on NT 3.x */
1066         if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
1067             skip("Level %d not supported\n", level);
1068             continue;
1069         }
1070
1071         ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1072             "(%d) returned %d with %d (expected '0' with "
1073             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1074
1075         buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
1076         if (buffer == NULL) continue;
1077
1078         pcbNeeded = 0xdeadbeef;
1079         SetLastError(0xdeadbeef);
1080         res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
1081         ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
1082         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1083         /* ToDo: Compare the returned Data with the Registry / "win.ini",[Ports] here */
1084
1085         pcbNeeded = 0xdeadbeef;
1086         pcReturned = 0xdeadbeef;
1087         SetLastError(0xdeadbeef);
1088         res = EnumPortsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1089         ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
1090         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1091
1092         pcbNeeded = 0xdeadbeef;
1093         SetLastError(0xdeadbeef);
1094         res = EnumPortsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1095         ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1096             "(%d) returned %d with %d (expected '0' with "
1097             "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1098         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1099
1100         /*
1101           Do not add this test:
1102           res = EnumPortsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1103           w2k+:  RPC_X_NULL_REF_POINTER 
1104           NT3.5: ERROR_INVALID_USER_BUFFER
1105           win9x: crash in winspool.drv
1106          */
1107
1108         SetLastError(0xdeadbeef);
1109         res = EnumPorts(NULL, level, buffer, cbBuf, NULL, &pcReturned);
1110         /* NT: RPC_X_NULL_REF_POINTER (1780),  9x: success */
1111         ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
1112             ( res && (GetLastError() == ERROR_SUCCESS) ),
1113             "(%d) returned %d with %d (expected '0' with "
1114             "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1115             level, res, GetLastError());
1116
1117
1118         SetLastError(0xdeadbeef);
1119         res = EnumPorts(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
1120         /* NT: RPC_X_NULL_REF_POINTER (1780),  9x: success */
1121         ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
1122             ( res && (GetLastError() == ERROR_SUCCESS) ),
1123             "(%d) returned %d with %d (expected '0' with "
1124             "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1125             level, res, GetLastError());
1126
1127         HeapFree(GetProcessHeap(), 0, buffer);
1128     }
1129 }
1130
1131 /* ########################### */
1132
1133 static void test_EnumPrinterDrivers(void)
1134 {
1135     static char env_all[] = "all";
1136
1137     DWORD   res;
1138     LPBYTE  buffer;
1139     DWORD   cbBuf;
1140     DWORD   pcbNeeded;
1141     DWORD   pcReturned;
1142     DWORD   level;
1143
1144     /* 1-3 for w95/w98/NT4; 1-3+6 for me; 1-6 for w2k/xp/2003; 1-6+8 for vista */
1145     for(level = 0; level < 10; level++) {
1146         cbBuf = 0xdeadbeef;
1147         pcReturned = 0xdeadbeef;
1148         SetLastError(0xdeadbeef);
1149         res = EnumPrinterDriversA(NULL, NULL, level, NULL, 0, &cbBuf, &pcReturned);
1150         if (is_spooler_deactivated(res, GetLastError())) return;
1151
1152         /* use only a short test when testing an invalid level */
1153         if(!level || (level == 7) || (level > 8)) {
1154
1155             ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1156                 (res && (pcReturned == 0)),
1157                 "(%d) got %u with %u and 0x%x "
1158                 "(expected '0' with ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1159                 level, res, GetLastError(), pcReturned);
1160             continue;
1161         }
1162
1163         /* some levels are not supported on all windows versions */
1164         if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
1165             skip("Level %d not supported\n", level);
1166             continue;
1167         }
1168
1169         ok( ((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) ||
1170             (res && (default_printer == NULL)),
1171             "(%u) got %u with %u for %s (expected '0' with "
1172             "ERROR_INSUFFICIENT_BUFFER or '!= 0' without a printer)\n",
1173             level, res, GetLastError(), default_printer);
1174
1175         if (!cbBuf) {
1176             skip("no valid buffer size returned\n");
1177             continue;
1178         }
1179
1180         /* EnumPrinterDriversA returns the same number of bytes as EnumPrinterDriversW */
1181         if (!on_win9x && pEnumPrinterDriversW)
1182         {
1183             DWORD double_needed;
1184             DWORD double_returned;
1185             pEnumPrinterDriversW(NULL, NULL, level, NULL, 0, &double_needed, &double_returned);
1186             ok(double_needed == cbBuf, "level %d: EnumPrinterDriversA returned different size %d than EnumPrinterDriversW (%d)\n", level, cbBuf, double_needed);
1187         }
1188
1189         buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4);
1190         if (buffer == NULL) continue;
1191
1192         SetLastError(0xdeadbeef);
1193         pcbNeeded = 0xdeadbeef;
1194         res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
1195         ok(res, "(%u) got %u with %u (expected '!=0')\n", level, res, GetLastError());
1196         ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1197
1198         /* validate the returned data here */
1199         if (level > 1) {
1200             LPDRIVER_INFO_2A di = (LPDRIVER_INFO_2A) buffer;
1201
1202             ok( strrchr(di->pDriverPath, '\\') != NULL,
1203                 "(%u) got %s for %s (expected a full path)\n",
1204                 level, di->pDriverPath, di->pName);
1205
1206         }
1207
1208         SetLastError(0xdeadbeef);
1209         pcReturned = 0xdeadbeef;
1210         pcbNeeded = 0xdeadbeef;
1211         res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1212         ok(res, "(%u) got %u with %u (expected '!=0')\n", level, res, GetLastError());
1213         ok(pcbNeeded == cbBuf, "(%u) returned %u (expected %u)\n", level, pcbNeeded, cbBuf);
1214
1215         SetLastError(0xdeadbeef);
1216         pcbNeeded = 0xdeadbeef;
1217         res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1218         ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1219             "(%u) got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1220             level, res, GetLastError());
1221         ok(pcbNeeded == cbBuf, "(%u) returned %u (expected %u)\n", level, pcbNeeded, cbBuf);
1222
1223 /*
1224       Do not add the next test:
1225       NT: ERROR_INVALID_USER_BUFFER
1226       win9x: crash or 100% CPU
1227
1228       res = EnumPrinterDriversA(NULL, NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1229 */
1230
1231         SetLastError(0xdeadbeef);
1232         pcbNeeded = 0xdeadbeef;
1233         pcReturned = 0xdeadbeef;
1234         res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, NULL, &pcReturned);
1235         ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
1236             "(%u) got %u with %u (expected '!=0' or '0' with "
1237             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1238
1239         pcbNeeded = 0xdeadbeef;
1240         pcReturned = 0xdeadbeef;
1241         SetLastError(0xdeadbeef);
1242         res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
1243         ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
1244             "(%u) got %u with %u (expected '!=0' or '0' with "
1245             "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1246
1247         HeapFree(GetProcessHeap(), 0, buffer);
1248     } /* for(level ... */
1249
1250     pcbNeeded = 0;
1251     pcReturned = 0;
1252     SetLastError(0xdeadbeef);
1253     res = EnumPrinterDriversA(NULL, env_all, 1, NULL, 0, &pcbNeeded, &pcReturned);
1254     if (res)
1255     {
1256         skip("no printer drivers found\n");
1257         return;
1258     }
1259     if (GetLastError() == ERROR_INVALID_ENVIRONMENT)
1260     {
1261         win_skip("NT4 and below don't support the 'all' environment value\n");
1262         return;
1263     }
1264     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "unexpected error %u\n", GetLastError());
1265
1266     buffer = HeapAlloc(GetProcessHeap(), 0, pcbNeeded);
1267     res = EnumPrinterDriversA(NULL, env_all, 1, buffer, pcbNeeded, &pcbNeeded, &pcReturned);
1268     ok(res, "EnumPrinterDriversA failed %u\n", GetLastError());
1269     if (res && pcReturned > 0)
1270     {
1271         DRIVER_INFO_1 *di_1 = (DRIVER_INFO_1 *)buffer;
1272         ok((LPBYTE) di_1->pName == NULL || (LPBYTE) di_1->pName < buffer ||
1273             (LPBYTE) di_1->pName >= (LPBYTE)(di_1 + pcReturned),
1274             "Driver Information not in sequence; pName %p, top of data %p\n",
1275             di_1->pName, di_1 + pcReturned);
1276     }
1277
1278     HeapFree(GetProcessHeap(), 0, buffer);
1279 }
1280
1281 /* ########################### */
1282
1283 static void test_EnumPrintProcessors(void)
1284 {
1285     DWORD   res;
1286     LPBYTE  buffer;
1287     DWORD   cbBuf;
1288     DWORD   pcbNeeded;
1289     DWORD   pcReturned;
1290
1291
1292     cbBuf = 0xdeadbeef;
1293     pcReturned = 0xdeadbeef;
1294     SetLastError(0xdeadbeef);
1295     res = EnumPrintProcessorsA(NULL, NULL, 1, NULL, 0, &cbBuf, &pcReturned);
1296     if (is_spooler_deactivated(res, GetLastError())) return;
1297
1298     if (res && !cbBuf) {
1299         skip("No Printprocessor installed\n");
1300         return;
1301     }
1302
1303     ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1304         "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1305         res, GetLastError());
1306
1307     buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4);
1308     if (buffer == NULL)
1309         return;
1310
1311     SetLastError(0xdeadbeef);
1312     pcbNeeded = 0xdeadbeef;
1313     res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1314     ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1315     /* validate the returned data here. */
1316
1317
1318     SetLastError(0xdeadbeef);
1319     pcReturned = 0xdeadbeef;
1320     pcbNeeded = 0xdeadbeef;
1321     res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1322     ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1323
1324     SetLastError(0xdeadbeef);
1325     pcbNeeded = 0xdeadbeef;
1326     res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1327     ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1328         "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1329         res, GetLastError());
1330
1331     /* only level 1 is valid */
1332     if (0) {
1333         /* both tests crash on win98se */
1334         SetLastError(0xdeadbeef);
1335         pcbNeeded = 0xdeadbeef;
1336         pcReturned = 0xdeadbeef;
1337         res = EnumPrintProcessorsA(NULL, NULL, 0, buffer, cbBuf, &pcbNeeded, &pcReturned);
1338         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1339             "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1340             res, GetLastError());
1341
1342         SetLastError(0xdeadbeef);
1343         pcbNeeded = 0xdeadbeef;
1344         res = EnumPrintProcessorsA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded, &pcReturned);
1345         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1346             "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1347             res, GetLastError());
1348     }
1349
1350     /* an empty environment is ignored */
1351     SetLastError(0xdeadbeef);
1352     pcbNeeded = 0xdeadbeef;
1353     res = EnumPrintProcessorsA(NULL, empty, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1354     ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1355
1356     /* the environment is checked */
1357     SetLastError(0xdeadbeef);
1358     pcbNeeded = 0xdeadbeef;
1359     res = EnumPrintProcessorsA(NULL, invalid_env, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1360     /* NT5: ERROR_INVALID_ENVIRONMENT, NT4: res != 0, 9x: ERROR_INVALID_PARAMETER */
1361     ok( broken(res) || /* NT4 */
1362         (GetLastError() == ERROR_INVALID_ENVIRONMENT) ||
1363         (GetLastError() == ERROR_INVALID_PARAMETER),
1364         "got %u with %u (expected '0' with ERROR_INVALID_ENVIRONMENT or "
1365         "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1366
1367
1368     /* failure-Codes for NULL */
1369     if (0) {
1370         /* this test crashes on win98se */
1371         SetLastError(0xdeadbeef);
1372         pcbNeeded = 0xdeadbeef;
1373         pcReturned = 0xdeadbeef;
1374         res = EnumPrintProcessorsA(NULL, NULL, 1, NULL, cbBuf, &pcbNeeded, &pcReturned);
1375         ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) ,
1376             "got %u with %u (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1377             res, GetLastError());
1378     }
1379
1380     SetLastError(0xdeadbeef);
1381     pcbNeeded = 0xdeadbeef;
1382     pcReturned = 0xdeadbeef;
1383     res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, NULL, &pcReturned);
1384     /* the NULL is ignored on win9x */
1385     ok( broken(res) || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)),
1386         "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1387         res, GetLastError());
1388
1389     pcbNeeded = 0xdeadbeef;
1390     pcReturned = 0xdeadbeef;
1391     SetLastError(0xdeadbeef);
1392     res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded, NULL);
1393     /* the NULL is ignored on win9x */
1394     ok( broken(res) || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)),
1395         "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1396         res, GetLastError());
1397
1398     HeapFree(GetProcessHeap(), 0, buffer);
1399
1400 }
1401
1402 /* ########################### */
1403
1404 static void test_GetDefaultPrinter(void)
1405 {
1406     BOOL    retval;
1407     DWORD   exact = DEFAULT_PRINTER_SIZE;
1408     DWORD   size;
1409     char    buffer[DEFAULT_PRINTER_SIZE];
1410
1411     if (!pGetDefaultPrinterA)  return;
1412         /* only supported on NT like OSes starting with win2k */
1413
1414     SetLastError(ERROR_SUCCESS);
1415     retval = pGetDefaultPrinterA(buffer, &exact);
1416     if (!retval || !exact || !strlen(buffer) ||
1417         (ERROR_SUCCESS != GetLastError())) {
1418         if ((ERROR_FILE_NOT_FOUND == GetLastError()) ||
1419             (ERROR_INVALID_NAME == GetLastError()))
1420             trace("this test requires a default printer to be set\n");
1421         else {
1422                 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
1423                 "function returned %s\n"
1424                 "last error 0x%08x\n"
1425                 "returned buffer size 0x%08x\n"
1426                 "returned buffer content %s\n",
1427                 retval ? "true" : "false", GetLastError(), exact, buffer);
1428         }
1429         return;
1430     }
1431     SetLastError(ERROR_SUCCESS);
1432     retval = pGetDefaultPrinterA(NULL, NULL); 
1433     ok( !retval, "function result wrong! False expected\n");
1434     ok( ERROR_INVALID_PARAMETER == GetLastError(),
1435         "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1436         GetLastError());
1437
1438     SetLastError(ERROR_SUCCESS);
1439     retval = pGetDefaultPrinterA(buffer, NULL); 
1440     ok( !retval, "function result wrong! False expected\n");
1441     ok( ERROR_INVALID_PARAMETER == GetLastError(),
1442         "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1443         GetLastError());
1444
1445     SetLastError(ERROR_SUCCESS);
1446     size = 0;
1447     retval = pGetDefaultPrinterA(NULL, &size); 
1448     ok( !retval, "function result wrong! False expected\n");
1449     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1450         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1451         GetLastError());
1452     ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1453         exact, size);
1454
1455     SetLastError(ERROR_SUCCESS);
1456     size = DEFAULT_PRINTER_SIZE;
1457     retval = pGetDefaultPrinterA(NULL, &size); 
1458     ok( !retval, "function result wrong! False expected\n");
1459     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1460         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1461         GetLastError());
1462     ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1463         exact, size);
1464
1465     size = 0;
1466     retval = pGetDefaultPrinterA(buffer, &size); 
1467     ok( !retval, "function result wrong! False expected\n");
1468     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1469         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1470         GetLastError());
1471     ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1472         exact, size);
1473
1474     size = exact;
1475     retval = pGetDefaultPrinterA(buffer, &size); 
1476     ok( retval, "function result wrong! True expected\n");
1477     ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1478         exact, size);
1479 }
1480
1481 static void test_GetPrinterDriverDirectory(void)
1482 {
1483     LPBYTE      buffer = NULL;
1484     DWORD       cbBuf = 0, pcbNeeded = 0;
1485     BOOL        res;
1486
1487
1488     SetLastError(MAGIC_DEAD);
1489     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
1490     if (is_spooler_deactivated(res, GetLastError())) return;
1491
1492     trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
1493           res, GetLastError(), cbBuf);
1494
1495     ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1496         "returned %d with lasterror=%d (expected '0' with "
1497         "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
1498
1499     if (!cbBuf) {
1500         skip("no valid buffer size returned\n");
1501         return;
1502     }
1503
1504     buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
1505     if (buffer == NULL)  return ;
1506
1507     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
1508     ok( res, "expected result != 0, got %d\n", res);
1509     ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1510                             pcbNeeded, cbBuf);
1511
1512     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1513     ok( res, "expected result != 0, got %d\n", res);
1514     ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1515                             pcbNeeded, cbBuf);
1516  
1517     SetLastError(MAGIC_DEAD);
1518     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
1519     ok( !res , "expected result == 0, got %d\n", res);
1520     ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1521                             pcbNeeded, cbBuf);
1522     
1523     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1524         "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
1525         GetLastError());
1526
1527 /*
1528     Do not add the next test:
1529     XPsp2: crash in this app, when the spooler is not running 
1530     NT3.5: ERROR_INVALID_USER_BUFFER
1531     win9x: ERROR_INVALID_PARAMETER
1532
1533     pcbNeeded = MAGIC_DEAD;
1534     SetLastError(MAGIC_DEAD);
1535     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1536 */
1537
1538     SetLastError(MAGIC_DEAD);
1539     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
1540     /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1541        NT: RPC_X_NULL_REF_POINTER  */
1542     ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER) ||
1543                (GetLastError() == ERROR_INVALID_PARAMETER),
1544         "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1545         "or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1546
1547     SetLastError(MAGIC_DEAD);
1548     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
1549     /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1550        NT: RPC_X_NULL_REF_POINTER  */
1551     ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER) ||
1552                (GetLastError() == ERROR_INVALID_PARAMETER),
1553         "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1554         "or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1555
1556     /* with a valid buffer, but level is too large */
1557     buffer[0] = '\0';
1558     SetLastError(MAGIC_DEAD);
1559     res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
1560
1561     /* Level not checked in win9x and wine:*/
1562     if((res != FALSE) && buffer[0])
1563     {
1564         trace("Level '2' not checked '%s'\n", buffer);
1565     }
1566     else
1567     {
1568         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1569         "returned %d with lasterror=%d (expected '0' with "
1570         "ERROR_INVALID_LEVEL)\n", res, GetLastError());
1571     }
1572
1573     /* printing environments are case insensitive */
1574     /* "Windows 4.0" is valid for win9x and NT */
1575     buffer[0] = '\0';
1576     SetLastError(MAGIC_DEAD);
1577     res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
1578                                         buffer, cbBuf*2, &pcbNeeded);
1579
1580     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
1581         cbBuf = pcbNeeded;
1582         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1583         if (buffer == NULL)  return ;
1584
1585         SetLastError(MAGIC_DEAD);
1586         res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
1587                                         buffer, cbBuf*2, &pcbNeeded);
1588     }
1589
1590     ok(res && buffer[0], "returned %d with "
1591         "lasterror=%d and len=%d (expected '1' with 'len > 0')\n", 
1592         res, GetLastError(), lstrlenA((char *)buffer));
1593
1594     buffer[0] = '\0';
1595     SetLastError(MAGIC_DEAD);
1596     res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
1597                                         buffer, cbBuf*2, &pcbNeeded);
1598
1599     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
1600         cbBuf = pcbNeeded;
1601         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1602         if (buffer == NULL)  return ;
1603
1604         buffer[0] = '\0';
1605         SetLastError(MAGIC_DEAD);
1606         res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
1607                                         buffer, cbBuf*2, &pcbNeeded);
1608     }
1609
1610     /* "Windows NT x86" is invalid for win9x */
1611     ok( (res && buffer[0]) ||
1612         (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 
1613         "returned %d with lasterror=%d and len=%d (expected '!= 0' with "
1614         "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
1615         res, GetLastError(), lstrlenA((char *)buffer));
1616
1617     /* A setup program (PDFCreator_0.8.0) use empty strings */
1618     SetLastError(MAGIC_DEAD);
1619     res = GetPrinterDriverDirectoryA(empty, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1620     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1621
1622     SetLastError(MAGIC_DEAD);
1623     res = GetPrinterDriverDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1624     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1625
1626     SetLastError(MAGIC_DEAD);
1627     res = GetPrinterDriverDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1628     ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1629
1630     HeapFree( GetProcessHeap(), 0, buffer);
1631 }
1632
1633 /* ##### */
1634
1635 static void test_GetPrintProcessorDirectory(void)
1636 {
1637     LPBYTE      buffer = NULL;
1638     DWORD       cbBuf = 0;
1639     DWORD       pcbNeeded = 0;
1640     BOOL        res;
1641
1642
1643     SetLastError(0xdeadbeef);
1644     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf);
1645     if (is_spooler_deactivated(res, GetLastError())) return;
1646
1647     ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1648         "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1649         res, GetLastError());
1650
1651     buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2);
1652     if(buffer == NULL)  return;
1653
1654     buffer[0] = '\0';
1655     SetLastError(0xdeadbeef);
1656     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
1657     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1658
1659     SetLastError(0xdeadbeef);
1660     buffer[0] = '\0';
1661     res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1662     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1663  
1664     /* Buffer to small */
1665     buffer[0] = '\0';
1666     SetLastError(0xdeadbeef);
1667     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
1668     ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1669         "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1670         res, GetLastError());
1671
1672     if (0)
1673     {
1674     /* XPsp2: the program will crash here, when the spooler is not running  */
1675     /*        GetPrinterDriverDirectory has the same bug */
1676     pcbNeeded = 0;
1677     SetLastError(0xdeadbeef);
1678     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1679     /* NT: ERROR_INVALID_USER_BUFFER, 9x: res != 0  */
1680     ok( (!res && (GetLastError() == ERROR_INVALID_USER_BUFFER)) ||
1681         broken(res),
1682         "returned %d with %d (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1683         res, GetLastError());
1684     }
1685
1686     buffer[0] = '\0';
1687     SetLastError(0xdeadbeef);
1688     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
1689     /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1690        NT: RPC_X_NULL_REF_POINTER, 9x: res != 0  */
1691     ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) ||
1692                  (GetLastError() == ERROR_INVALID_PARAMETER)),
1693         "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1694         "or with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1695
1696     buffer[0] = '\0';
1697     SetLastError(0xdeadbeef);
1698     res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
1699     /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1700        NT: RPC_X_NULL_REF_POINTER, 9x: res != 0  */
1701     ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) ||
1702                  (GetLastError() == ERROR_INVALID_PARAMETER)),
1703         "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1704         "or with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1705
1706     /* with a valid buffer, but level is invalid */
1707     buffer[0] = '\0';
1708     SetLastError(0xdeadbeef);
1709     res = GetPrintProcessorDirectoryA(NULL, NULL, 0, buffer, cbBuf, &pcbNeeded);
1710     /* Level is ignored in win9x*/
1711     ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1712         broken(res && buffer[0]),
1713         "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1714         res, GetLastError());
1715
1716     buffer[0] = '\0';
1717     SetLastError(0xdeadbeef);
1718     res = GetPrintProcessorDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
1719     /* Level is ignored on win9x*/
1720     ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1721         broken(res && buffer[0]),
1722         "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1723         res, GetLastError());
1724
1725     /* Empty environment is the same as the default environment */
1726     buffer[0] = '\0';
1727     SetLastError(0xdeadbeef);
1728     res = GetPrintProcessorDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1729     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1730
1731     /* "Windows 4.0" is valid for win9x and NT */
1732     buffer[0] = '\0';
1733     SetLastError(0xdeadbeef);
1734     res = GetPrintProcessorDirectoryA(NULL, env_win9x_case, 1, buffer, cbBuf*2, &pcbNeeded);
1735     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1736
1737
1738     /* "Windows NT x86" is invalid for win9x */
1739     buffer[0] = '\0';
1740     SetLastError(0xdeadbeef);
1741     res = GetPrintProcessorDirectoryA(NULL, env_x86, 1, buffer, cbBuf*2, &pcbNeeded);
1742     ok( res || (GetLastError() == ERROR_INVALID_ENVIRONMENT), 
1743         "returned %d with %d (expected '!= 0' or '0' with "
1744         "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
1745
1746     /* invalid on all systems */
1747     buffer[0] = '\0';
1748     SetLastError(0xdeadbeef);
1749     res = GetPrintProcessorDirectoryA(NULL, invalid_env, 1, buffer, cbBuf*2, &pcbNeeded);
1750     ok( !res && (GetLastError() == ERROR_INVALID_ENVIRONMENT), 
1751         "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
1752         res, GetLastError());
1753
1754     /* Empty servername is the same as the local computer */
1755     buffer[0] = '\0';
1756     SetLastError(0xdeadbeef);
1757     res = GetPrintProcessorDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1758     ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1759
1760     /* invalid on all systems */
1761     buffer[0] = '\0';
1762     SetLastError(0xdeadbeef);
1763     res = GetPrintProcessorDirectoryA(server_does_not_exist, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1764     ok( !res, "expected failure\n");
1765     ok( GetLastError() == RPC_S_SERVER_UNAVAILABLE || /* NT */
1766         GetLastError() == ERROR_INVALID_PARAMETER ||  /* 9x */
1767         GetLastError() == RPC_S_INVALID_NET_ADDR,     /* Some Vista */
1768         "unexpected last error %d\n", GetLastError());
1769
1770     HeapFree(GetProcessHeap(), 0, buffer);
1771 }
1772
1773 /* ##### */
1774
1775 static void test_OpenPrinter(void)
1776 {
1777     PRINTER_DEFAULTSA   defaults;
1778     HANDLE              hprinter;
1779     DWORD               res;
1780
1781     SetLastError(MAGIC_DEAD);
1782     res = OpenPrinter(NULL, NULL, NULL);
1783     if (is_spooler_deactivated(res, GetLastError())) return;
1784
1785     ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
1786         "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1787         res, GetLastError());
1788
1789
1790     /* Get Handle for the local Printserver (NT only)*/
1791     hprinter = (HANDLE) MAGIC_DEAD;
1792     SetLastError(MAGIC_DEAD);
1793     res = OpenPrinter(NULL, &hprinter, NULL);
1794     if (is_spooler_deactivated(res, GetLastError())) return;
1795     ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1796         "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1797         res, GetLastError());
1798     if(res) {
1799         ClosePrinter(hprinter);
1800
1801         defaults.pDatatype=NULL;
1802         defaults.pDevMode=NULL;
1803
1804         defaults.DesiredAccess=0;
1805         hprinter = (HANDLE) MAGIC_DEAD;
1806         SetLastError(MAGIC_DEAD);
1807         res = OpenPrinter(NULL, &hprinter, &defaults);
1808         ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1809         if (res) ClosePrinter(hprinter);
1810
1811         defaults.DesiredAccess=-1;
1812         hprinter = (HANDLE) MAGIC_DEAD;
1813         SetLastError(MAGIC_DEAD);
1814         res = OpenPrinter(NULL, &hprinter, &defaults);
1815         todo_wine {
1816         ok(!res && GetLastError() == ERROR_ACCESS_DENIED,
1817             "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n", 
1818             res, GetLastError());
1819         }
1820         if (res) ClosePrinter(hprinter);
1821
1822     }
1823
1824
1825     if (local_server != NULL) {
1826         hprinter = (HANDLE) 0xdeadbeef;
1827         SetLastError(0xdeadbeef);
1828         res = OpenPrinter(local_server, &hprinter, NULL);
1829         ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1830             "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1831             res, GetLastError());
1832         if(res) ClosePrinter(hprinter);
1833     }
1834
1835     /* Invalid Printername */
1836     hprinter = (HANDLE) MAGIC_DEAD;
1837     SetLastError(MAGIC_DEAD);
1838     res = OpenPrinter(illegal_name, &hprinter, NULL);
1839     ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
1840                 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1841        "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or"
1842        "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1843     if(res) ClosePrinter(hprinter);
1844
1845     hprinter = (HANDLE) MAGIC_DEAD;
1846     SetLastError(MAGIC_DEAD);
1847     res = OpenPrinter(empty, &hprinter, NULL);
1848     /* NT: ERROR_INVALID_PRINTER_NAME,  9x: ERROR_INVALID_PARAMETER */
1849     ok( !res &&
1850         ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
1851         (GetLastError() == ERROR_INVALID_PARAMETER) ),
1852         "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME"
1853         " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1854     if(res) ClosePrinter(hprinter);
1855
1856
1857     /* get handle for the default printer */
1858     if (default_printer)
1859     {
1860         hprinter = (HANDLE) MAGIC_DEAD;
1861         SetLastError(MAGIC_DEAD);
1862         res = OpenPrinter(default_printer, &hprinter, NULL);
1863         if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
1864         {
1865             trace("The service 'Spooler' is required for '%s'\n", default_printer);
1866             return;
1867         }
1868         ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1869         if(res) ClosePrinter(hprinter);
1870
1871         SetLastError(MAGIC_DEAD);
1872         res = OpenPrinter(default_printer, NULL, NULL);
1873         /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1874         ok(res || (GetLastError() == ERROR_INVALID_PARAMETER),
1875             "returned %d with %d (expected '!=0' or '0' with "
1876             "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1877
1878         defaults.pDatatype=NULL;
1879         defaults.pDevMode=NULL;
1880         defaults.DesiredAccess=0;
1881
1882         hprinter = (HANDLE) MAGIC_DEAD;
1883         SetLastError(MAGIC_DEAD);
1884         res = OpenPrinter(default_printer, &hprinter, &defaults);
1885         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1886             "returned %d with %d (expected '!=0' or '0' with "
1887             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1888         if(res) ClosePrinter(hprinter);
1889
1890         defaults.pDatatype = empty;
1891
1892         hprinter = (HANDLE) MAGIC_DEAD;
1893         SetLastError(MAGIC_DEAD);
1894         res = OpenPrinter(default_printer, &hprinter, &defaults);
1895         /* stop here, when a remote Printserver has no RPC-Service running */
1896         if (is_spooler_deactivated(res, GetLastError())) return;
1897         ok(res || ((GetLastError() == ERROR_INVALID_DATATYPE) ||
1898                    (GetLastError() == ERROR_ACCESS_DENIED)),
1899             "returned %d with %d (expected '!=0' or '0' with: "
1900             "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1901             res, GetLastError());
1902         if(res) ClosePrinter(hprinter);
1903
1904
1905         defaults.pDatatype=NULL;
1906         defaults.DesiredAccess=PRINTER_ACCESS_USE;
1907
1908         hprinter = (HANDLE) MAGIC_DEAD;
1909         SetLastError(MAGIC_DEAD);
1910         res = OpenPrinter(default_printer, &hprinter, &defaults);
1911         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1912             "returned %d with %d (expected '!=0' or '0' with "
1913             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1914         if(res) ClosePrinter(hprinter);
1915
1916
1917         defaults.DesiredAccess=PRINTER_ALL_ACCESS;
1918         hprinter = (HANDLE) MAGIC_DEAD;
1919         SetLastError(MAGIC_DEAD);
1920         res = OpenPrinter(default_printer, &hprinter, &defaults);
1921         ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1922             "returned %d with %d (expected '!=0' or '0' with "
1923             "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1924         if(res) ClosePrinter(hprinter);
1925     }
1926
1927 }
1928
1929
1930 static void test_SetDefaultPrinter(void)
1931 {
1932     DWORD   res;
1933     DWORD   size = DEFAULT_PRINTER_SIZE;
1934     CHAR    buffer[DEFAULT_PRINTER_SIZE];
1935     CHAR    org_value[DEFAULT_PRINTER_SIZE];
1936
1937     if (!default_printer)
1938     {
1939         skip("There is no default printer installed\n");
1940         return;
1941     }
1942
1943     if (!pSetDefaultPrinterA)  return;
1944         /* only supported on win2k and above */
1945
1946     /* backup the original value */
1947     org_value[0] = '\0';
1948     SetLastError(MAGIC_DEAD);
1949     res = GetProfileStringA("windows", "device", NULL, org_value, size);
1950     ok(res, "GetProfileString error %d\n", GetLastError());
1951
1952     /* first part: with the default Printer */
1953     SetLastError(MAGIC_DEAD);
1954     res = pSetDefaultPrinterA("no_printer_with_this_name");
1955     if (is_spooler_deactivated(res, GetLastError())) return;
1956
1957     /* Not implemented in wine */
1958     if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
1959         trace("SetDefaultPrinterA() not implemented yet.\n");
1960         return;
1961     }
1962
1963     ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1964         "returned %d with %d (expected '0' with "
1965         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1966
1967     WriteProfileStringA("windows", "device", org_value);
1968     SetLastError(MAGIC_DEAD);
1969     res = pSetDefaultPrinterA("");
1970     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1971         "returned %d with %d (expected '!=0' or '0' with "
1972         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1973
1974     WriteProfileStringA("windows", "device", org_value);
1975     SetLastError(MAGIC_DEAD);
1976     res = pSetDefaultPrinterA(NULL);
1977     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1978         "returned %d with %d (expected '!=0' or '0' with "
1979         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1980
1981     WriteProfileStringA("windows", "device", org_value);
1982     SetLastError(MAGIC_DEAD);
1983     res = pSetDefaultPrinterA(default_printer);
1984     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1985         "returned %d with %d (expected '!=0' or '0' with "
1986         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1987
1988
1989     /* second part: always without a default Printer */
1990     WriteProfileStringA("windows", "device", NULL);    
1991     SetLastError(MAGIC_DEAD);
1992     res = pSetDefaultPrinterA("no_printer_with_this_name");
1993
1994     ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1995         "returned %d with %d (expected '0' with "
1996         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1997
1998     WriteProfileStringA("windows", "device", NULL);    
1999     SetLastError(MAGIC_DEAD);
2000     res = pSetDefaultPrinterA("");
2001     if (is_spooler_deactivated(res, GetLastError()))
2002         goto restore_old_printer;
2003
2004     /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2005     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
2006          "returned %d with %d (expected '!=0' or '0' with "
2007          "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2008
2009     WriteProfileStringA("windows", "device", NULL);    
2010     SetLastError(MAGIC_DEAD);
2011     res = pSetDefaultPrinterA(NULL);
2012     /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2013     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
2014         "returned %d with %d (expected '!=0' or '0' with "
2015         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2016
2017     WriteProfileStringA("windows", "device", NULL);    
2018     SetLastError(MAGIC_DEAD);
2019     res = pSetDefaultPrinterA(default_printer);
2020     ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
2021         "returned %d with %d (expected '!=0' or '0' with "
2022         "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2023
2024     /* restore the original value */
2025 restore_old_printer:
2026     res = pSetDefaultPrinterA(default_printer);          /* the nice way */
2027     ok(res, "SetDefaultPrinter error %d\n", GetLastError());
2028     WriteProfileStringA("windows", "device", org_value); /* the old way */
2029
2030     buffer[0] = '\0';
2031     SetLastError(MAGIC_DEAD);
2032     res = GetProfileStringA("windows", "device", NULL, buffer, size);
2033     ok(res, "GetProfileString error %d\n", GetLastError());
2034     ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value);
2035
2036 }
2037
2038 /* ########################### */
2039
2040 static void test_XcvDataW_MonitorUI(void)
2041 {
2042     DWORD   res;
2043     HANDLE  hXcv;
2044     BYTE    buffer[MAX_PATH + 4];
2045     DWORD   needed;
2046     DWORD   status;
2047     DWORD   len;
2048     PRINTER_DEFAULTSA pd;
2049
2050     /* api is not present before w2k */
2051     if (pXcvDataW == NULL) return;
2052
2053     pd.pDatatype = NULL;
2054     pd.pDevMode  = NULL;
2055     pd.DesiredAccess = SERVER_ACCESS_ADMINISTER;
2056
2057     hXcv = NULL;
2058     SetLastError(0xdeadbeef);
2059     res = OpenPrinter(xcv_localport, &hXcv, &pd);
2060     if (is_spooler_deactivated(res, GetLastError())) return;
2061     if (is_access_denied(res, GetLastError())) return;
2062
2063     ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv);
2064     if (!res) return;
2065
2066     /* ask for needed size */
2067     needed = (DWORD) 0xdeadbeef;
2068     status = (DWORD) 0xdeadbeef;
2069     SetLastError(0xdeadbeef);
2070     res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, NULL, 0, &needed, &status);
2071     ok( res && (status == ERROR_INSUFFICIENT_BUFFER) && (needed <= MAX_PATH),
2072         "returned %d with %u and %u for status %u (expected '!= 0' and "
2073         "'<= MAX_PATH' for status ERROR_INSUFFICIENT_BUFFER)\n",
2074         res, GetLastError(), needed, status);
2075
2076     if (needed > MAX_PATH) {
2077         ClosePrinter(hXcv);
2078         skip("buffer overflow (%u)\n", needed);
2079         return;
2080     }
2081     len = needed;       /* Size is in bytes */
2082
2083     /* the command is required */
2084     needed = (DWORD) 0xdeadbeef;
2085     status = (DWORD) 0xdeadbeef;
2086     SetLastError(0xdeadbeef);
2087     res = pXcvDataW(hXcv, emptyW, NULL, 0, NULL, 0, &needed, &status);
2088     ok( res && (status == ERROR_INVALID_PARAMETER),
2089         "returned %d with %u and %u for status %u (expected '!= 0' with "
2090         "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), needed, status);
2091
2092     needed = (DWORD) 0xdeadbeef;
2093     status = (DWORD) 0xdeadbeef;
2094     SetLastError(0xdeadbeef);
2095     res = pXcvDataW(hXcv, NULL, NULL, 0, buffer, MAX_PATH, &needed, &status);
2096     ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER),
2097         "returned %d with %u and %u for status %u (expected '0' with "
2098         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2099
2100     /* "PDWORD needed" is checked before RPC-Errors */
2101     needed = (DWORD) 0xdeadbeef;
2102     status = (DWORD) 0xdeadbeef;
2103     SetLastError(0xdeadbeef);
2104     res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, NULL, &status);
2105     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
2106         "returned %d with %u and %u for status %u (expected '0' with "
2107         "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), needed, status);
2108
2109     needed = (DWORD) 0xdeadbeef;
2110     status = (DWORD) 0xdeadbeef;
2111     SetLastError(0xdeadbeef);
2112     res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, NULL, len, &needed, &status);
2113     ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER),
2114         "returned %d with %u and %u for status %u (expected '0' with "
2115         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2116
2117     needed = (DWORD) 0xdeadbeef;
2118     status = (DWORD) 0xdeadbeef;
2119     SetLastError(0xdeadbeef);
2120     res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, &needed, NULL);
2121     ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER),
2122         "returned %d with %u and %u for status %u (expected '0' with "
2123         "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2124
2125     /* off by one: larger  */
2126     needed = (DWORD) 0xdeadbeef;
2127     status = (DWORD) 0xdeadbeef;
2128     SetLastError(0xdeadbeef);
2129     res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len+1, &needed, &status);
2130     ok( res && (status == ERROR_SUCCESS),
2131         "returned %d with %u and %u for status %u (expected '!= 0' for status "
2132         "ERROR_SUCCESS)\n", res, GetLastError(), needed, status);
2133
2134     /* off by one: smaller */
2135     /* the buffer is not modified for NT4, w2k, XP */
2136     needed = (DWORD) 0xdeadbeef;
2137     status = (DWORD) 0xdeadbeef;
2138     SetLastError(0xdeadbeef);
2139     res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len-1, &needed, &status);
2140     ok( res && (status == ERROR_INSUFFICIENT_BUFFER),
2141         "returned %d with %u and %u for status %u (expected '!= 0' for status "
2142         "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError(), needed, status);
2143
2144
2145     /* Normal use. The DLL-Name without a Path is returned */
2146     memset(buffer, 0, len);
2147     needed = (DWORD) 0xdeadbeef;
2148     status = (DWORD) 0xdeadbeef;
2149     SetLastError(0xdeadbeef);
2150     res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, &needed, &status);
2151     ok( res && (status == ERROR_SUCCESS),
2152         "returned %d with %u and %u for status %u (expected '!= 0' for status "
2153         "ERROR_SUCCESS)\n", res, GetLastError(), needed, status);
2154
2155     ClosePrinter(hXcv);
2156 }
2157
2158 /* ########################### */
2159
2160 static void test_XcvDataW_PortIsValid(void)
2161 {
2162     DWORD   res;
2163     HANDLE  hXcv;
2164     DWORD   needed;
2165     DWORD   status;
2166     PRINTER_DEFAULTSA   pd;
2167
2168     /* api is not present before w2k */
2169     if (pXcvDataW == NULL) return;
2170
2171     pd.pDatatype = NULL;
2172     pd.pDevMode  = NULL;
2173     pd.DesiredAccess = SERVER_ACCESS_ADMINISTER;
2174
2175     hXcv = NULL;
2176     SetLastError(0xdeadbeef);
2177     res = OpenPrinter(xcv_localport, &hXcv, &pd);
2178     if (is_spooler_deactivated(res, GetLastError())) return;
2179     if (is_access_denied(res, GetLastError())) return;
2180
2181     ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv);
2182     if (!res) return;
2183
2184
2185     /* "PDWORD needed" is always required */
2186     needed = (DWORD) 0xdeadbeef;
2187     status = (DWORD) 0xdeadbeef;
2188     SetLastError(0xdeadbeef);
2189     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt1W, sizeof(portname_lpt1W), NULL, 0, NULL, &status);
2190     ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
2191         "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_INVALID_PARAMETER)\n",
2192          res, GetLastError(), needed, status);
2193
2194     /* an empty name is not allowed */
2195     needed = (DWORD) 0xdeadbeef;
2196     status = (DWORD) 0xdeadbeef;
2197     SetLastError(0xdeadbeef);
2198     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) emptyW, sizeof(emptyW), NULL, 0, &needed, &status);
2199     ok( res && ((status == ERROR_FILE_NOT_FOUND) || (status == ERROR_PATH_NOT_FOUND)),
2200         "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2201         "ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND)\n",
2202         res, GetLastError(), needed, status);
2203
2204     /* a directory is not allowed */
2205     needed = (DWORD) 0xdeadbeef;
2206     status = (DWORD) 0xdeadbeef;
2207     SetLastError(0xdeadbeef);
2208     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) tempdirW, (lstrlenW(tempdirW) + 1) * sizeof(WCHAR), NULL, 0, &needed, &status);
2209     /* XP: ERROR_PATH_NOT_FOUND, w2k ERROR_ACCESS_DENIED */
2210     ok( res && ((status == ERROR_PATH_NOT_FOUND) || (status == ERROR_ACCESS_DENIED)),
2211         "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2212         "ERROR_PATH_NOT_FOUND or ERROR_ACCESS_DENIED)\n",
2213         res, GetLastError(), needed, status);
2214
2215     /* more valid well known ports */
2216     needed = (DWORD) 0xdeadbeef;
2217     status = (DWORD) 0xdeadbeef;
2218     SetLastError(0xdeadbeef);
2219     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt1W, sizeof(portname_lpt1W), NULL, 0, &needed, &status);
2220     ok( res && (status == ERROR_SUCCESS),
2221         "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2222         res, GetLastError(), needed, status);
2223
2224     needed = (DWORD) 0xdeadbeef;
2225     status = (DWORD) 0xdeadbeef;
2226     SetLastError(0xdeadbeef);
2227     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt2W, sizeof(portname_lpt2W), NULL, 0, &needed, &status);
2228     ok( res && (status == ERROR_SUCCESS),
2229         "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2230         res, GetLastError(), needed, status);
2231
2232     needed = (DWORD) 0xdeadbeef;
2233     status = (DWORD) 0xdeadbeef;
2234     SetLastError(0xdeadbeef);
2235     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_com1W, sizeof(portname_com1W), NULL, 0, &needed, &status);
2236     ok( res && (status == ERROR_SUCCESS),
2237         "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2238         res, GetLastError(), needed, status);
2239
2240     needed = (DWORD) 0xdeadbeef;
2241     status = (DWORD) 0xdeadbeef;
2242     SetLastError(0xdeadbeef);
2243     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_com2W, sizeof(portname_com2W), NULL, 0, &needed, &status);
2244     ok( res && (status == ERROR_SUCCESS),
2245         "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2246         res, GetLastError(), needed, status);
2247
2248     needed = (DWORD) 0xdeadbeef;
2249     status = (DWORD) 0xdeadbeef;
2250     SetLastError(0xdeadbeef);
2251     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_fileW, sizeof(portname_fileW), NULL, 0, &needed, &status);
2252     ok( res && (status == ERROR_SUCCESS),
2253         "returned %d with %u and %u for status %u (expected '!= 0' with  ERROR_SUCCESS)\n",
2254         res, GetLastError(), needed, status);
2255
2256
2257     /* a normal, writable file is allowed */
2258     needed = (DWORD) 0xdeadbeef;
2259     status = (DWORD) 0xdeadbeef;
2260     SetLastError(0xdeadbeef);
2261     res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) tempfileW, (lstrlenW(tempfileW) + 1) * sizeof(WCHAR), NULL, 0, &needed, &status);
2262     ok( res && (status == ERROR_SUCCESS),
2263         "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2264         res, GetLastError(), needed, status);
2265
2266     ClosePrinter(hXcv);
2267 }
2268
2269 /* ########################### */
2270
2271 static void test_GetPrinter(void)
2272 {
2273     HANDLE hprn;
2274     BOOL ret;
2275     BYTE *buf;
2276     INT level;
2277     DWORD needed, filled;
2278
2279     if (!default_printer)
2280     {
2281         skip("There is no default printer installed\n");
2282         return;
2283     }
2284
2285     hprn = 0;
2286     ret = OpenPrinter(default_printer, &hprn, NULL);
2287     if (!ret)
2288     {
2289         skip("Unable to open the default printer (%s)\n", default_printer);
2290         return;
2291     }
2292     ok(hprn != 0, "wrong hprn %p\n", hprn);
2293
2294     for (level = 1; level <= 9; level++)
2295     {
2296         SetLastError(0xdeadbeef);
2297         needed = (DWORD)-1;
2298         ret = GetPrinter(hprn, level, NULL, 0, &needed);
2299         if (ret)
2300         {
2301             win_skip("Level %d is not supported on Win9x/WinMe\n", level);
2302             ok(GetLastError() == ERROR_SUCCESS, "wrong error %d\n", GetLastError());
2303             ok(needed == 0,"Expected 0, got %d\n", needed);
2304             continue;
2305         }
2306         ok(!ret, "level %d: GetPrinter should fail\n", level);
2307         /* Not all levels are supported on all Windows-Versions */
2308         if (GetLastError() == ERROR_INVALID_LEVEL ||
2309             GetLastError() == ERROR_NOT_SUPPORTED /* Win9x/WinMe */)
2310         {
2311             skip("Level %d not supported\n", level);
2312             continue;
2313         }
2314         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
2315         ok(needed > 0,"not expected needed buffer size %d\n", needed);
2316
2317         /* GetPrinterA returns the same number of bytes as GetPrinterW */
2318         if (!on_win9x && !ret && pGetPrinterW && level != 6 && level != 7)
2319         {
2320             DWORD double_needed;
2321             ret = pGetPrinterW(hprn, level, NULL, 0, &double_needed);
2322             ok(!ret, "level %d: GetPrinter error %d\n", level, GetLastError());
2323             ok(double_needed == needed, "level %d: GetPrinterA returned different size %d than GetPrinterW (%d)\n", level, needed, double_needed);
2324         }
2325
2326         buf = HeapAlloc(GetProcessHeap(), 0, needed);
2327
2328         SetLastError(0xdeadbeef);
2329         filled = -1;
2330         ret = GetPrinter(hprn, level, buf, needed, &filled);
2331         ok(ret, "level %d: GetPrinter error %d\n", level, GetLastError());
2332         ok(needed == filled, "needed %d != filled %d\n", needed, filled);
2333
2334         if (level == 2)
2335         {
2336             PRINTER_INFO_2 *pi_2 = (PRINTER_INFO_2 *)buf;
2337
2338             ok(pi_2->pPrinterName!= NULL, "not expected NULL ptr\n");
2339             ok(pi_2->pDriverName!= NULL, "not expected NULL ptr\n");
2340
2341             trace("pPrinterName %s\n", pi_2->pPrinterName);
2342             trace("pDriverName %s\n", pi_2->pDriverName);
2343         }
2344
2345         HeapFree(GetProcessHeap(), 0, buf);
2346     }
2347
2348     SetLastError(0xdeadbeef);
2349     ret = ClosePrinter(hprn);
2350     ok(ret, "ClosePrinter error %d\n", GetLastError());
2351 }
2352
2353 /* ########################### */
2354
2355 static void test_GetPrinterData(void)
2356 {
2357     HANDLE hprn = 0;
2358     DWORD res;
2359     DWORD type;
2360     CHAR  buffer[MAX_PATH + 1];
2361     DWORD needed;
2362     DWORD len;
2363
2364     /* ToDo: test parameter validation, test with the default printer */
2365
2366     SetLastError(0xdeadbeef);
2367     res = OpenPrinter(NULL, &hprn, NULL);
2368     if (!res)
2369     {
2370         /* printserver not available on win9x */
2371         if (!on_win9x)
2372             win_skip("Unable to open the printserver: %d\n", GetLastError());
2373         return;
2374     }
2375
2376     memset(buffer, '#', sizeof(buffer));
2377     buffer[MAX_PATH] = 0;
2378     type = 0xdeadbeef;
2379     needed = 0xdeadbeef;
2380     SetLastError(0xdeadbeef);
2381     res = GetPrinterDataA(hprn, defaultspooldirectory, &type, (LPBYTE) buffer, sizeof(buffer), &needed);
2382
2383     len = lstrlenA(buffer) + sizeof(CHAR);
2384     /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2385     ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2386         "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2387         res, type, needed, buffer, len);
2388
2389     needed = 0xdeadbeef;
2390     SetLastError(0xdeadbeef);
2391     res = GetPrinterDataA(hprn, defaultspooldirectory, NULL, NULL, 0, &needed);
2392     ok( (res == ERROR_MORE_DATA) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2393         "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2394
2395     /* ToDo: test SPLREG_*  */
2396
2397     SetLastError(0xdeadbeef);
2398     res = ClosePrinter(hprn);
2399     ok(res, "ClosePrinter error %d\n", GetLastError());
2400 }
2401
2402 /* ########################### */
2403
2404 static void test_GetPrinterDataEx(void)
2405 {
2406     HANDLE hprn = 0;
2407     DWORD res;
2408     DWORD type;
2409     CHAR  buffer[MAX_PATH + 1];
2410     DWORD needed;
2411     DWORD len;
2412
2413     /* not present before w2k */
2414     if (!pGetPrinterDataExA) {
2415         win_skip("GetPrinterDataEx not found\n");
2416         return;
2417     }
2418
2419     /* ToDo: test parameter validation, test with the default printer */
2420
2421     SetLastError(0xdeadbeef);
2422     res = OpenPrinter(NULL, &hprn, NULL);
2423     if (!res)
2424     {
2425         win_skip("Unable to open the printserver: %d\n", GetLastError());
2426         return;
2427     }
2428
2429     /* keyname is ignored, when hprn is a HANDLE for a printserver */
2430     memset(buffer, '#', sizeof(buffer));
2431     buffer[MAX_PATH] = 0;
2432     type = 0xdeadbeef;
2433     needed = 0xdeadbeef;
2434     SetLastError(0xdeadbeef);
2435     res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, &type,
2436                              (LPBYTE) buffer, sizeof(buffer), &needed);
2437
2438     len = lstrlenA(buffer) + sizeof(CHAR);
2439     /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2440     ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2441         "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2442         res, type, needed, buffer, len);
2443
2444     memset(buffer, '#', sizeof(buffer));
2445     buffer[MAX_PATH] = 0;
2446     type = 0xdeadbeef;
2447     needed = 0xdeadbeef;
2448     SetLastError(0xdeadbeef);
2449     res = pGetPrinterDataExA(hprn, "", defaultspooldirectory, &type,
2450                              (LPBYTE) buffer, sizeof(buffer), &needed);
2451     len = lstrlenA(buffer) + sizeof(CHAR);
2452     ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2453         "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2454         res, type, needed, buffer, len);
2455
2456     memset(buffer, '#', sizeof(buffer));
2457     buffer[MAX_PATH] = 0;
2458     type = 0xdeadbeef;
2459     needed = 0xdeadbeef;
2460     SetLastError(0xdeadbeef);
2461     /* Wine uses GetPrinterDataEx with "PrinterDriverData" to implement GetPrinterData */
2462     res = pGetPrinterDataExA(hprn, "PrinterDriverData", defaultspooldirectory,
2463                              &type, (LPBYTE) buffer, sizeof(buffer), &needed);
2464     len = lstrlenA(buffer) + sizeof(CHAR);
2465     ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2466         "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2467         res, type, needed, buffer, len);
2468
2469
2470     memset(buffer, '#', sizeof(buffer));
2471     buffer[MAX_PATH] = 0;
2472     type = 0xdeadbeef;
2473     needed = 0xdeadbeef;
2474     SetLastError(0xdeadbeef);
2475     res = pGetPrinterDataExA(hprn, does_not_exist, defaultspooldirectory, &type,
2476                              (LPBYTE) buffer, sizeof(buffer), &needed);
2477     len = lstrlenA(buffer) + sizeof(CHAR);
2478     ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2479         "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2480         res, type, needed, buffer, len);
2481
2482     needed = 0xdeadbeef;
2483     SetLastError(0xdeadbeef);
2484     /* vista and w2k8 have a bug in GetPrinterDataEx:
2485        the current LastError value is returned as result */
2486     res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, NULL, NULL, 0, &needed);
2487     ok( ((res == ERROR_MORE_DATA) || broken(res == 0xdeadbeef)) &&
2488         ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2489         "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2490
2491     needed = 0xdeadbeef;
2492     SetLastError(0xdeaddead);
2493     res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, NULL, NULL, 0, &needed);
2494     ok( ((res == ERROR_MORE_DATA) || broken(res == 0xdeaddead)) &&
2495         ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2496         "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2497
2498     SetLastError(0xdeadbeef);
2499     res = ClosePrinter(hprn);
2500     ok(res, "ClosePrinter error %d\n", GetLastError());
2501 }
2502
2503 /* ########################### */
2504
2505 static void test_GetPrinterDriver(void)
2506 {
2507     HANDLE hprn;
2508     BOOL ret;
2509     BYTE *buf;
2510     INT level;
2511     DWORD needed, filled;
2512
2513     if (!default_printer)
2514     {
2515         skip("There is no default printer installed\n");
2516         return;
2517     }
2518
2519     hprn = 0;
2520     ret = OpenPrinter(default_printer, &hprn, NULL);
2521     if (!ret)
2522     {
2523         skip("Unable to open the default printer (%s)\n", default_printer);
2524         return;
2525     }
2526     ok(hprn != 0, "wrong hprn %p\n", hprn);
2527
2528     for (level = -1; level <= 7; level++)
2529     {
2530         SetLastError(0xdeadbeef);
2531         needed = (DWORD)-1;
2532         ret = GetPrinterDriver(hprn, NULL, level, NULL, 0, &needed);
2533         ok(!ret, "level %d: GetPrinterDriver should fail\n", level);
2534         if (level >= 1 && level <= 6)
2535         {
2536             /* Not all levels are supported on all Windows-Versions */
2537             if(GetLastError() == ERROR_INVALID_LEVEL) continue;
2538             ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
2539             ok(needed > 0,"not expected needed buffer size %d\n", needed);
2540         }
2541         else
2542         {
2543             /* ERROR_OUTOFMEMORY found on win9x */
2544             ok( ((GetLastError() == ERROR_INVALID_LEVEL) ||
2545                  (GetLastError() == ERROR_OUTOFMEMORY)),
2546                 "%d: returned %d with %d (expected '0' with: "
2547                 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
2548                 level, ret, GetLastError());
2549             /* needed is modified in win9x. The modified Value depends on the
2550                default Printer. testing for "needed == (DWORD)-1" will fail */
2551             continue;
2552         }
2553
2554         /* GetPrinterDriverA returns the same number of bytes as GetPrinterDriverW */
2555         if (!on_win9x && !ret && pGetPrinterDriverW)
2556         {
2557             DWORD double_needed;
2558             ret = pGetPrinterDriverW(hprn, NULL, level, NULL, 0, &double_needed);
2559             ok(!ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
2560             ok(double_needed == needed, "GetPrinterDriverA returned different size %d than GetPrinterDriverW (%d)\n", needed, double_needed);
2561         }
2562
2563         buf = HeapAlloc(GetProcessHeap(), 0, needed);
2564
2565         SetLastError(0xdeadbeef);
2566         filled = -1;
2567         ret = GetPrinterDriver(hprn, NULL, level, buf, needed, &filled);
2568         ok(ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
2569         ok(needed == filled, "needed %d != filled %d\n", needed, filled);
2570
2571         if (level == 2)
2572         {
2573             DRIVER_INFO_2 *di_2 = (DRIVER_INFO_2 *)buf;
2574             DWORD calculated = sizeof(*di_2);
2575             HANDLE hf;
2576
2577             /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
2578                NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k-win7(Usermode): 3, win8 and above(Usermode): 4 */
2579             ok( (di_2->cVersion <= 4) ||
2580                 (di_2->cVersion == 0x0400), "di_2->cVersion = %d\n", di_2->cVersion);
2581             ok(di_2->pName != NULL, "not expected NULL ptr\n");
2582             ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n");
2583             ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n");
2584             ok(di_2->pDataFile != NULL, "not expected NULL ptr\n");
2585             ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n");
2586
2587             trace("cVersion %d\n", di_2->cVersion);
2588             trace("pName %s\n", di_2->pName);
2589             calculated += strlen(di_2->pName) + 1;
2590             trace("pEnvironment %s\n", di_2->pEnvironment);
2591             calculated += strlen(di_2->pEnvironment) + 1;
2592             trace("pDriverPath %s\n", di_2->pDriverPath);
2593             calculated += strlen(di_2->pDriverPath) + 1;
2594             trace("pDataFile %s\n", di_2->pDataFile);
2595             calculated += strlen(di_2->pDataFile) + 1;
2596             trace("pConfigFile %s\n", di_2->pConfigFile);
2597             calculated += strlen(di_2->pConfigFile) + 1;
2598
2599             hf = CreateFileA(di_2->pDriverPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2600             if(hf != INVALID_HANDLE_VALUE)
2601                 CloseHandle(hf);
2602             todo_wine
2603             ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pDriverPath);
2604
2605             hf = CreateFileA(di_2->pDataFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2606             if(hf != INVALID_HANDLE_VALUE)
2607                 CloseHandle(hf);
2608             ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pDataFile);
2609
2610             hf = CreateFileA(di_2->pConfigFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2611             if(hf != INVALID_HANDLE_VALUE)
2612                 CloseHandle(hf);
2613             todo_wine
2614             ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pConfigFile);
2615
2616             /* XP allocates memory for both ANSI and unicode names */
2617             ok(filled >= calculated,"calculated %d != filled %d\n", calculated, filled);
2618
2619             /* Obscure test - demonstrate that Windows zero fills the buffer, even on failure */
2620             ret = GetPrinterDriver(hprn, NULL, level, buf, needed - 2, &filled);
2621             ok(!ret, "level %d: GetPrinterDriver succeeded with less buffer than it should\n", level);
2622             ok(di_2->pDataFile == NULL ||
2623                broken(di_2->pDataFile != NULL), /* Win9x/WinMe */
2624                "Even on failure, GetPrinterDriver clears the buffer to zeros\n");
2625         }
2626
2627         HeapFree(GetProcessHeap(), 0, buf);
2628     }
2629
2630     SetLastError(0xdeadbeef);
2631     ret = ClosePrinter(hprn);
2632     ok(ret, "ClosePrinter error %d\n", GetLastError());
2633 }
2634
2635 static void test_DEVMODE(const DEVMODE *dm, LONG dmSize, LPCSTR exp_prn_name)
2636 {
2637     /* On NT3.51, some fields in DEVMODE are empty/zero
2638       (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
2639        We skip the Tests on this Platform */
2640     if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) {
2641     /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
2642         ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1) ||
2643            !strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -2), /* XP+ */
2644             "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName);
2645         ok(dm->dmSize + dm->dmDriverExtra == dmSize,
2646             "%u != %d\n", dm->dmSize + dm->dmDriverExtra, dmSize);
2647     }
2648     trace("dmFields %08x\n", dm->dmFields);
2649 }
2650
2651 static void test_DocumentProperties(void)
2652 {
2653     HANDLE hprn;
2654     LONG dm_size, ret;
2655     DEVMODE *dm;
2656     char empty_str[] = "";
2657
2658     if (!default_printer)
2659     {
2660         skip("There is no default printer installed\n");
2661         return;
2662     }
2663
2664     hprn = 0;
2665     ret = OpenPrinter(default_printer, &hprn, NULL);
2666     if (!ret)
2667     {
2668         skip("Unable to open the default printer (%s)\n", default_printer);
2669         return;
2670     }
2671     ok(hprn != 0, "wrong hprn %p\n", hprn);
2672
2673     dm_size = DocumentProperties(0, hprn, NULL, NULL, NULL, 0);
2674     trace("DEVMODE required size %d\n", dm_size);
2675     ok(dm_size >= sizeof(DEVMODE), "unexpected DocumentProperties ret value %d\n", dm_size);
2676
2677     dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
2678
2679     ret = DocumentProperties(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
2680     ok(ret == IDOK, "DocumentProperties ret value %d != expected IDOK\n", ret);
2681
2682     ret = DocumentProperties(0, hprn, empty_str, dm, dm, DM_OUT_BUFFER);
2683     ok(ret == IDOK, "DocumentProperties ret value %d != expected IDOK\n", ret);
2684
2685     test_DEVMODE(dm, dm_size, default_printer);
2686
2687     HeapFree(GetProcessHeap(), 0, dm);
2688
2689     SetLastError(0xdeadbeef);
2690     ret = ClosePrinter(hprn);
2691     ok(ret, "ClosePrinter error %d\n", GetLastError());
2692 }
2693
2694 static void test_EnumPrinters(void)
2695 {
2696     DWORD neededA, neededW, num;
2697     DWORD ret;
2698
2699     SetLastError(0xdeadbeef);
2700     neededA = -1;
2701     ret = EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededA, &num);
2702     if (is_spooler_deactivated(ret, GetLastError())) return;
2703     if (!ret)
2704     {
2705         /* We have 1 or more printers */
2706         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "gle %d\n", GetLastError());
2707         ok(neededA > 0, "Expected neededA to show the number of needed bytes\n");
2708     }
2709     else
2710     {
2711         /* We don't have any printers defined */
2712         ok(GetLastError() == S_OK, "gle %d\n", GetLastError());
2713         ok(neededA == 0, "Expected neededA to be zero\n");
2714     }
2715     ok(num == 0, "num %d\n", num);
2716
2717     SetLastError(0xdeadbeef);
2718     neededW = -1;
2719     ret = EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededW, &num);
2720     /* EnumPrintersW is not supported on all platforms */
2721     if (!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2722     {
2723         win_skip("EnumPrintersW is not implemented\n");
2724         return;
2725     }
2726
2727     if (!ret)
2728     {
2729         /* We have 1 or more printers */
2730         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "gle %d\n", GetLastError());
2731         ok(neededW > 0, "Expected neededW to show the number of needed bytes\n");
2732     }
2733     else
2734     {
2735         /* We don't have any printers defined */
2736         ok(GetLastError() == S_OK, "gle %d\n", GetLastError());
2737         ok(neededW == 0, "Expected neededW to be zero\n");
2738     }
2739     ok(num == 0, "num %d\n", num);
2740
2741     /* Outlook2003 relies on the buffer size returned by EnumPrintersA being big enough
2742        to hold the buffer returned by EnumPrintersW */
2743     ok(neededA == neededW, "neededA %d neededW %d\n", neededA, neededW);
2744 }
2745
2746 static void test_DeviceCapabilities(void)
2747 {
2748     HANDLE hComdlg32;
2749     BOOL (WINAPI *pPrintDlgA)(PRINTDLGA *);
2750     PRINTDLGA prn_dlg;
2751     DEVMODE *dm;
2752     DEVNAMES *dn;
2753     const char *driver, *device, *port;
2754     WORD *papers;
2755     POINT *paper_size;
2756     POINTS ext;
2757     struct
2758     {
2759         char name[64];
2760     } *paper_name;
2761     INT n_papers, n_paper_size, n_paper_names, n_copies, ret;
2762     DWORD fields;
2763
2764     hComdlg32 = LoadLibrary("comdlg32.dll");
2765     assert(hComdlg32);
2766     pPrintDlgA = (void *)GetProcAddress(hComdlg32, "PrintDlgA");
2767     assert(pPrintDlgA);
2768
2769     memset(&prn_dlg, 0, sizeof(prn_dlg));
2770     prn_dlg.lStructSize = sizeof(prn_dlg);
2771     prn_dlg.Flags = PD_RETURNDEFAULT;
2772     ret = pPrintDlgA(&prn_dlg);
2773     FreeLibrary(hComdlg32);
2774     if (!ret)
2775     {
2776         skip("PrintDlg returned no default printer\n");
2777         return;
2778     }
2779     ok(prn_dlg.hDevMode != 0, "PrintDlg returned hDevMode == NULL\n");
2780     ok(prn_dlg.hDevNames != 0, "PrintDlg returned hDevNames == NULL\n");
2781
2782     dm = GlobalLock(prn_dlg.hDevMode);
2783     ok(dm != NULL, "GlobalLock(prn_dlg.hDevMode) failed\n");
2784     trace("dmDeviceName \"%s\"\n", dm->dmDeviceName);
2785
2786     dn = GlobalLock(prn_dlg.hDevNames);
2787     ok(dn != NULL, "GlobalLock(prn_dlg.hDevNames) failed\n");
2788     ok(dn->wDriverOffset, "expected not 0 wDriverOffset\n");
2789     ok(dn->wDeviceOffset, "expected not 0 wDeviceOffset\n");
2790     ok(dn->wOutputOffset, "expected not 0 wOutputOffset\n");
2791     ok(dn->wDefault == DN_DEFAULTPRN, "expected DN_DEFAULTPRN got %x\n", dn->wDefault);
2792     driver = (const char *)dn + dn->wDriverOffset;
2793     device = (const char *)dn + dn->wDeviceOffset;
2794     port = (const char *)dn + dn->wOutputOffset;
2795     trace("driver \"%s\" device \"%s\" port \"%s\"\n", driver, device, port);
2796
2797     test_DEVMODE(dm, dm->dmSize + dm->dmDriverExtra, device);
2798
2799     n_papers = DeviceCapabilities(device, port, DC_PAPERS, NULL, NULL);
2800     ok(n_papers > 0, "DeviceCapabilities DC_PAPERS failed\n");
2801     papers = HeapAlloc(GetProcessHeap(), 0, sizeof(*papers) * n_papers);
2802     ret = DeviceCapabilities(device, port, DC_PAPERS, (LPSTR)papers, NULL);
2803     ok(ret == n_papers, "expected %d, got %d\n", n_papers, ret);
2804 #ifdef VERBOSE
2805     for (ret = 0; ret < n_papers; ret++)
2806         trace("papers[%d] = %d\n", ret, papers[ret]);
2807 #endif
2808     HeapFree(GetProcessHeap(), 0, papers);
2809
2810     n_paper_size = DeviceCapabilities(device, port, DC_PAPERSIZE, NULL, NULL);
2811     ok(n_paper_size > 0, "DeviceCapabilities DC_PAPERSIZE failed\n");
2812     ok(n_paper_size == n_papers, "n_paper_size %d != n_papers %d\n", n_paper_size, n_papers);
2813     paper_size = HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_size) * n_paper_size);
2814     ret = DeviceCapabilities(device, port, DC_PAPERSIZE, (LPSTR)paper_size, NULL);
2815     ok(ret == n_paper_size, "expected %d, got %d\n", n_paper_size, ret);
2816 #ifdef VERBOSE
2817     for (ret = 0; ret < n_paper_size; ret++)
2818         trace("paper_size[%d] = %d x %d\n", ret, paper_size[ret].x, paper_size[ret].y);
2819 #endif
2820     HeapFree(GetProcessHeap(), 0, paper_size);
2821
2822     n_paper_names = DeviceCapabilities(device, port, DC_PAPERNAMES, NULL, NULL);
2823     ok(n_paper_names > 0, "DeviceCapabilities DC_PAPERNAMES failed\n");
2824     ok(n_paper_names == n_papers, "n_paper_names %d != n_papers %d\n", n_paper_names, n_papers);
2825     paper_name = HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_name) * n_paper_names);
2826     ret = DeviceCapabilities(device, port, DC_PAPERNAMES, (LPSTR)paper_name, NULL);
2827     ok(ret == n_paper_names, "expected %d, got %d\n", n_paper_names, ret);
2828 #ifdef VERBOSE
2829     for (ret = 0; ret < n_paper_names; ret++)
2830         trace("paper_name[%u] = %s\n", ret, paper_name[ret].name);
2831 #endif
2832     HeapFree(GetProcessHeap(), 0, paper_name);
2833
2834     n_copies = DeviceCapabilities(device, port, DC_COPIES, NULL, dm);
2835     ok(n_copies > 0, "DeviceCapabilities DC_COPIES failed\n");
2836     trace("n_copies = %d\n", n_copies);
2837
2838     /* these capabilities are not available on all printer drivers */
2839     if (0)
2840     {
2841         ret = DeviceCapabilities(device, port, DC_MAXEXTENT, NULL, NULL);
2842         ok(ret != -1, "DeviceCapabilities DC_MAXEXTENT failed\n");
2843         ext = MAKEPOINTS(ret);
2844         trace("max ext = %d x %d\n", ext.x, ext.y);
2845
2846         ret = DeviceCapabilities(device, port, DC_MINEXTENT, NULL, NULL);
2847         ok(ret != -1, "DeviceCapabilities DC_MINEXTENT failed\n");
2848         ext = MAKEPOINTS(ret);
2849         trace("min ext = %d x %d\n", ext.x, ext.y);
2850     }
2851
2852     fields = DeviceCapabilities(device, port, DC_FIELDS, NULL, NULL);
2853     ok(fields != (DWORD)-1, "DeviceCapabilities DC_FIELDS failed\n");
2854     ok(fields == (dm->dmFields | DM_FORMNAME) ||
2855        fields == ((dm->dmFields | DM_FORMNAME | DM_PAPERSIZE) & ~(DM_PAPERLENGTH|DM_PAPERWIDTH)) ||
2856         broken(fields == dm->dmFields), /* Win9x/WinMe */
2857         "fields %x, dm->dmFields %x\n", fields, dm->dmFields);
2858
2859     GlobalUnlock(prn_dlg.hDevMode);
2860     GlobalFree(prn_dlg.hDevMode);
2861     GlobalUnlock(prn_dlg.hDevNames);
2862     GlobalFree(prn_dlg.hDevNames);
2863 }
2864
2865 static void test_IsValidDevmodeW(void)
2866 {
2867     BOOL br;
2868
2869     if (!pIsValidDevmodeW)
2870     {
2871         win_skip("IsValidDevmodeW not implemented.\n");
2872         return;
2873     }
2874
2875     br = pIsValidDevmodeW(NULL, 0);
2876     ok(br == FALSE, "Got %d\n", br);
2877
2878     br = pIsValidDevmodeW(NULL, 1);
2879     ok(br == FALSE, "Got %d\n", br);
2880
2881     br = pIsValidDevmodeW(NULL, sizeof(DEVMODEW));
2882     ok(br == FALSE, "Got %d\n", br);
2883 }
2884
2885 static void test_OpenPrinter_defaults(void)
2886 {
2887     HANDLE printer;
2888     BOOL ret;
2889     DWORD needed;
2890     short default_size;
2891     ADDJOB_INFO_1 *add_job;
2892     JOB_INFO_2 *job_info;
2893     DEVMODE my_dm;
2894     PRINTER_DEFAULTS prn_def;
2895     PRINTER_INFO_2 *pi;
2896
2897     if (!default_printer)
2898     {
2899         skip("There is no default printer installed\n");
2900         return;
2901     }
2902
2903     /* Printer opened with NULL defaults.  Retrieve default paper size
2904        and confirm that jobs have this size. */
2905
2906     ret = OpenPrinter( default_printer, &printer, NULL );
2907     if (!ret)
2908     {
2909         skip("Unable to open the default printer (%s)\n", default_printer);
2910         return;
2911     }
2912
2913     ret = GetPrinter( printer, 2, NULL, 0, &needed );
2914     ok( !ret, "got %d\n", ret );
2915     pi = HeapAlloc( GetProcessHeap(), 0, needed );
2916     ret = GetPrinter( printer, 2, (BYTE *)pi, needed, &needed );
2917     ok( ret, "got %d\n", ret );
2918     default_size = pi->pDevMode->u1.s1.dmPaperSize;
2919     HeapFree( GetProcessHeap(), 0, pi );
2920
2921     ret = AddJob( printer, 1, NULL, 0, &needed );
2922     ok( !ret, "got %d\n", ret );
2923     add_job = HeapAlloc( GetProcessHeap(), 0, needed );
2924     ret = AddJob( printer, 1, (BYTE *)add_job, needed, &needed );
2925     ok( ret, "got %d\n", ret );
2926
2927     ret = GetJob( printer, add_job->JobId, 2, NULL, 0, &needed );
2928     ok( !ret, "got %d\n", ret );
2929     job_info = HeapAlloc( GetProcessHeap(), 0, needed );
2930     ret = GetJob( printer, add_job->JobId, 2, (BYTE *)job_info, needed, &needed );
2931     ok( ret, "got %d\n", ret );
2932
2933 todo_wine
2934     ok( job_info->pDevMode != NULL, "got NULL devmode\n");
2935     if (job_info->pDevMode)
2936         ok( job_info->pDevMode->u1.s1.dmPaperSize == default_size, "got %d default %d\n",
2937             job_info->pDevMode->u1.s1.dmPaperSize, default_size );
2938
2939     HeapFree( GetProcessHeap(), 0, job_info );
2940     ScheduleJob( printer, add_job->JobId ); /* remove the empty job */
2941     HeapFree( GetProcessHeap(), 0, add_job );
2942     ClosePrinter( printer );
2943
2944     /* Printer opened with something other than the default paper size. */
2945
2946     memset( &my_dm, 0, sizeof(my_dm) );
2947     my_dm.dmSize = sizeof(my_dm);
2948     my_dm.dmFields = DM_PAPERSIZE;
2949     my_dm.u1.s1.dmPaperSize = (default_size == DMPAPER_A4) ? DMPAPER_LETTER : DMPAPER_A4;
2950
2951     prn_def.pDatatype = NULL;
2952     prn_def.pDevMode = &my_dm;
2953     prn_def.DesiredAccess = PRINTER_ACCESS_USE;
2954
2955     ret = OpenPrinter( default_printer, &printer, &prn_def );
2956     ok( ret, "got %d\n", ret );
2957
2958     /* GetPrinter stills returns default size */
2959     ret = GetPrinter( printer, 2, NULL, 0, &needed );
2960     ok( !ret, "got %d\n", ret );
2961     pi = HeapAlloc( GetProcessHeap(), 0, needed );
2962     ret = GetPrinter( printer, 2, (BYTE *)pi, needed, &needed );
2963     ok( ret, "got %d\n", ret );
2964     ok( pi->pDevMode->u1.s1.dmPaperSize == default_size, "got %d default %d\n",
2965         pi->pDevMode->u1.s1.dmPaperSize, default_size );
2966
2967     HeapFree( GetProcessHeap(), 0, pi );
2968
2969     /* However the GetJob has the new size */
2970     ret = AddJob( printer, 1, NULL, 0, &needed );
2971     ok( !ret, "got %d\n", ret );
2972     add_job = HeapAlloc( GetProcessHeap(), 0, needed );
2973     ret = AddJob( printer, 1, (BYTE *)add_job, needed, &needed );
2974     ok( ret, "got %d\n", ret );
2975
2976     ret = GetJob( printer, add_job->JobId, 2, NULL, 0, &needed );
2977     ok( !ret, "got %d\n", ret );
2978     job_info = HeapAlloc( GetProcessHeap(), 0, needed );
2979     ret = GetJob( printer, add_job->JobId, 2, (BYTE *)job_info, needed, &needed );
2980     ok( ret, "got %d\n", ret );
2981
2982     ok( job_info->pDevMode->dmFields == DM_PAPERSIZE, "got %08x\n",
2983         job_info->pDevMode->dmFields );
2984     ok( job_info->pDevMode->u1.s1.dmPaperSize == my_dm.u1.s1.dmPaperSize,
2985         "got %d new size %d\n",
2986         job_info->pDevMode->u1.s1.dmPaperSize, my_dm.u1.s1.dmPaperSize );
2987
2988     HeapFree( GetProcessHeap(), 0, job_info );
2989     ScheduleJob( printer, add_job->JobId ); /* remove the empty job */
2990     HeapFree( GetProcessHeap(), 0, add_job );
2991     ClosePrinter( printer );
2992 }
2993
2994 START_TEST(info)
2995 {
2996     hwinspool = LoadLibrary("winspool.drv");
2997     pAddPortExA = (void *) GetProcAddress(hwinspool, "AddPortExA");
2998     pEnumPrinterDriversW = (void *) GetProcAddress(hwinspool, "EnumPrinterDriversW");
2999     pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
3000     pGetPrinterDataExA = (void *) GetProcAddress(hwinspool, "GetPrinterDataExA");
3001     pGetPrinterDriverW = (void *) GetProcAddress(hwinspool, "GetPrinterDriverW");
3002     pGetPrinterW = (void *) GetProcAddress(hwinspool, "GetPrinterW");
3003     pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
3004     pXcvDataW = (void *) GetProcAddress(hwinspool, "XcvDataW");
3005     pIsValidDevmodeW = (void *) GetProcAddress(hwinspool, "IsValidDevmodeW");
3006
3007     on_win9x = check_win9x();
3008     if (on_win9x)
3009         win_skip("Several W-functions are not available on Win9x/WinMe\n");
3010
3011     find_default_printer();
3012     find_local_server();
3013     find_tempfile();
3014
3015     test_AddMonitor();
3016     test_AddPort();
3017     test_AddPortEx();
3018     test_ConfigurePort();
3019     test_DeleteMonitor();
3020     test_DeletePort();
3021     test_DeviceCapabilities();
3022     test_DocumentProperties();
3023     test_EnumForms(NULL);
3024     if (default_printer) test_EnumForms(default_printer);
3025     test_EnumMonitors();
3026     test_EnumPorts();
3027     test_EnumPrinterDrivers();
3028     test_EnumPrinters();
3029     test_EnumPrintProcessors();
3030     test_GetDefaultPrinter();
3031     test_GetPrinterDriverDirectory();
3032     test_GetPrintProcessorDirectory();
3033     test_OpenPrinter();
3034     test_GetPrinter();
3035     test_GetPrinterData();
3036     test_GetPrinterDataEx();
3037     test_GetPrinterDriver();
3038     test_SetDefaultPrinter();
3039     test_XcvDataW_MonitorUI();
3040     test_XcvDataW_PortIsValid();
3041     test_IsValidDevmodeW();
3042     test_OpenPrinter_defaults();
3043
3044     /* Cleanup our temporary file */
3045     DeleteFileA(tempfileA);
3046 }