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