2 * Copyright (C) 2003, 2004 Stefan Leichter
3 * Copyright (C) 2005, 2006 Detlef Riekenberg
4 * Copyright (C) 2006 Dmitry Timoshkov
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.
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.
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
24 #define NONAMELESSSTRUCT
25 #define NONAMELESSUNION
36 #include "wine/test.h"
38 #define MAGIC_DEAD 0xdeadbeef
39 #define DEFAULT_PRINTER_SIZE 1000
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";
59 static const WCHAR cmd_MonitorUIW
[] = {'M','o','n','i','t','o','r','U','I',0};
60 static const WCHAR cmd_PortIsValidW
[] = {'P','o','r','t','I','s','V','a','l','i','d',0};
61 static WCHAR emptyW
[] = {0};
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};
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
);
81 /* ################################ */
83 struct monitor_entry
{
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
;
95 static BOOL
is_spooler_deactivated(DWORD res
, DWORD lasterror
)
97 if (!res
&& lasterror
== RPC_S_SERVER_UNAVAILABLE
)
99 static int deactivated_spooler_reported
= 0;
100 if (!deactivated_spooler_reported
)
102 deactivated_spooler_reported
= 1;
103 skip("The service 'Spooler' is required for many tests\n");
110 static BOOL
is_access_denied(DWORD res
, DWORD lasterror
)
112 if (!res
&& lasterror
== ERROR_ACCESS_DENIED
)
114 static int access_denied_reported
= 0;
115 if (!access_denied_reported
)
117 access_denied_reported
= 1;
118 skip("More access rights are required for many tests\n");
125 static BOOL on_win9x
= FALSE
;
127 static BOOL
check_win9x(void)
131 SetLastError(0xdeadbeef);
132 pGetPrinterW(NULL
, 0, NULL
, 0, NULL
);
133 return (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
);
141 static void find_default_printer(VOID
)
143 static char buffer
[DEFAULT_PRINTER_SIZE
];
148 if ((default_printer
== NULL
) && (pGetDefaultPrinterA
))
151 needed
= sizeof(buffer
);
152 res
= pGetDefaultPrinterA(buffer
, &needed
);
153 if(res
) default_printer
= buffer
;
154 trace("default_printer: '%s'\n", default_printer
? default_printer
: "(null)");
156 if (default_printer
== NULL
)
160 /* NT 3.x and above */
161 if (RegOpenKeyExA(HKEY_CURRENT_USER
,
162 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
163 0, KEY_QUERY_VALUE
, &hwindows
) == NO_ERROR
) {
165 needed
= sizeof(buffer
);
166 if (RegQueryValueExA(hwindows
, "device", NULL
, &type
, (LPBYTE
)buffer
, &needed
) == NO_ERROR
) {
167 ptr
= strchr(buffer
, ',');
170 default_printer
= buffer
;
173 RegCloseKey(hwindows
);
175 trace("default_printer: '%s'\n", default_printer
? default_printer
: "(null)");
177 if (default_printer
== NULL
)
180 needed
= sizeof(buffer
);
181 res
= GetProfileStringA("windows", "device", "*", buffer
, needed
);
183 ptr
= strchr(buffer
, ',');
186 default_printer
= buffer
;
189 trace("default_printer: '%s'\n", default_printer
? default_printer
: "(null)");
194 static struct monitor_entry
* find_installed_monitor(void)
196 MONITOR_INFO_2A mi2a
;
197 static struct monitor_entry
* entry
= NULL
;
201 static struct monitor_entry monitor_table
[] = {
202 {env_win9x_case
, "localspl.dll"},
203 {env_x86
, "localspl.dll"},
204 {env_x64
, "localspl.dll"},
205 {env_win9x_case
, "localmon.dll"},
206 {env_x86
, "localmon.dll"},
207 {env_win9x_case
, "tcpmon.dll"},
208 {env_x86
, "tcpmon.dll"},
209 {env_win9x_case
, "usbmon.dll"},
210 {env_x86
, "usbmon.dll"},
211 {env_win9x_case
, "mspp32.dll"},
212 {env_x86
, "win32spl.dll"},
213 {env_x86
, "redmonnt.dll"},
214 {env_x86
, "redmon35.dll"},
215 {env_win9x_case
, "redmon95.dll"},
216 {env_x86
, "pdfcmnnt.dll"},
217 {env_win9x_case
, "pdfcmn95.dll"},
220 if (entry
) return entry
;
222 num_tests
= (sizeof(monitor_table
)/sizeof(struct monitor_entry
));
225 DeleteMonitorA(NULL
, env_x64
, winetest
);
226 DeleteMonitorA(NULL
, env_x86
, winetest
);
227 DeleteMonitorA(NULL
, env_win9x_case
, winetest
);
229 /* find a usable monitor from the table */
230 mi2a
.pName
= winetest
;
231 while ((entry
== NULL
) && (i
< num_tests
)) {
232 entry
= &monitor_table
[i
];
234 mi2a
.pEnvironment
= entry
->env
;
235 mi2a
.pDLLName
= entry
->dllname
;
237 if (AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
)) {
239 trace("using '%s', '%s'\n", entry
->env
, entry
->dllname
);
240 DeleteMonitorA(NULL
, entry
->env
, winetest
);
251 /* ########################### */
253 static void find_local_server(VOID
)
255 static char buffer
[MAX_PATH
];
259 size
= sizeof(buffer
) - 3 ;
264 SetLastError(0xdeadbeef);
265 res
= GetComputerNameA(&buffer
[2], &size
);
266 trace("returned %d with %d and %d: '%s'\n", res
, GetLastError(), size
, buffer
);
268 ok( res
!= 0, "returned %d with %d and %d: '%s' (expected '!= 0')\n",
269 res
, GetLastError(), size
, buffer
);
271 if (res
) local_server
= buffer
;
274 /* ########################### */
276 static void find_tempfile(VOID
)
278 static CHAR buffer_dirA
[MAX_PATH
];
279 static CHAR buffer_fileA
[MAX_PATH
];
280 static WCHAR buffer_dirW
[MAX_PATH
];
281 static WCHAR buffer_fileW
[MAX_PATH
];
285 memset(buffer_dirA
, 0, MAX_PATH
- 1);
286 buffer_dirA
[MAX_PATH
- 1] = '\0';
287 SetLastError(0xdeadbeef);
288 res
= GetTempPathA(MAX_PATH
, buffer_dirA
);
289 ok(res
, "returned %u with %u and '%s' (expected '!= 0')\n", res
, GetLastError(), buffer_dirA
);
290 if (res
== 0) return;
292 memset(buffer_fileA
, 0, MAX_PATH
- 1);
293 buffer_fileA
[MAX_PATH
- 1] = '\0';
294 SetLastError(0xdeadbeef);
295 res
= GetTempFileNameA(buffer_dirA
, winetest
, 0, buffer_fileA
);
296 ok(res
, "returned %u with %u and '%s' (expected '!= 0')\n", res
, GetLastError(), buffer_fileA
);
297 if (res
== 0) return;
299 SetLastError(0xdeadbeef);
300 resint
= MultiByteToWideChar(CP_ACP
, 0, buffer_dirA
, -1, buffer_dirW
, MAX_PATH
);
301 ok(res
, "returned %u with %u (expected '!= 0')\n", resint
, GetLastError());
302 if (resint
== 0) return;
304 SetLastError(0xdeadbeef);
305 resint
= MultiByteToWideChar(CP_ACP
, 0, buffer_fileA
, -1, buffer_fileW
, MAX_PATH
);
306 ok(res
, "returned %u with %u (expected '!= 0')\n", resint
, GetLastError());
307 if (resint
== 0) return;
309 tempdirA
= buffer_dirA
;
310 tempfileA
= buffer_fileA
;
311 tempdirW
= buffer_dirW
;
312 tempfileW
= buffer_fileW
;
313 trace("tempfile: '%s'\n", tempfileA
);
316 /* ########################### */
318 static void test_AddMonitor(void)
320 MONITOR_INFO_2A mi2a
;
321 struct monitor_entry
* entry
= NULL
;
324 entry
= find_installed_monitor();
326 SetLastError(MAGIC_DEAD
);
327 res
= AddMonitorA(NULL
, 1, NULL
);
328 ok(!res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
329 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
330 res
, GetLastError());
332 SetLastError(MAGIC_DEAD
);
333 res
= AddMonitorA(NULL
, 3, NULL
);
334 ok(!res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
335 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
336 res
, GetLastError());
340 /* This test crashes win9x on vmware (works with win9x on qemu 0.8.1) */
341 SetLastError(MAGIC_DEAD
);
342 res
= AddMonitorA(NULL
, 2, NULL
);
343 /* NT: unchanged, 9x: ERROR_PRIVILEGE_NOT_HELD */
345 ((GetLastError() == MAGIC_DEAD
) ||
346 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD
)),
347 "returned %d with %d (expected '0' with: MAGIC_DEAD or "
348 "ERROR_PRIVILEGE_NOT_HELD)\n", res
, GetLastError());
351 ZeroMemory(&mi2a
, sizeof(MONITOR_INFO_2A
));
352 SetLastError(MAGIC_DEAD
);
353 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
354 if (is_spooler_deactivated(res
, GetLastError())) return;
355 if (is_access_denied(res
, GetLastError())) return;
357 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_INVALID_ENVIRONMENT */
358 ok(!res
&& ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
359 (GetLastError() == ERROR_INVALID_ENVIRONMENT
)),
360 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
361 "ERROR_INVALID_ENVIRONMENT)\n", res
, GetLastError());
364 skip("No usable Monitor found\n");
370 /* The test is deactivated, because when mi2a.pName is NULL, the subkey
371 HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM
372 or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì
373 is created on win9x and we do not want to hit this bug here. */
375 mi2a
.pEnvironment
= entry
->env
;
376 SetLastError(MAGIC_DEAD
);
377 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
378 ok(res
, "AddMonitor error %d\n", GetLastError());
379 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
382 mi2a
.pEnvironment
= entry
->env
;
384 SetLastError(MAGIC_DEAD
);
385 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
386 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
388 ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
389 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD
)),
390 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
391 "ERROR_PRIVILEGE_NOT_HELD)\n",
392 res
, GetLastError());
394 mi2a
.pName
= winetest
;
395 SetLastError(MAGIC_DEAD
);
396 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
397 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
399 ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
400 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD
)),
401 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
402 "ERROR_PRIVILEGE_NOT_HELD)\n",
403 res
, GetLastError());
405 mi2a
.pDLLName
= empty
;
406 SetLastError(MAGIC_DEAD
);
407 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
408 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
409 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
410 res
, GetLastError());
412 mi2a
.pDLLName
= does_not_exist_dll
;
413 SetLastError(MAGIC_DEAD
);
414 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
415 /* NT: ERROR_MOD_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
417 ((GetLastError() == ERROR_MOD_NOT_FOUND
) ||
418 (GetLastError() == ERROR_INVALID_PARAMETER
)),
419 "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or "
420 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
422 mi2a
.pDLLName
= version_dll
;
423 SetLastError(MAGIC_DEAD
);
424 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
425 /* NT: ERROR_PROC_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
427 ((GetLastError() == ERROR_PROC_NOT_FOUND
) ||
428 (GetLastError() == ERROR_INVALID_PARAMETER
)),
429 "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or "
430 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
431 if (res
) DeleteMonitorA(NULL
, entry
->env
, winetest
);
433 /* Test AddMonitor with real options */
434 mi2a
.pDLLName
= entry
->dllname
;
435 SetLastError(MAGIC_DEAD
);
436 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
437 /* Some apps depend on the result of GetLastError() also on success of AddMonitor */
438 ok(res
&& (GetLastError() == ERROR_SUCCESS
),
439 "returned %d with %d (expected '!= 0' with ERROR_SUCCESS)\n", res
, GetLastError());
441 /* add a monitor twice */
442 SetLastError(MAGIC_DEAD
);
443 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
444 /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */
446 ((GetLastError() == ERROR_PRINT_MONITOR_ALREADY_INSTALLED
) ||
447 (GetLastError() == ERROR_ALREADY_EXISTS
)),
448 "returned %d with %d (expected '0' with: "
449 "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n",
450 res
, GetLastError());
452 DeleteMonitorA(NULL
, entry
->env
, winetest
);
453 SetLastError(MAGIC_DEAD
);
454 res
= AddMonitorA(empty
, 2, (LPBYTE
) &mi2a
);
455 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
458 DeleteMonitorA(NULL
, entry
->env
, winetest
);
462 /* ########################### */
464 static void test_AddPort(void)
468 SetLastError(0xdeadbeef);
469 res
= AddPortA(NULL
, 0, NULL
);
470 if (is_spooler_deactivated(res
, GetLastError())) return;
471 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
472 ok( !res
&& ((GetLastError() == RPC_X_NULL_REF_POINTER
) ||
473 (GetLastError() == ERROR_INVALID_PARAMETER
)),
474 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
475 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
478 SetLastError(0xdeadbeef);
479 res
= AddPortA(NULL
, 0, empty
);
480 /* Allowed only for (Printer-)Administrators */
481 if (is_access_denied(res
, GetLastError())) return;
483 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
484 ok( !res
&& ((GetLastError() == ERROR_NOT_SUPPORTED
) ||
485 (GetLastError() == ERROR_INVALID_PARAMETER
)),
486 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
487 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
490 SetLastError(0xdeadbeef);
491 res
= AddPortA(NULL
, 0, does_not_exist
);
492 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
493 ok( !res
&& ((GetLastError() == ERROR_NOT_SUPPORTED
) ||
494 (GetLastError() == ERROR_INVALID_PARAMETER
)),
495 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
496 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
500 /* ########################### */
502 static void test_AddPortEx(void)
509 win_skip("AddPortEx not supported\n");
513 /* start test with a clean system */
514 DeletePortA(NULL
, 0, tempfileA
);
516 pi
.pPortName
= tempfileA
;
517 SetLastError(0xdeadbeef);
518 res
= pAddPortExA(NULL
, 1, (LPBYTE
) &pi
, LocalPortA
);
519 if (is_spooler_deactivated(res
, GetLastError())) return;
521 /* Allowed only for (Printer-)Administrators.
522 W2K+XP: ERROR_INVALID_PARAMETER */
523 if (!res
&& (GetLastError() == ERROR_INVALID_PARAMETER
)) {
524 skip("ACCESS_DENIED (ERROR_INVALID_PARAMETER)\n");
527 ok( res
, "got %u with %u (expected '!= 0')\n", res
, GetLastError());
529 /* add a port that already exists */
530 SetLastError(0xdeadbeef);
531 res
= pAddPortExA(NULL
, 1, (LPBYTE
) &pi
, LocalPortA
);
532 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
533 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
534 res
, GetLastError());
535 DeletePortA(NULL
, 0, tempfileA
);
538 /* the Monitorname must match */
539 SetLastError(0xdeadbeef);
540 res
= pAddPortExA(NULL
, 1, (LPBYTE
) &pi
, NULL
);
541 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
542 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
543 res
, GetLastError());
544 if (res
) DeletePortA(NULL
, 0, tempfileA
);
546 SetLastError(0xdeadbeef);
547 res
= pAddPortExA(NULL
, 1, (LPBYTE
) &pi
, empty
);
548 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
549 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
550 res
, GetLastError());
551 if (res
) DeletePortA(NULL
, 0, tempfileA
);
553 SetLastError(0xdeadbeef);
554 res
= pAddPortExA(NULL
, 1, (LPBYTE
) &pi
, does_not_exist
);
555 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
556 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
557 res
, GetLastError());
558 if (res
) DeletePortA(NULL
, 0, tempfileA
);
561 /* We need a Portname */
562 SetLastError(0xdeadbeef);
563 res
= pAddPortExA(NULL
, 1, NULL
, LocalPortA
);
564 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
565 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
566 res
, GetLastError());
569 SetLastError(0xdeadbeef);
570 res
= pAddPortExA(NULL
, 1, (LPBYTE
) &pi
, LocalPortA
);
571 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
572 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
573 res
, GetLastError());
574 if (res
) DeletePortA(NULL
, 0, tempfileA
);
577 /* level 2 is documented as supported for Printmonitors,
578 but that is not supported for "Local Port" (localspl.dll) and
579 AddPortEx fails with ERROR_INVALID_LEVEL */
581 pi
.pPortName
= tempfileA
;
582 pi
.pMonitorName
= LocalPortA
;
583 pi
.pDescription
= winetest
;
584 pi
.fPortType
= PORT_TYPE_WRITE
;
586 SetLastError(0xdeadbeef);
587 res
= pAddPortExA(NULL
, 2, (LPBYTE
) &pi
, LocalPortA
);
588 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
589 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
590 res
, GetLastError());
591 if (res
) DeletePortA(NULL
, 0, tempfileA
);
595 SetLastError(0xdeadbeef);
596 res
= pAddPortExA(NULL
, 0, (LPBYTE
) &pi
, LocalPortA
);
597 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
598 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
599 res
, GetLastError());
601 SetLastError(0xdeadbeef);
602 res
= pAddPortExA(NULL
, 3, (LPBYTE
) &pi
, LocalPortA
);
603 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
604 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
605 res
, GetLastError());
609 DeletePortA(NULL
, 0, tempfileA
);
613 /* ########################### */
615 static void test_ConfigurePort(void)
620 SetLastError(0xdeadbeef);
621 res
= ConfigurePortA(NULL
, 0, NULL
);
622 if (is_spooler_deactivated(res
, GetLastError())) return;
623 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
624 ok( !res
&& ((GetLastError() == RPC_X_NULL_REF_POINTER
) ||
625 (GetLastError() == ERROR_INVALID_PARAMETER
)),
626 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
627 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
629 SetLastError(0xdeadbeef);
630 res
= ConfigurePortA(NULL
, 0, empty
);
631 /* Allowed only for (Printer-)Administrators */
632 if (is_access_denied(res
, GetLastError())) return;
634 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
635 ok( !res
&& ((GetLastError() == ERROR_NOT_SUPPORTED
) ||
636 (GetLastError() == ERROR_INVALID_PARAMETER
)),
637 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
638 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
641 SetLastError(0xdeadbeef);
642 res
= ConfigurePortA(NULL
, 0, does_not_exist
);
643 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
644 ok( !res
&& ((GetLastError() == ERROR_NOT_SUPPORTED
) ||
645 (GetLastError() == ERROR_INVALID_PARAMETER
)),
646 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
647 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
651 - Case of Portnames is ignored
652 - Portname without ":" => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
653 - Empty Servername (LPT1:) => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
655 - Port not present => 9x: ERROR_INVALID_PARAMETER, NT:ERROR_NOT_SUPPORTED
656 - "FILE:" => 9x:Success, NT:ERROR_CANCELED
657 - Cancel ("Local Port") => ERROR_CANCELED
658 - Cancel ("Redirected Port") => Success
660 if (winetest_interactive
> 0) {
661 SetLastError(0xdeadbeef);
662 res
= ConfigurePortA(NULL
, 0, portname_com1
);
663 trace("'%s' returned %d with %d\n", portname_com1
, res
, GetLastError());
665 SetLastError(0xdeadbeef);
666 res
= ConfigurePortA(NULL
, 0, portname_lpt1
);
667 trace("'%s' returned %d with %d\n", portname_lpt1
, res
, GetLastError());
669 SetLastError(0xdeadbeef);
670 res
= ConfigurePortA(NULL
, 0, portname_file
);
671 trace("'%s' returned %d with %d\n", portname_file
, res
, GetLastError());
675 /* ########################### */
677 static void test_ClosePrinter(void)
682 /* NULL is handled */
683 SetLastError(0xdeadbeef);
684 res
= ClosePrinter(NULL
);
685 ok(!res
&& (GetLastError() == ERROR_INVALID_HANDLE
),
686 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
687 res
, GetLastError());
689 /* A random value as HANDLE is handled */
690 SetLastError(0xdeadbeef);
691 res
= ClosePrinter( (void *) -1);
692 if (is_spooler_deactivated(res
, GetLastError())) return;
693 ok(!res
&& (GetLastError() == ERROR_INVALID_HANDLE
),
694 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
695 res
, GetLastError());
698 /* Normal use (The Spooler service is needed) */
699 SetLastError(0xdeadbeef);
700 res
= OpenPrinterA(default_printer
, &printer
, NULL
);
701 if (is_spooler_deactivated(res
, GetLastError())) return;
704 SetLastError(0xdeadbeef);
705 res
= ClosePrinter(printer
);
706 ok(res
, "got %d with %d (expected TRUE)\n", res
, GetLastError());
709 /* double free is handled */
710 SetLastError(0xdeadbeef);
711 res
= ClosePrinter(printer
);
712 ok(!res
&& (GetLastError() == ERROR_INVALID_HANDLE
),
713 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
714 res
, GetLastError());
719 /* ########################### */
721 static void test_DeleteMonitor(void)
723 MONITOR_INFO_2A mi2a
;
724 struct monitor_entry
* entry
= NULL
;
728 entry
= find_installed_monitor();
731 skip("No usable Monitor found\n");
735 mi2a
.pName
= winetest
;
736 mi2a
.pEnvironment
= entry
->env
;
737 mi2a
.pDLLName
= entry
->dllname
;
739 /* Testing DeleteMonitor with real options */
740 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
742 SetLastError(MAGIC_DEAD
);
743 res
= DeleteMonitorA(NULL
, entry
->env
, winetest
);
744 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
746 /* Delete the Monitor twice */
747 SetLastError(MAGIC_DEAD
);
748 res
= DeleteMonitorA(NULL
, entry
->env
, winetest
);
749 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
751 ((GetLastError() == ERROR_UNKNOWN_PRINT_MONITOR
) ||
752 (GetLastError() == ERROR_INVALID_PARAMETER
)),
753 "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR"
754 " or ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
756 /* the environment */
757 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
758 SetLastError(MAGIC_DEAD
);
759 res
= DeleteMonitorA(NULL
, NULL
, winetest
);
760 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
762 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
763 SetLastError(MAGIC_DEAD
);
764 res
= DeleteMonitorA(NULL
, empty
, winetest
);
765 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
767 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
768 SetLastError(MAGIC_DEAD
);
769 res
= DeleteMonitorA(NULL
, invalid_env
, winetest
);
770 ok( res
|| GetLastError() == ERROR_INVALID_ENVIRONMENT
/* Vista/W2K8 */,
771 "returned %d with %d\n", res
, GetLastError());
773 /* the monitor-name */
774 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
775 SetLastError(MAGIC_DEAD
);
776 res
= DeleteMonitorA(NULL
, entry
->env
, NULL
);
777 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
779 ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
780 (GetLastError() == ERROR_INVALID_NAME
)),
781 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
782 "ERROR_INVALID_NAME)\n", res
, GetLastError());
784 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
785 SetLastError(MAGIC_DEAD
);
786 res
= DeleteMonitorA(NULL
, entry
->env
, empty
);
787 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
789 ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
790 (GetLastError() == ERROR_INVALID_NAME
)),
791 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
792 "ERROR_INVALID_NAME)\n", res
, GetLastError());
794 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
795 SetLastError(MAGIC_DEAD
);
796 res
= DeleteMonitorA(empty
, entry
->env
, winetest
);
797 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
800 DeleteMonitorA(NULL
, entry
->env
, winetest
);
803 /* ########################### */
805 static void test_DeletePort(void)
809 SetLastError(0xdeadbeef);
810 res
= DeletePortA(NULL
, 0, NULL
);
811 if (is_spooler_deactivated(res
, GetLastError())) return;
813 SetLastError(0xdeadbeef);
814 res
= DeletePortA(NULL
, 0, empty
);
815 /* Allowed only for (Printer-)Administrators */
816 if (is_access_denied(res
, GetLastError())) return;
818 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
819 ok( !res
&& ((GetLastError() == ERROR_NOT_SUPPORTED
) ||
820 (GetLastError() == ERROR_INVALID_PARAMETER
)),
821 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
822 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
825 SetLastError(0xdeadbeef);
826 res
= DeletePortA(NULL
, 0, does_not_exist
);
827 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
828 ok( !res
&& ((GetLastError() == ERROR_NOT_SUPPORTED
) ||
829 (GetLastError() == ERROR_INVALID_PARAMETER
)),
830 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
831 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
835 /* ########################### */
837 static void test_EnumForms(LPSTR pName
)
847 const char *formtype
;
848 static const char * const formtypes
[] = { "FORM_USER", "FORM_BUILTIN", "FORM_PRINTER", "FORM_flag_unknown" };
849 #define FORMTYPE_MAX 2
850 PFORM_INFO_1A pFI_1a
;
851 PFORM_INFO_2A pFI_2a
;
853 res
= OpenPrinterA(pName
, &hprinter
, NULL
);
854 if (is_spooler_deactivated(res
, GetLastError())) return;
855 if (!res
|| !hprinter
)
857 /* opening the local Printserver is not supported on win9x */
858 if (pName
) skip("Failed to open '%s' (not supported on win9x)\n", pName
);
862 /* valid levels are 1 and 2 */
863 for(level
= 0; level
< 4; level
++) {
865 pcReturned
= 0xdeadbeef;
866 SetLastError(0xdeadbeef);
867 res
= EnumFormsA(hprinter
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
869 /* EnumForms is not implemented on win9x */
870 if (!res
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)) continue;
872 /* EnumForms for the server is not implemented on all NT-versions */
873 if (!res
&& (GetLastError() == ERROR_INVALID_HANDLE
) && !pName
) continue;
875 /* Level 2 for EnumForms is not supported on all systems */
876 if (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
) && (level
== 2)) continue;
878 /* use only a short test when testing an invalid level */
879 if(!level
|| (level
> 2)) {
880 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
881 (res
&& (pcReturned
== 0)),
882 "(%d) returned %d with %d and 0x%08x (expected '0' with "
883 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
884 level
, res
, GetLastError(), pcReturned
);
888 ok((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
889 "(%d) returned %d with %d (expected '0' with "
890 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
892 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
*2);
893 if (buffer
== NULL
) continue;
895 SetLastError(0xdeadbeef);
896 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
897 ok(res
, "(%d) returned %d with %d (expected '!=0')\n",
898 level
, res
, GetLastError());
900 if (winetest_debug
> 1) {
901 trace("dumping %d forms level %d\n", pcReturned
, level
);
902 pFI_1a
= (PFORM_INFO_1A
)buffer
;
903 pFI_2a
= (PFORM_INFO_2A
)buffer
;
904 for (i
= 0; i
< pcReturned
; i
++)
906 /* first part is same in FORM_INFO_1 and FORM_INFO_2 */
907 formtype
= (pFI_1a
->Flags
<= FORMTYPE_MAX
) ? formtypes
[pFI_1a
->Flags
] : formtypes
[3];
908 trace("%u (%s): %.03fmm x %.03fmm, %s\n", i
, pFI_1a
->pName
,
909 (float)pFI_1a
->Size
.cx
/1000, (float)pFI_1a
->Size
.cy
/1000, formtype
);
911 if (level
== 1) pFI_1a
++;
913 /* output additional FORM_INFO_2 fields */
914 trace("\tkeyword=%s strtype=%u muidll=%s resid=%u dispname=%s langid=%u\n",
915 pFI_2a
->pKeyword
, pFI_2a
->StringType
, pFI_2a
->pMuiDll
,
916 pFI_2a
->dwResourceId
, pFI_2a
->pDisplayName
, pFI_2a
->wLangId
);
918 /* offset pointer pFI_1a by 1*sizeof(FORM_INFO_2A) Bytes */
920 pFI_1a
= (PFORM_INFO_1A
)pFI_2a
;
925 SetLastError(0xdeadbeef);
926 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
927 ok( res
, "(%d) returned %d with %d (expected '!=0')\n",
928 level
, res
, GetLastError());
930 SetLastError(0xdeadbeef);
931 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
932 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
933 "(%d) returned %d with %d (expected '0' with "
934 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
937 SetLastError(0xdeadbeef);
938 res
= EnumFormsA(hprinter
, level
, NULL
, cbBuf
, &pcbNeeded
, &pcReturned
);
939 ok( !res
&& (GetLastError() == ERROR_INVALID_USER_BUFFER
) ,
940 "(%d) returned %d with %d (expected '0' with "
941 "ERROR_INVALID_USER_BUFFER)\n", level
, res
, GetLastError());
944 SetLastError(0xdeadbeef);
945 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
946 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
) ,
947 "(%d) returned %d with %d (expected '0' with "
948 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
950 SetLastError(0xdeadbeef);
951 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
952 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
) ,
953 "(%d) returned %d with %d (expected '0' with "
954 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
956 SetLastError(0xdeadbeef);
957 res
= EnumFormsA(0, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
958 ok( !res
&& (GetLastError() == ERROR_INVALID_HANDLE
) ,
959 "(%d) returned %d with %d (expected '0' with "
960 "ERROR_INVALID_HANDLE)\n", level
, res
, GetLastError());
962 HeapFree(GetProcessHeap(), 0, buffer
);
963 } /* for(level ... */
965 ClosePrinter(hprinter
);
968 /* ########################### */
970 static void test_EnumMonitors(void)
979 /* valid levels are 1 and 2 */
980 for(level
= 0; level
< 4; level
++) {
982 pcReturned
= MAGIC_DEAD
;
983 SetLastError(MAGIC_DEAD
);
984 res
= EnumMonitorsA(NULL
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
985 if (is_spooler_deactivated(res
, GetLastError())) return;
986 /* not implemented yet in wine */
987 if (!res
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)) continue;
990 /* use only a short test when testing an invalid level */
991 if(!level
|| (level
> 2)) {
992 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
993 (res
&& (pcReturned
== 0)),
994 "(%d) returned %d with %d and 0x%08x (expected '0' with "
995 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
996 level
, res
, GetLastError(), pcReturned
);
1000 /* Level 2 is not supported on win9x */
1001 if (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) {
1002 skip("Level %d not supported\n", level
);
1006 ok((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1007 "(%d) returned %d with %d (expected '0' with "
1008 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
1011 skip("no valid buffer size returned\n");
1015 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
*2);
1016 if (buffer
== NULL
) continue;
1018 SetLastError(MAGIC_DEAD
);
1019 pcbNeeded
= MAGIC_DEAD
;
1020 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1021 ok(res
, "(%d) returned %d with %d (expected '!=0')\n",
1022 level
, res
, GetLastError());
1023 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n",
1024 level
, pcbNeeded
, cbBuf
);
1025 /* We can validate the returned Data with the Registry here */
1028 SetLastError(MAGIC_DEAD
);
1029 pcReturned
= MAGIC_DEAD
;
1030 pcbNeeded
= MAGIC_DEAD
;
1031 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
1032 ok(res
, "(%d) returned %d with %d (expected '!=0')\n", level
,
1033 res
, GetLastError());
1034 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
,
1037 SetLastError(MAGIC_DEAD
);
1038 pcbNeeded
= MAGIC_DEAD
;
1039 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
1040 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1041 "(%d) returned %d with %d (expected '0' with "
1042 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
1044 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
,
1048 Do not add the next test:
1049 w2k+: RPC_X_NULL_REF_POINTER
1050 NT3.5: ERROR_INVALID_USER_BUFFER
1051 win9x: crash in winspool.drv
1053 res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1056 SetLastError(MAGIC_DEAD
);
1057 pcbNeeded
= MAGIC_DEAD
;
1058 pcReturned
= MAGIC_DEAD
;
1059 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
1060 ok( res
|| GetLastError() == RPC_X_NULL_REF_POINTER
,
1061 "(%d) returned %d with %d (expected '!=0' or '0' with "
1062 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
1064 pcbNeeded
= MAGIC_DEAD
;
1065 pcReturned
= MAGIC_DEAD
;
1066 SetLastError(MAGIC_DEAD
);
1067 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
1068 ok( res
|| GetLastError() == RPC_X_NULL_REF_POINTER
,
1069 "(%d) returned %d with %d (expected '!=0' or '0' with "
1070 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
1072 HeapFree(GetProcessHeap(), 0, buffer
);
1073 } /* for(level ... */
1076 /* ########################### */
1078 static void test_EnumPorts(void)
1087 /* valid levels are 1 and 2 */
1088 for(level
= 0; level
< 4; level
++) {
1091 pcReturned
= 0xdeadbeef;
1092 SetLastError(0xdeadbeef);
1093 res
= EnumPortsA(NULL
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
1094 if (is_spooler_deactivated(res
, GetLastError())) return;
1096 /* use only a short test when testing an invalid level */
1097 if(!level
|| (level
> 2)) {
1098 /* NT: ERROR_INVALID_LEVEL, 9x: success */
1099 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
1100 (res
&& (pcReturned
== 0)),
1101 "(%d) returned %d with %d and 0x%08x (expected '0' with "
1102 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1103 level
, res
, GetLastError(), pcReturned
);
1108 /* Level 2 is not supported on NT 3.x */
1109 if (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) {
1110 skip("Level %d not supported\n", level
);
1114 ok((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1115 "(%d) returned %d with %d (expected '0' with "
1116 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
1118 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
*2);
1119 if (buffer
== NULL
) continue;
1121 pcbNeeded
= 0xdeadbeef;
1122 SetLastError(0xdeadbeef);
1123 res
= EnumPortsA(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1124 ok(res
, "(%d) returned %d with %d (expected '!=0')\n", level
, res
, GetLastError());
1125 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
, pcbNeeded
, cbBuf
);
1126 /* ToDo: Compare the returned Data with the Registry / "win.ini",[Ports] here */
1128 pcbNeeded
= 0xdeadbeef;
1129 pcReturned
= 0xdeadbeef;
1130 SetLastError(0xdeadbeef);
1131 res
= EnumPortsA(NULL
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
1132 ok(res
, "(%d) returned %d with %d (expected '!=0')\n", level
, res
, GetLastError());
1133 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
, pcbNeeded
, cbBuf
);
1135 pcbNeeded
= 0xdeadbeef;
1136 SetLastError(0xdeadbeef);
1137 res
= EnumPortsA(NULL
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
1138 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1139 "(%d) returned %d with %d (expected '0' with "
1140 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
1141 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
, pcbNeeded
, cbBuf
);
1144 Do not add this test:
1145 res = EnumPortsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1146 w2k+: RPC_X_NULL_REF_POINTER
1147 NT3.5: ERROR_INVALID_USER_BUFFER
1148 win9x: crash in winspool.drv
1151 SetLastError(0xdeadbeef);
1152 res
= EnumPortsA(NULL
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
1153 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
1154 ok( (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
) ) ||
1155 ( res
&& (GetLastError() == ERROR_SUCCESS
) ),
1156 "(%d) returned %d with %d (expected '0' with "
1157 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1158 level
, res
, GetLastError());
1161 SetLastError(0xdeadbeef);
1162 res
= EnumPortsA(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
1163 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
1164 ok( (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
) ) ||
1165 ( res
&& (GetLastError() == ERROR_SUCCESS
) ),
1166 "(%d) returned %d with %d (expected '0' with "
1167 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1168 level
, res
, GetLastError());
1170 HeapFree(GetProcessHeap(), 0, buffer
);
1174 /* ########################### */
1176 static void test_EnumPrinterDrivers(void)
1178 static char env_all
[] = "all";
1187 /* 1-3 for w95/w98/NT4; 1-3+6 for me; 1-6 for w2k/xp/2003; 1-6+8 for vista */
1188 for(level
= 0; level
< 10; level
++) {
1190 pcReturned
= 0xdeadbeef;
1191 SetLastError(0xdeadbeef);
1192 res
= EnumPrinterDriversA(NULL
, NULL
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
1193 if (is_spooler_deactivated(res
, GetLastError())) return;
1195 /* use only a short test when testing an invalid level */
1196 if(!level
|| (level
== 7) || (level
> 8)) {
1198 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
1199 (res
&& (pcReturned
== 0)),
1200 "(%d) got %u with %u and 0x%x "
1201 "(expected '0' with ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1202 level
, res
, GetLastError(), pcReturned
);
1206 /* some levels are not supported on all windows versions */
1207 if (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) {
1208 skip("Level %d not supported\n", level
);
1212 ok( ((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) ||
1213 (res
&& (default_printer
== NULL
)),
1214 "(%u) got %u with %u for %s (expected '0' with "
1215 "ERROR_INSUFFICIENT_BUFFER or '!= 0' without a printer)\n",
1216 level
, res
, GetLastError(), default_printer
);
1219 skip("no valid buffer size returned\n");
1223 /* EnumPrinterDriversA returns the same number of bytes as EnumPrinterDriversW */
1224 if (!on_win9x
&& pEnumPrinterDriversW
)
1226 DWORD double_needed
;
1227 DWORD double_returned
;
1228 pEnumPrinterDriversW(NULL
, NULL
, level
, NULL
, 0, &double_needed
, &double_returned
);
1229 ok(double_needed
== cbBuf
, "level %d: EnumPrinterDriversA returned different size %d than EnumPrinterDriversW (%d)\n", level
, cbBuf
, double_needed
);
1232 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
+ 4);
1233 if (buffer
== NULL
) continue;
1235 SetLastError(0xdeadbeef);
1236 pcbNeeded
= 0xdeadbeef;
1237 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1238 ok(res
, "(%u) got %u with %u (expected '!=0')\n", level
, res
, GetLastError());
1239 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
, pcbNeeded
, cbBuf
);
1241 /* validate the returned data here */
1243 LPDRIVER_INFO_2A di
= (LPDRIVER_INFO_2A
) buffer
;
1245 ok( strrchr(di
->pDriverPath
, '\\') != NULL
,
1246 "(%u) got %s for %s (expected a full path)\n",
1247 level
, di
->pDriverPath
, di
->pName
);
1251 SetLastError(0xdeadbeef);
1252 pcReturned
= 0xdeadbeef;
1253 pcbNeeded
= 0xdeadbeef;
1254 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
1255 ok(res
, "(%u) got %u with %u (expected '!=0')\n", level
, res
, GetLastError());
1256 ok(pcbNeeded
== cbBuf
, "(%u) returned %u (expected %u)\n", level
, pcbNeeded
, cbBuf
);
1258 SetLastError(0xdeadbeef);
1259 pcbNeeded
= 0xdeadbeef;
1260 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
1261 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1262 "(%u) got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1263 level
, res
, GetLastError());
1264 ok(pcbNeeded
== cbBuf
, "(%u) returned %u (expected %u)\n", level
, pcbNeeded
, cbBuf
);
1267 Do not add the next test:
1268 NT: ERROR_INVALID_USER_BUFFER
1269 win9x: crash or 100% CPU
1271 res = EnumPrinterDriversA(NULL, NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1274 SetLastError(0xdeadbeef);
1275 pcbNeeded
= 0xdeadbeef;
1276 pcReturned
= 0xdeadbeef;
1277 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
1278 ok( res
|| GetLastError() == RPC_X_NULL_REF_POINTER
,
1279 "(%u) got %u with %u (expected '!=0' or '0' with "
1280 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
1282 pcbNeeded
= 0xdeadbeef;
1283 pcReturned
= 0xdeadbeef;
1284 SetLastError(0xdeadbeef);
1285 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
1286 ok( res
|| GetLastError() == RPC_X_NULL_REF_POINTER
,
1287 "(%u) got %u with %u (expected '!=0' or '0' with "
1288 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
1290 HeapFree(GetProcessHeap(), 0, buffer
);
1291 } /* for(level ... */
1295 SetLastError(0xdeadbeef);
1296 res
= EnumPrinterDriversA(NULL
, env_all
, 1, NULL
, 0, &pcbNeeded
, &pcReturned
);
1299 skip("no printer drivers found\n");
1302 if (GetLastError() == ERROR_INVALID_ENVIRONMENT
)
1304 win_skip("NT4 and below don't support the 'all' environment value\n");
1307 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "unexpected error %u\n", GetLastError());
1309 buffer
= HeapAlloc(GetProcessHeap(), 0, pcbNeeded
);
1310 res
= EnumPrinterDriversA(NULL
, env_all
, 1, buffer
, pcbNeeded
, &pcbNeeded
, &pcReturned
);
1311 ok(res
, "EnumPrinterDriversA failed %u\n", GetLastError());
1312 if (res
&& pcReturned
> 0)
1314 DRIVER_INFO_1A
*di_1
= (DRIVER_INFO_1A
*)buffer
;
1315 ok((LPBYTE
) di_1
->pName
== NULL
|| (LPBYTE
) di_1
->pName
< buffer
||
1316 (LPBYTE
) di_1
->pName
>= (LPBYTE
)(di_1
+ pcReturned
),
1317 "Driver Information not in sequence; pName %p, top of data %p\n",
1318 di_1
->pName
, di_1
+ pcReturned
);
1321 HeapFree(GetProcessHeap(), 0, buffer
);
1324 /* ########################### */
1326 static void test_EnumPrintProcessors(void)
1336 pcReturned
= 0xdeadbeef;
1337 SetLastError(0xdeadbeef);
1338 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, NULL
, 0, &cbBuf
, &pcReturned
);
1339 if (is_spooler_deactivated(res
, GetLastError())) return;
1341 if (res
&& !cbBuf
) {
1342 skip("No Printprocessor installed\n");
1346 ok((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1347 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1348 res
, GetLastError());
1350 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
+ 4);
1354 SetLastError(0xdeadbeef);
1355 pcbNeeded
= 0xdeadbeef;
1356 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1357 ok(res
, "got %u with %u (expected '!=0')\n", res
, GetLastError());
1358 /* validate the returned data here. */
1361 SetLastError(0xdeadbeef);
1362 pcReturned
= 0xdeadbeef;
1363 pcbNeeded
= 0xdeadbeef;
1364 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
1365 ok(res
, "got %u with %u (expected '!=0')\n", res
, GetLastError());
1367 SetLastError(0xdeadbeef);
1368 pcbNeeded
= 0xdeadbeef;
1369 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
1370 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1371 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1372 res
, GetLastError());
1374 /* only level 1 is valid */
1376 /* both tests crash on win98se */
1377 SetLastError(0xdeadbeef);
1378 pcbNeeded
= 0xdeadbeef;
1379 pcReturned
= 0xdeadbeef;
1380 res
= EnumPrintProcessorsA(NULL
, NULL
, 0, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1381 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
1382 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1383 res
, GetLastError());
1385 SetLastError(0xdeadbeef);
1386 pcbNeeded
= 0xdeadbeef;
1387 res
= EnumPrintProcessorsA(NULL
, NULL
, 2, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1388 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
1389 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1390 res
, GetLastError());
1393 /* an empty environment is ignored */
1394 SetLastError(0xdeadbeef);
1395 pcbNeeded
= 0xdeadbeef;
1396 res
= EnumPrintProcessorsA(NULL
, empty
, 1, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1397 ok(res
, "got %u with %u (expected '!=0')\n", res
, GetLastError());
1399 /* the environment is checked */
1400 SetLastError(0xdeadbeef);
1401 pcbNeeded
= 0xdeadbeef;
1402 res
= EnumPrintProcessorsA(NULL
, invalid_env
, 1, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1403 /* NT5: ERROR_INVALID_ENVIRONMENT, NT4: res != 0, 9x: ERROR_INVALID_PARAMETER */
1404 ok( broken(res
) || /* NT4 */
1405 (GetLastError() == ERROR_INVALID_ENVIRONMENT
) ||
1406 (GetLastError() == ERROR_INVALID_PARAMETER
),
1407 "got %u with %u (expected '0' with ERROR_INVALID_ENVIRONMENT or "
1408 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1411 /* failure-Codes for NULL */
1413 /* this test crashes on win98se */
1414 SetLastError(0xdeadbeef);
1415 pcbNeeded
= 0xdeadbeef;
1416 pcReturned
= 0xdeadbeef;
1417 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, NULL
, cbBuf
, &pcbNeeded
, &pcReturned
);
1418 ok( !res
&& (GetLastError() == ERROR_INVALID_USER_BUFFER
) ,
1419 "got %u with %u (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1420 res
, GetLastError());
1423 SetLastError(0xdeadbeef);
1424 pcbNeeded
= 0xdeadbeef;
1425 pcReturned
= 0xdeadbeef;
1426 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
, NULL
, &pcReturned
);
1427 /* the NULL is ignored on win9x */
1428 ok( broken(res
) || (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
)),
1429 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1430 res
, GetLastError());
1432 pcbNeeded
= 0xdeadbeef;
1433 pcReturned
= 0xdeadbeef;
1434 SetLastError(0xdeadbeef);
1435 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
, NULL
);
1436 /* the NULL is ignored on win9x */
1437 ok( broken(res
) || (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
)),
1438 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1439 res
, GetLastError());
1441 HeapFree(GetProcessHeap(), 0, buffer
);
1445 /* ########################### */
1447 static void test_GetDefaultPrinter(void)
1450 DWORD exact
= DEFAULT_PRINTER_SIZE
;
1452 char buffer
[DEFAULT_PRINTER_SIZE
];
1454 if (!pGetDefaultPrinterA
) return;
1455 /* only supported on NT like OSes starting with win2k */
1457 SetLastError(ERROR_SUCCESS
);
1458 retval
= pGetDefaultPrinterA(buffer
, &exact
);
1459 if (!retval
|| !exact
|| !strlen(buffer
) ||
1460 (ERROR_SUCCESS
!= GetLastError())) {
1461 if ((ERROR_FILE_NOT_FOUND
== GetLastError()) ||
1462 (ERROR_INVALID_NAME
== GetLastError()))
1463 trace("this test requires a default printer to be set\n");
1465 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
1466 "function returned %s\n"
1467 "last error 0x%08x\n"
1468 "returned buffer size 0x%08x\n"
1469 "returned buffer content %s\n",
1470 retval
? "true" : "false", GetLastError(), exact
, buffer
);
1474 SetLastError(ERROR_SUCCESS
);
1475 retval
= pGetDefaultPrinterA(NULL
, NULL
);
1476 ok( !retval
, "function result wrong! False expected\n");
1477 ok( ERROR_INVALID_PARAMETER
== GetLastError(),
1478 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1481 SetLastError(ERROR_SUCCESS
);
1482 retval
= pGetDefaultPrinterA(buffer
, NULL
);
1483 ok( !retval
, "function result wrong! False expected\n");
1484 ok( ERROR_INVALID_PARAMETER
== GetLastError(),
1485 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1488 SetLastError(ERROR_SUCCESS
);
1490 retval
= pGetDefaultPrinterA(NULL
, &size
);
1491 ok( !retval
, "function result wrong! False expected\n");
1492 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
1493 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1495 ok( size
== exact
, "Parameter size wrong! %d expected got %d\n",
1498 SetLastError(ERROR_SUCCESS
);
1499 size
= DEFAULT_PRINTER_SIZE
;
1500 retval
= pGetDefaultPrinterA(NULL
, &size
);
1501 ok( !retval
, "function result wrong! False expected\n");
1502 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
1503 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1505 ok( size
== exact
, "Parameter size wrong! %d expected got %d\n",
1509 retval
= pGetDefaultPrinterA(buffer
, &size
);
1510 ok( !retval
, "function result wrong! False expected\n");
1511 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
1512 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1514 ok( size
== exact
, "Parameter size wrong! %d expected got %d\n",
1518 retval
= pGetDefaultPrinterA(buffer
, &size
);
1519 ok( retval
, "function result wrong! True expected\n");
1520 ok( size
== exact
, "Parameter size wrong! %d expected got %d\n",
1524 static void test_GetPrinterDriverDirectory(void)
1526 LPBYTE buffer
= NULL
;
1527 DWORD cbBuf
= 0, pcbNeeded
= 0;
1531 SetLastError(MAGIC_DEAD
);
1532 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, NULL
, 0, &cbBuf
);
1533 if (is_spooler_deactivated(res
, GetLastError())) return;
1535 trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
1536 res
, GetLastError(), cbBuf
);
1538 ok((res
== 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1539 "returned %d with lasterror=%d (expected '0' with "
1540 "ERROR_INSUFFICIENT_BUFFER)\n", res
, GetLastError());
1543 skip("no valid buffer size returned\n");
1547 buffer
= HeapAlloc( GetProcessHeap(), 0, cbBuf
*2);
1548 if (buffer
== NULL
) return ;
1550 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
);
1551 ok( res
, "expected result != 0, got %d\n", res
);
1552 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %d instead of %d\n",
1555 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1556 ok( res
, "expected result != 0, got %d\n", res
);
1557 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %d instead of %d\n",
1560 SetLastError(MAGIC_DEAD
);
1561 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
-1, &pcbNeeded
);
1562 ok( !res
, "expected result == 0, got %d\n", res
);
1563 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %d instead of %d\n",
1566 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
1567 "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
1571 Do not add the next test:
1572 XPsp2: crash in this app, when the spooler is not running
1573 NT3.5: ERROR_INVALID_USER_BUFFER
1574 win9x: ERROR_INVALID_PARAMETER
1576 pcbNeeded = MAGIC_DEAD;
1577 SetLastError(MAGIC_DEAD);
1578 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1581 SetLastError(MAGIC_DEAD
);
1582 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
, NULL
);
1583 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1584 NT: RPC_X_NULL_REF_POINTER */
1585 ok( res
|| (GetLastError() == RPC_X_NULL_REF_POINTER
) ||
1586 (GetLastError() == ERROR_INVALID_PARAMETER
),
1587 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1588 "or '0' with ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1590 SetLastError(MAGIC_DEAD
);
1591 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, NULL
, cbBuf
, NULL
);
1592 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1593 NT: RPC_X_NULL_REF_POINTER */
1594 ok( res
|| (GetLastError() == RPC_X_NULL_REF_POINTER
) ||
1595 (GetLastError() == ERROR_INVALID_PARAMETER
),
1596 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1597 "or '0' with ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1599 /* with a valid buffer, but level is too large */
1601 SetLastError(MAGIC_DEAD
);
1602 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 2, buffer
, cbBuf
, &pcbNeeded
);
1604 /* Level not checked in win9x and wine:*/
1605 if((res
!= FALSE
) && buffer
[0])
1607 trace("Level '2' not checked '%s'\n", buffer
);
1611 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
1612 "returned %d with lasterror=%d (expected '0' with "
1613 "ERROR_INVALID_LEVEL)\n", res
, GetLastError());
1616 /* printing environments are case insensitive */
1617 /* "Windows 4.0" is valid for win9x and NT */
1619 SetLastError(MAGIC_DEAD
);
1620 res
= GetPrinterDriverDirectoryA(NULL
, env_win9x_case
, 1,
1621 buffer
, cbBuf
*2, &pcbNeeded
);
1623 if(!res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
1625 buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, cbBuf
*2);
1626 if (buffer
== NULL
) return ;
1628 SetLastError(MAGIC_DEAD
);
1629 res
= GetPrinterDriverDirectoryA(NULL
, env_win9x_case
, 1,
1630 buffer
, cbBuf
*2, &pcbNeeded
);
1633 ok(res
&& buffer
[0], "returned %d with "
1634 "lasterror=%d and len=%d (expected '1' with 'len > 0')\n",
1635 res
, GetLastError(), lstrlenA((char *)buffer
));
1638 SetLastError(MAGIC_DEAD
);
1639 res
= GetPrinterDriverDirectoryA(NULL
, env_x86
, 1,
1640 buffer
, cbBuf
*2, &pcbNeeded
);
1642 if(!res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
1644 buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, cbBuf
*2);
1645 if (buffer
== NULL
) return ;
1648 SetLastError(MAGIC_DEAD
);
1649 res
= GetPrinterDriverDirectoryA(NULL
, env_x86
, 1,
1650 buffer
, cbBuf
*2, &pcbNeeded
);
1653 /* "Windows NT x86" is invalid for win9x */
1654 ok( (res
&& buffer
[0]) ||
1655 (!res
&& (GetLastError() == ERROR_INVALID_ENVIRONMENT
)),
1656 "returned %d with lasterror=%d and len=%d (expected '!= 0' with "
1657 "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
1658 res
, GetLastError(), lstrlenA((char *)buffer
));
1660 /* A setup program (PDFCreator_0.8.0) use empty strings */
1661 SetLastError(MAGIC_DEAD
);
1662 res
= GetPrinterDriverDirectoryA(empty
, empty
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1663 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError() );
1665 SetLastError(MAGIC_DEAD
);
1666 res
= GetPrinterDriverDirectoryA(NULL
, empty
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1667 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError() );
1669 SetLastError(MAGIC_DEAD
);
1670 res
= GetPrinterDriverDirectoryA(empty
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1671 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError() );
1673 HeapFree( GetProcessHeap(), 0, buffer
);
1678 static void test_GetPrintProcessorDirectory(void)
1680 LPBYTE buffer
= NULL
;
1682 DWORD pcbNeeded
= 0;
1686 SetLastError(0xdeadbeef);
1687 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 1, NULL
, 0, &cbBuf
);
1688 if (is_spooler_deactivated(res
, GetLastError())) return;
1690 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1691 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1692 res
, GetLastError());
1694 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
*2);
1695 if(buffer
== NULL
) return;
1698 SetLastError(0xdeadbeef);
1699 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
);
1700 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1702 SetLastError(0xdeadbeef);
1704 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1705 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1707 /* Buffer too small */
1709 SetLastError(0xdeadbeef);
1710 res
= GetPrintProcessorDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
-1, &pcbNeeded
);
1711 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1712 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1713 res
, GetLastError());
1717 /* XPsp2: the program will crash here, when the spooler is not running */
1718 /* GetPrinterDriverDirectory has the same bug */
1720 SetLastError(0xdeadbeef);
1721 res
= GetPrintProcessorDirectoryA( NULL
, NULL
, 1, NULL
, cbBuf
, &pcbNeeded
);
1722 /* NT: ERROR_INVALID_USER_BUFFER, 9x: res != 0 */
1723 ok( (!res
&& (GetLastError() == ERROR_INVALID_USER_BUFFER
)) ||
1725 "returned %d with %d (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1726 res
, GetLastError());
1730 SetLastError(0xdeadbeef);
1731 res
= GetPrintProcessorDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
, NULL
);
1732 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1733 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1734 ok( !res
&& ((GetLastError() == RPC_X_NULL_REF_POINTER
) ||
1735 (GetLastError() == ERROR_INVALID_PARAMETER
)),
1736 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1737 "or with ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1740 SetLastError(0xdeadbeef);
1741 res
= GetPrintProcessorDirectoryA( NULL
, NULL
, 1, NULL
, cbBuf
, NULL
);
1742 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1743 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1744 ok( !res
&& ((GetLastError() == RPC_X_NULL_REF_POINTER
) ||
1745 (GetLastError() == ERROR_INVALID_PARAMETER
)),
1746 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1747 "or with ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1749 /* with a valid buffer, but level is invalid */
1751 SetLastError(0xdeadbeef);
1752 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 0, buffer
, cbBuf
, &pcbNeeded
);
1753 /* Level is ignored in win9x*/
1754 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
1755 broken(res
&& buffer
[0]),
1756 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1757 res
, GetLastError());
1760 SetLastError(0xdeadbeef);
1761 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 2, buffer
, cbBuf
, &pcbNeeded
);
1762 /* Level is ignored on win9x*/
1763 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
1764 broken(res
&& buffer
[0]),
1765 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1766 res
, GetLastError());
1768 /* Empty environment is the same as the default environment */
1770 SetLastError(0xdeadbeef);
1771 res
= GetPrintProcessorDirectoryA(NULL
, empty
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1772 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1774 /* "Windows 4.0" is valid for win9x and NT */
1776 SetLastError(0xdeadbeef);
1777 res
= GetPrintProcessorDirectoryA(NULL
, env_win9x_case
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1778 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1781 /* "Windows NT x86" is invalid for win9x */
1783 SetLastError(0xdeadbeef);
1784 res
= GetPrintProcessorDirectoryA(NULL
, env_x86
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1785 ok( res
|| (GetLastError() == ERROR_INVALID_ENVIRONMENT
),
1786 "returned %d with %d (expected '!= 0' or '0' with "
1787 "ERROR_INVALID_ENVIRONMENT)\n", res
, GetLastError());
1789 /* invalid on all systems */
1791 SetLastError(0xdeadbeef);
1792 res
= GetPrintProcessorDirectoryA(NULL
, invalid_env
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1793 ok( !res
&& (GetLastError() == ERROR_INVALID_ENVIRONMENT
),
1794 "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
1795 res
, GetLastError());
1797 /* Empty servername is the same as the local computer */
1799 SetLastError(0xdeadbeef);
1800 res
= GetPrintProcessorDirectoryA(empty
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1801 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1803 /* invalid on all systems */
1805 SetLastError(0xdeadbeef);
1806 res
= GetPrintProcessorDirectoryA(server_does_not_exist
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1807 ok( !res
, "expected failure\n");
1808 ok( GetLastError() == RPC_S_SERVER_UNAVAILABLE
|| /* NT */
1809 GetLastError() == ERROR_INVALID_PARAMETER
|| /* 9x */
1810 GetLastError() == RPC_S_INVALID_NET_ADDR
, /* Some Vista */
1811 "unexpected last error %d\n", GetLastError());
1813 HeapFree(GetProcessHeap(), 0, buffer
);
1818 static void test_OpenPrinter(void)
1820 PRINTER_DEFAULTSA defaults
;
1824 SetLastError(MAGIC_DEAD
);
1825 res
= OpenPrinterA(NULL
, NULL
, NULL
);
1826 if (is_spooler_deactivated(res
, GetLastError())) return;
1828 ok(!res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
1829 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1830 res
, GetLastError());
1833 /* Get Handle for the local Printserver (NT only)*/
1834 hprinter
= (HANDLE
) MAGIC_DEAD
;
1835 SetLastError(MAGIC_DEAD
);
1836 res
= OpenPrinterA(NULL
, &hprinter
, NULL
);
1837 if (is_spooler_deactivated(res
, GetLastError())) return;
1838 ok(res
|| GetLastError() == ERROR_INVALID_PARAMETER
,
1839 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1840 res
, GetLastError());
1842 ClosePrinter(hprinter
);
1844 defaults
.pDatatype
=NULL
;
1845 defaults
.pDevMode
=NULL
;
1847 defaults
.DesiredAccess
=0;
1848 hprinter
= (HANDLE
) MAGIC_DEAD
;
1849 SetLastError(MAGIC_DEAD
);
1850 res
= OpenPrinterA(NULL
, &hprinter
, &defaults
);
1851 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
1852 if (res
) ClosePrinter(hprinter
);
1854 defaults
.DesiredAccess
=-1;
1855 hprinter
= (HANDLE
) MAGIC_DEAD
;
1856 SetLastError(MAGIC_DEAD
);
1857 res
= OpenPrinterA(NULL
, &hprinter
, &defaults
);
1859 ok(!res
&& GetLastError() == ERROR_ACCESS_DENIED
,
1860 "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n",
1861 res
, GetLastError());
1863 if (res
) ClosePrinter(hprinter
);
1868 if (local_server
!= NULL
) {
1869 hprinter
= (HANDLE
) 0xdeadbeef;
1870 SetLastError(0xdeadbeef);
1871 res
= OpenPrinterA(local_server
, &hprinter
, NULL
);
1872 ok(res
|| GetLastError() == ERROR_INVALID_PARAMETER
,
1873 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1874 res
, GetLastError());
1875 if(res
) ClosePrinter(hprinter
);
1878 /* Invalid Printername */
1879 hprinter
= (HANDLE
) MAGIC_DEAD
;
1880 SetLastError(MAGIC_DEAD
);
1881 res
= OpenPrinterA(illegal_name
, &hprinter
, NULL
);
1882 ok(!res
&& ((GetLastError() == ERROR_INVALID_PRINTER_NAME
) ||
1883 (GetLastError() == ERROR_INVALID_PARAMETER
) ),
1884 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or"
1885 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
1886 if(res
) ClosePrinter(hprinter
);
1888 hprinter
= (HANDLE
) MAGIC_DEAD
;
1889 SetLastError(MAGIC_DEAD
);
1890 res
= OpenPrinterA(empty
, &hprinter
, NULL
);
1891 /* NT: ERROR_INVALID_PRINTER_NAME, 9x: ERROR_INVALID_PARAMETER */
1893 ((GetLastError() == ERROR_INVALID_PRINTER_NAME
) ||
1894 (GetLastError() == ERROR_INVALID_PARAMETER
) ),
1895 "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME"
1896 " or ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1897 if(res
) ClosePrinter(hprinter
);
1900 /* get handle for the default printer */
1901 if (default_printer
)
1903 hprinter
= (HANDLE
) MAGIC_DEAD
;
1904 SetLastError(MAGIC_DEAD
);
1905 res
= OpenPrinterA(default_printer
, &hprinter
, NULL
);
1906 if((!res
) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE
))
1908 trace("The service 'Spooler' is required for '%s'\n", default_printer
);
1911 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
1912 if(res
) ClosePrinter(hprinter
);
1914 SetLastError(MAGIC_DEAD
);
1915 res
= OpenPrinterA(default_printer
, NULL
, NULL
);
1916 /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1917 ok(res
|| (GetLastError() == ERROR_INVALID_PARAMETER
),
1918 "returned %d with %d (expected '!=0' or '0' with "
1919 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1921 defaults
.pDatatype
=NULL
;
1922 defaults
.pDevMode
=NULL
;
1923 defaults
.DesiredAccess
=0;
1925 hprinter
= (HANDLE
) MAGIC_DEAD
;
1926 SetLastError(MAGIC_DEAD
);
1927 res
= OpenPrinterA(default_printer
, &hprinter
, &defaults
);
1928 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
1929 "returned %d with %d (expected '!=0' or '0' with "
1930 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
1931 if(res
) ClosePrinter(hprinter
);
1933 defaults
.pDatatype
= empty
;
1935 hprinter
= (HANDLE
) MAGIC_DEAD
;
1936 SetLastError(MAGIC_DEAD
);
1937 res
= OpenPrinterA(default_printer
, &hprinter
, &defaults
);
1938 /* stop here, when a remote Printserver has no RPC-Service running */
1939 if (is_spooler_deactivated(res
, GetLastError())) return;
1940 ok(res
|| ((GetLastError() == ERROR_INVALID_DATATYPE
) ||
1941 (GetLastError() == ERROR_ACCESS_DENIED
)),
1942 "returned %d with %d (expected '!=0' or '0' with: "
1943 "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1944 res
, GetLastError());
1945 if(res
) ClosePrinter(hprinter
);
1948 defaults
.pDatatype
=NULL
;
1949 defaults
.DesiredAccess
=PRINTER_ACCESS_USE
;
1951 hprinter
= (HANDLE
) MAGIC_DEAD
;
1952 SetLastError(MAGIC_DEAD
);
1953 res
= OpenPrinterA(default_printer
, &hprinter
, &defaults
);
1954 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
1955 "returned %d with %d (expected '!=0' or '0' with "
1956 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
1957 if(res
) ClosePrinter(hprinter
);
1960 defaults
.DesiredAccess
=PRINTER_ALL_ACCESS
;
1961 hprinter
= (HANDLE
) MAGIC_DEAD
;
1962 SetLastError(MAGIC_DEAD
);
1963 res
= OpenPrinterA(default_printer
, &hprinter
, &defaults
);
1964 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
1965 "returned %d with %d (expected '!=0' or '0' with "
1966 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
1967 if(res
) ClosePrinter(hprinter
);
1973 static void test_SetDefaultPrinter(void)
1976 DWORD size
= DEFAULT_PRINTER_SIZE
;
1977 CHAR buffer
[DEFAULT_PRINTER_SIZE
];
1978 CHAR org_value
[DEFAULT_PRINTER_SIZE
];
1980 if (!default_printer
)
1982 skip("There is no default printer installed\n");
1986 if (!pSetDefaultPrinterA
) return;
1987 /* only supported on win2k and above */
1989 /* backup the original value */
1990 org_value
[0] = '\0';
1991 SetLastError(MAGIC_DEAD
);
1992 res
= GetProfileStringA("windows", "device", NULL
, org_value
, size
);
1993 ok(res
, "GetProfileString error %d\n", GetLastError());
1995 /* first part: with the default Printer */
1996 SetLastError(MAGIC_DEAD
);
1997 res
= pSetDefaultPrinterA("no_printer_with_this_name");
1998 if (is_spooler_deactivated(res
, GetLastError())) return;
2000 /* Not implemented in wine */
2001 if (!res
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)) {
2002 trace("SetDefaultPrinterA() not implemented yet.\n");
2006 ok(!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
),
2007 "returned %d with %d (expected '0' with "
2008 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2010 WriteProfileStringA("windows", "device", org_value
);
2011 SetLastError(MAGIC_DEAD
);
2012 res
= pSetDefaultPrinterA("");
2013 ok(res
|| GetLastError() == ERROR_INVALID_PRINTER_NAME
,
2014 "returned %d with %d (expected '!=0' or '0' with "
2015 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2017 WriteProfileStringA("windows", "device", org_value
);
2018 SetLastError(MAGIC_DEAD
);
2019 res
= pSetDefaultPrinterA(NULL
);
2020 ok(res
|| GetLastError() == ERROR_INVALID_PRINTER_NAME
,
2021 "returned %d with %d (expected '!=0' or '0' with "
2022 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2024 WriteProfileStringA("windows", "device", org_value
);
2025 SetLastError(MAGIC_DEAD
);
2026 res
= pSetDefaultPrinterA(default_printer
);
2027 ok(res
|| GetLastError() == ERROR_INVALID_PRINTER_NAME
,
2028 "returned %d with %d (expected '!=0' or '0' with "
2029 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2032 /* second part: always without a default Printer */
2033 WriteProfileStringA("windows", "device", NULL
);
2034 SetLastError(MAGIC_DEAD
);
2035 res
= pSetDefaultPrinterA("no_printer_with_this_name");
2037 ok(!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
),
2038 "returned %d with %d (expected '0' with "
2039 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2041 WriteProfileStringA("windows", "device", NULL
);
2042 SetLastError(MAGIC_DEAD
);
2043 res
= pSetDefaultPrinterA("");
2044 if (is_spooler_deactivated(res
, GetLastError()))
2045 goto restore_old_printer
;
2047 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2048 ok(res
|| GetLastError() == ERROR_INVALID_PRINTER_NAME
,
2049 "returned %d with %d (expected '!=0' or '0' with "
2050 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2052 WriteProfileStringA("windows", "device", NULL
);
2053 SetLastError(MAGIC_DEAD
);
2054 res
= pSetDefaultPrinterA(NULL
);
2055 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2056 ok(res
|| GetLastError() == ERROR_INVALID_PRINTER_NAME
,
2057 "returned %d with %d (expected '!=0' or '0' with "
2058 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2060 WriteProfileStringA("windows", "device", NULL
);
2061 SetLastError(MAGIC_DEAD
);
2062 res
= pSetDefaultPrinterA(default_printer
);
2063 ok(res
|| GetLastError() == ERROR_INVALID_PRINTER_NAME
,
2064 "returned %d with %d (expected '!=0' or '0' with "
2065 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2067 /* restore the original value */
2068 restore_old_printer
:
2069 res
= pSetDefaultPrinterA(default_printer
); /* the nice way */
2070 ok(res
, "SetDefaultPrinter error %d\n", GetLastError());
2071 WriteProfileStringA("windows", "device", org_value
); /* the old way */
2074 SetLastError(MAGIC_DEAD
);
2075 res
= GetProfileStringA("windows", "device", NULL
, buffer
, size
);
2076 ok(res
, "GetProfileString error %d\n", GetLastError());
2077 ok(!lstrcmpA(org_value
, buffer
), "'%s' (expected '%s')\n", buffer
, org_value
);
2081 /* ########################### */
2083 static void test_XcvDataW_MonitorUI(void)
2087 BYTE buffer
[MAX_PATH
+ 4];
2091 PRINTER_DEFAULTSA pd
;
2093 /* api is not present before w2k */
2094 if (pXcvDataW
== NULL
) return;
2096 pd
.pDatatype
= NULL
;
2098 pd
.DesiredAccess
= SERVER_ACCESS_ADMINISTER
;
2101 SetLastError(0xdeadbeef);
2102 res
= OpenPrinterA(xcv_localport
, &hXcv
, &pd
);
2103 if (is_spooler_deactivated(res
, GetLastError())) return;
2104 if (is_access_denied(res
, GetLastError())) return;
2106 ok(res
, "returned %d with %u and handle %p (expected '!= 0')\n", res
, GetLastError(), hXcv
);
2109 /* ask for needed size */
2110 needed
= (DWORD
) 0xdeadbeef;
2111 status
= (DWORD
) 0xdeadbeef;
2112 SetLastError(0xdeadbeef);
2113 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, NULL
, 0, &needed
, &status
);
2114 ok( res
&& (status
== ERROR_INSUFFICIENT_BUFFER
) && (needed
<= MAX_PATH
),
2115 "returned %d with %u and %u for status %u (expected '!= 0' and "
2116 "'<= MAX_PATH' for status ERROR_INSUFFICIENT_BUFFER)\n",
2117 res
, GetLastError(), needed
, status
);
2119 if (needed
> MAX_PATH
) {
2121 skip("buffer overflow (%u)\n", needed
);
2124 len
= needed
; /* Size is in bytes */
2126 /* the command is required */
2127 needed
= (DWORD
) 0xdeadbeef;
2128 status
= (DWORD
) 0xdeadbeef;
2129 SetLastError(0xdeadbeef);
2130 res
= pXcvDataW(hXcv
, emptyW
, NULL
, 0, NULL
, 0, &needed
, &status
);
2131 ok( res
&& (status
== ERROR_INVALID_PARAMETER
),
2132 "returned %d with %u and %u for status %u (expected '!= 0' with "
2133 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError(), needed
, status
);
2135 needed
= (DWORD
) 0xdeadbeef;
2136 status
= (DWORD
) 0xdeadbeef;
2137 SetLastError(0xdeadbeef);
2138 res
= pXcvDataW(hXcv
, NULL
, NULL
, 0, buffer
, MAX_PATH
, &needed
, &status
);
2139 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
),
2140 "returned %d with %u and %u for status %u (expected '0' with "
2141 "RPC_X_NULL_REF_POINTER)\n", res
, GetLastError(), needed
, status
);
2143 /* "PDWORD needed" is checked before RPC-Errors */
2144 needed
= (DWORD
) 0xdeadbeef;
2145 status
= (DWORD
) 0xdeadbeef;
2146 SetLastError(0xdeadbeef);
2147 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, NULL
, &status
);
2148 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
2149 "returned %d with %u and %u for status %u (expected '0' with "
2150 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError(), needed
, status
);
2152 needed
= (DWORD
) 0xdeadbeef;
2153 status
= (DWORD
) 0xdeadbeef;
2154 SetLastError(0xdeadbeef);
2155 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, NULL
, len
, &needed
, &status
);
2156 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
),
2157 "returned %d with %u and %u for status %u (expected '0' with "
2158 "RPC_X_NULL_REF_POINTER)\n", res
, GetLastError(), needed
, status
);
2160 needed
= (DWORD
) 0xdeadbeef;
2161 status
= (DWORD
) 0xdeadbeef;
2162 SetLastError(0xdeadbeef);
2163 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, &needed
, NULL
);
2164 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
),
2165 "returned %d with %u and %u for status %u (expected '0' with "
2166 "RPC_X_NULL_REF_POINTER)\n", res
, GetLastError(), needed
, status
);
2168 /* off by one: larger */
2169 needed
= (DWORD
) 0xdeadbeef;
2170 status
= (DWORD
) 0xdeadbeef;
2171 SetLastError(0xdeadbeef);
2172 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
+1, &needed
, &status
);
2173 ok( res
&& (status
== ERROR_SUCCESS
),
2174 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2175 "ERROR_SUCCESS)\n", res
, GetLastError(), needed
, status
);
2177 /* off by one: smaller */
2178 /* the buffer is not modified for NT4, w2k, XP */
2179 needed
= (DWORD
) 0xdeadbeef;
2180 status
= (DWORD
) 0xdeadbeef;
2181 SetLastError(0xdeadbeef);
2182 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
-1, &needed
, &status
);
2183 ok( res
&& (status
== ERROR_INSUFFICIENT_BUFFER
),
2184 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2185 "ERROR_INSUFFICIENT_BUFFER)\n", res
, GetLastError(), needed
, status
);
2188 /* Normal use. The DLL-Name without a Path is returned */
2189 memset(buffer
, 0, len
);
2190 needed
= (DWORD
) 0xdeadbeef;
2191 status
= (DWORD
) 0xdeadbeef;
2192 SetLastError(0xdeadbeef);
2193 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, &needed
, &status
);
2194 ok( res
&& (status
== ERROR_SUCCESS
),
2195 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2196 "ERROR_SUCCESS)\n", res
, GetLastError(), needed
, status
);
2201 /* ########################### */
2203 static void test_XcvDataW_PortIsValid(void)
2209 PRINTER_DEFAULTSA pd
;
2211 /* api is not present before w2k */
2212 if (pXcvDataW
== NULL
) return;
2214 pd
.pDatatype
= NULL
;
2216 pd
.DesiredAccess
= SERVER_ACCESS_ADMINISTER
;
2219 SetLastError(0xdeadbeef);
2220 res
= OpenPrinterA(xcv_localport
, &hXcv
, &pd
);
2221 if (is_spooler_deactivated(res
, GetLastError())) return;
2222 if (is_access_denied(res
, GetLastError())) return;
2224 ok(res
, "returned %d with %u and handle %p (expected '!= 0')\n", res
, GetLastError(), hXcv
);
2228 /* "PDWORD needed" is always required */
2229 needed
= (DWORD
) 0xdeadbeef;
2230 status
= (DWORD
) 0xdeadbeef;
2231 SetLastError(0xdeadbeef);
2232 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
), NULL
, 0, NULL
, &status
);
2233 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
2234 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_INVALID_PARAMETER)\n",
2235 res
, GetLastError(), needed
, status
);
2237 /* an empty name is not allowed */
2238 needed
= (DWORD
) 0xdeadbeef;
2239 status
= (DWORD
) 0xdeadbeef;
2240 SetLastError(0xdeadbeef);
2241 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) emptyW
, sizeof(emptyW
), NULL
, 0, &needed
, &status
);
2242 ok( res
&& ((status
== ERROR_FILE_NOT_FOUND
) || (status
== ERROR_PATH_NOT_FOUND
)),
2243 "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2244 "ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND)\n",
2245 res
, GetLastError(), needed
, status
);
2247 /* a directory is not allowed */
2248 needed
= (DWORD
) 0xdeadbeef;
2249 status
= (DWORD
) 0xdeadbeef;
2250 SetLastError(0xdeadbeef);
2251 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) tempdirW
, (lstrlenW(tempdirW
) + 1) * sizeof(WCHAR
), NULL
, 0, &needed
, &status
);
2252 /* XP: ERROR_PATH_NOT_FOUND, w2k ERROR_ACCESS_DENIED */
2253 ok( res
&& ((status
== ERROR_PATH_NOT_FOUND
) || (status
== ERROR_ACCESS_DENIED
)),
2254 "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2255 "ERROR_PATH_NOT_FOUND or ERROR_ACCESS_DENIED)\n",
2256 res
, GetLastError(), needed
, status
);
2258 /* more valid well known ports */
2259 needed
= (DWORD
) 0xdeadbeef;
2260 status
= (DWORD
) 0xdeadbeef;
2261 SetLastError(0xdeadbeef);
2262 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
), NULL
, 0, &needed
, &status
);
2263 ok( res
&& (status
== ERROR_SUCCESS
),
2264 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2265 res
, GetLastError(), needed
, status
);
2267 needed
= (DWORD
) 0xdeadbeef;
2268 status
= (DWORD
) 0xdeadbeef;
2269 SetLastError(0xdeadbeef);
2270 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt2W
, sizeof(portname_lpt2W
), NULL
, 0, &needed
, &status
);
2271 ok( res
&& (status
== ERROR_SUCCESS
),
2272 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2273 res
, GetLastError(), needed
, status
);
2275 needed
= (DWORD
) 0xdeadbeef;
2276 status
= (DWORD
) 0xdeadbeef;
2277 SetLastError(0xdeadbeef);
2278 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_com1W
, sizeof(portname_com1W
), NULL
, 0, &needed
, &status
);
2279 ok( res
&& (status
== ERROR_SUCCESS
),
2280 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2281 res
, GetLastError(), needed
, status
);
2283 needed
= (DWORD
) 0xdeadbeef;
2284 status
= (DWORD
) 0xdeadbeef;
2285 SetLastError(0xdeadbeef);
2286 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_com2W
, sizeof(portname_com2W
), NULL
, 0, &needed
, &status
);
2287 ok( res
&& (status
== ERROR_SUCCESS
),
2288 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2289 res
, GetLastError(), needed
, status
);
2291 needed
= (DWORD
) 0xdeadbeef;
2292 status
= (DWORD
) 0xdeadbeef;
2293 SetLastError(0xdeadbeef);
2294 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_fileW
, sizeof(portname_fileW
), NULL
, 0, &needed
, &status
);
2295 ok( res
&& (status
== ERROR_SUCCESS
),
2296 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2297 res
, GetLastError(), needed
, status
);
2300 /* a normal, writable file is allowed */
2301 needed
= (DWORD
) 0xdeadbeef;
2302 status
= (DWORD
) 0xdeadbeef;
2303 SetLastError(0xdeadbeef);
2304 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) tempfileW
, (lstrlenW(tempfileW
) + 1) * sizeof(WCHAR
), NULL
, 0, &needed
, &status
);
2305 ok( res
&& (status
== ERROR_SUCCESS
),
2306 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2307 res
, GetLastError(), needed
, status
);
2312 /* ########################### */
2314 static void test_GetPrinter(void)
2320 DWORD needed
, filled
;
2322 if (!default_printer
)
2324 skip("There is no default printer installed\n");
2329 ret
= OpenPrinterA(default_printer
, &hprn
, NULL
);
2332 skip("Unable to open the default printer (%s)\n", default_printer
);
2335 ok(hprn
!= 0, "wrong hprn %p\n", hprn
);
2337 for (level
= 1; level
<= 9; level
++)
2339 SetLastError(0xdeadbeef);
2341 ret
= GetPrinterA(hprn
, level
, NULL
, 0, &needed
);
2344 win_skip("Level %d is not supported on Win9x/WinMe\n", level
);
2345 ok(GetLastError() == ERROR_SUCCESS
, "wrong error %d\n", GetLastError());
2346 ok(needed
== 0,"Expected 0, got %d\n", needed
);
2349 ok(!ret
, "level %d: GetPrinter should fail\n", level
);
2350 /* Not all levels are supported on all Windows-Versions */
2351 if (GetLastError() == ERROR_INVALID_LEVEL
||
2352 GetLastError() == ERROR_NOT_SUPPORTED
/* Win9x/WinMe */)
2354 skip("Level %d not supported\n", level
);
2357 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %d\n", GetLastError());
2358 ok(needed
> 0,"not expected needed buffer size %d\n", needed
);
2360 /* GetPrinterA returns the same number of bytes as GetPrinterW */
2361 if (!on_win9x
&& !ret
&& pGetPrinterW
&& level
!= 6 && level
!= 7)
2363 DWORD double_needed
;
2364 ret
= pGetPrinterW(hprn
, level
, NULL
, 0, &double_needed
);
2365 ok(!ret
, "level %d: GetPrinter error %d\n", level
, GetLastError());
2366 ok(double_needed
== needed
, "level %d: GetPrinterA returned different size %d than GetPrinterW (%d)\n", level
, needed
, double_needed
);
2369 buf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2371 SetLastError(0xdeadbeef);
2373 ret
= GetPrinterA(hprn
, level
, buf
, needed
, &filled
);
2374 ok(ret
, "level %d: GetPrinter error %d\n", level
, GetLastError());
2375 ok(needed
== filled
, "needed %d != filled %d\n", needed
, filled
);
2379 PRINTER_INFO_2A
*pi_2
= (PRINTER_INFO_2A
*)buf
;
2381 ok(pi_2
->pPrinterName
!= NULL
, "not expected NULL ptr\n");
2382 ok(pi_2
->pDriverName
!= NULL
, "not expected NULL ptr\n");
2384 trace("pPrinterName %s\n", pi_2
->pPrinterName
);
2385 trace("pDriverName %s\n", pi_2
->pDriverName
);
2388 HeapFree(GetProcessHeap(), 0, buf
);
2391 SetLastError(0xdeadbeef);
2392 ret
= ClosePrinter(hprn
);
2393 ok(ret
, "ClosePrinter error %d\n", GetLastError());
2396 /* ########################### */
2398 static void test_GetPrinterData(void)
2403 CHAR buffer
[MAX_PATH
+ 1];
2407 /* ToDo: test parameter validation, test with the default printer */
2409 SetLastError(0xdeadbeef);
2410 res
= OpenPrinterA(NULL
, &hprn
, NULL
);
2413 /* printserver not available on win9x */
2415 win_skip("Unable to open the printserver: %d\n", GetLastError());
2419 memset(buffer
, '#', sizeof(buffer
));
2420 buffer
[MAX_PATH
] = 0;
2422 needed
= 0xdeadbeef;
2423 SetLastError(0xdeadbeef);
2424 res
= GetPrinterDataA(hprn
, defaultspooldirectory
, &type
, (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2426 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2427 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2428 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2429 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2430 res
, type
, needed
, buffer
, len
);
2432 needed
= 0xdeadbeef;
2433 SetLastError(0xdeadbeef);
2434 res
= GetPrinterDataA(hprn
, defaultspooldirectory
, NULL
, NULL
, 0, &needed
);
2435 ok( (res
== ERROR_MORE_DATA
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2436 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res
, needed
, len
);
2438 /* ToDo: test SPLREG_* */
2440 SetLastError(0xdeadbeef);
2441 res
= ClosePrinter(hprn
);
2442 ok(res
, "ClosePrinter error %d\n", GetLastError());
2445 /* ########################### */
2447 static void test_GetPrinterDataEx(void)
2452 CHAR buffer
[MAX_PATH
+ 1];
2456 /* not present before w2k */
2457 if (!pGetPrinterDataExA
) {
2458 win_skip("GetPrinterDataEx not found\n");
2462 /* ToDo: test parameter validation, test with the default printer */
2464 SetLastError(0xdeadbeef);
2465 res
= OpenPrinterA(NULL
, &hprn
, NULL
);
2468 win_skip("Unable to open the printserver: %d\n", GetLastError());
2472 /* keyname is ignored, when hprn is a HANDLE for a printserver */
2473 memset(buffer
, '#', sizeof(buffer
));
2474 buffer
[MAX_PATH
] = 0;
2476 needed
= 0xdeadbeef;
2477 SetLastError(0xdeadbeef);
2478 res
= pGetPrinterDataExA(hprn
, NULL
, defaultspooldirectory
, &type
,
2479 (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2481 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2482 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2483 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2484 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2485 res
, type
, needed
, buffer
, len
);
2487 memset(buffer
, '#', sizeof(buffer
));
2488 buffer
[MAX_PATH
] = 0;
2490 needed
= 0xdeadbeef;
2491 SetLastError(0xdeadbeef);
2492 res
= pGetPrinterDataExA(hprn
, "", defaultspooldirectory
, &type
,
2493 (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2494 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2495 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2496 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2497 res
, type
, needed
, buffer
, len
);
2499 memset(buffer
, '#', sizeof(buffer
));
2500 buffer
[MAX_PATH
] = 0;
2502 needed
= 0xdeadbeef;
2503 SetLastError(0xdeadbeef);
2504 /* Wine uses GetPrinterDataEx with "PrinterDriverData" to implement GetPrinterData */
2505 res
= pGetPrinterDataExA(hprn
, "PrinterDriverData", defaultspooldirectory
,
2506 &type
, (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2507 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2508 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2509 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2510 res
, type
, needed
, buffer
, len
);
2513 memset(buffer
, '#', sizeof(buffer
));
2514 buffer
[MAX_PATH
] = 0;
2516 needed
= 0xdeadbeef;
2517 SetLastError(0xdeadbeef);
2518 res
= pGetPrinterDataExA(hprn
, does_not_exist
, defaultspooldirectory
, &type
,
2519 (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2520 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2521 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2522 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2523 res
, type
, needed
, buffer
, len
);
2525 needed
= 0xdeadbeef;
2526 SetLastError(0xdeadbeef);
2527 /* vista and w2k8 have a bug in GetPrinterDataEx:
2528 the current LastError value is returned as result */
2529 res
= pGetPrinterDataExA(hprn
, NULL
, defaultspooldirectory
, NULL
, NULL
, 0, &needed
);
2530 ok( ((res
== ERROR_MORE_DATA
) || broken(res
== 0xdeadbeef)) &&
2531 ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2532 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res
, needed
, len
);
2534 needed
= 0xdeadbeef;
2535 SetLastError(0xdeaddead);
2536 res
= pGetPrinterDataExA(hprn
, NULL
, defaultspooldirectory
, NULL
, NULL
, 0, &needed
);
2537 ok( ((res
== ERROR_MORE_DATA
) || broken(res
== 0xdeaddead)) &&
2538 ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2539 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res
, needed
, len
);
2541 SetLastError(0xdeadbeef);
2542 res
= ClosePrinter(hprn
);
2543 ok(res
, "ClosePrinter error %d\n", GetLastError());
2546 /* ########################### */
2548 static void test_GetPrinterDriver(void)
2554 DWORD needed
, filled
;
2556 if (!default_printer
)
2558 skip("There is no default printer installed\n");
2563 ret
= OpenPrinterA(default_printer
, &hprn
, NULL
);
2566 skip("Unable to open the default printer (%s)\n", default_printer
);
2569 ok(hprn
!= 0, "wrong hprn %p\n", hprn
);
2571 for (level
= -1; level
<= 7; level
++)
2573 SetLastError(0xdeadbeef);
2575 ret
= GetPrinterDriverA(hprn
, NULL
, level
, NULL
, 0, &needed
);
2576 ok(!ret
, "level %d: GetPrinterDriver should fail\n", level
);
2577 if (level
>= 1 && level
<= 6)
2579 /* Not all levels are supported on all Windows-Versions */
2580 if(GetLastError() == ERROR_INVALID_LEVEL
) continue;
2581 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %d\n", GetLastError());
2582 ok(needed
> 0,"not expected needed buffer size %d\n", needed
);
2586 /* ERROR_OUTOFMEMORY found on win9x */
2587 ok( ((GetLastError() == ERROR_INVALID_LEVEL
) ||
2588 (GetLastError() == ERROR_OUTOFMEMORY
)),
2589 "%d: returned %d with %d (expected '0' with: "
2590 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
2591 level
, ret
, GetLastError());
2592 /* needed is modified in win9x. The modified Value depends on the
2593 default Printer. testing for "needed == (DWORD)-1" will fail */
2597 /* GetPrinterDriverA returns the same number of bytes as GetPrinterDriverW */
2598 if (!on_win9x
&& !ret
&& pGetPrinterDriverW
)
2600 DWORD double_needed
;
2601 ret
= pGetPrinterDriverW(hprn
, NULL
, level
, NULL
, 0, &double_needed
);
2602 ok(!ret
, "level %d: GetPrinterDriver error %d\n", level
, GetLastError());
2603 ok(double_needed
== needed
, "GetPrinterDriverA returned different size %d than GetPrinterDriverW (%d)\n", needed
, double_needed
);
2606 buf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2608 SetLastError(0xdeadbeef);
2610 ret
= GetPrinterDriverA(hprn
, NULL
, level
, buf
, needed
, &filled
);
2611 ok(ret
, "level %d: GetPrinterDriver error %d\n", level
, GetLastError());
2612 ok(needed
== filled
, "needed %d != filled %d\n", needed
, filled
);
2616 DRIVER_INFO_2A
*di_2
= (DRIVER_INFO_2A
*)buf
;
2617 DWORD calculated
= sizeof(*di_2
);
2620 /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
2621 NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k-win7(Usermode): 3, win8 and above(Usermode): 4 */
2622 ok( (di_2
->cVersion
<= 4) ||
2623 (di_2
->cVersion
== 0x0400), "di_2->cVersion = %d\n", di_2
->cVersion
);
2624 ok(di_2
->pName
!= NULL
, "not expected NULL ptr\n");
2625 ok(di_2
->pEnvironment
!= NULL
, "not expected NULL ptr\n");
2626 ok(di_2
->pDriverPath
!= NULL
, "not expected NULL ptr\n");
2627 ok(di_2
->pDataFile
!= NULL
, "not expected NULL ptr\n");
2628 ok(di_2
->pConfigFile
!= NULL
, "not expected NULL ptr\n");
2630 trace("cVersion %d\n", di_2
->cVersion
);
2631 trace("pName %s\n", di_2
->pName
);
2632 calculated
+= strlen(di_2
->pName
) + 1;
2633 trace("pEnvironment %s\n", di_2
->pEnvironment
);
2634 calculated
+= strlen(di_2
->pEnvironment
) + 1;
2635 trace("pDriverPath %s\n", di_2
->pDriverPath
);
2636 calculated
+= strlen(di_2
->pDriverPath
) + 1;
2637 trace("pDataFile %s\n", di_2
->pDataFile
);
2638 calculated
+= strlen(di_2
->pDataFile
) + 1;
2639 trace("pConfigFile %s\n", di_2
->pConfigFile
);
2640 calculated
+= strlen(di_2
->pConfigFile
) + 1;
2642 hf
= CreateFileA(di_2
->pDriverPath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2643 if(hf
!= INVALID_HANDLE_VALUE
)
2646 ok(hf
!= INVALID_HANDLE_VALUE
, "Could not open %s\n", di_2
->pDriverPath
);
2648 hf
= CreateFileA(di_2
->pDataFile
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2649 if(hf
!= INVALID_HANDLE_VALUE
)
2651 ok(hf
!= INVALID_HANDLE_VALUE
, "Could not open %s\n", di_2
->pDataFile
);
2653 hf
= CreateFileA(di_2
->pConfigFile
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2654 if(hf
!= INVALID_HANDLE_VALUE
)
2657 ok(hf
!= INVALID_HANDLE_VALUE
, "Could not open %s\n", di_2
->pConfigFile
);
2659 /* XP allocates memory for both ANSI and unicode names */
2660 ok(filled
>= calculated
,"calculated %d != filled %d\n", calculated
, filled
);
2662 /* Obscure test - demonstrate that Windows zero fills the buffer, even on failure */
2663 ret
= GetPrinterDriverA(hprn
, NULL
, level
, buf
, needed
- 2, &filled
);
2664 ok(!ret
, "level %d: GetPrinterDriver succeeded with less buffer than it should\n", level
);
2665 ok(di_2
->pDataFile
== NULL
||
2666 broken(di_2
->pDataFile
!= NULL
), /* Win9x/WinMe */
2667 "Even on failure, GetPrinterDriver clears the buffer to zeros\n");
2670 HeapFree(GetProcessHeap(), 0, buf
);
2673 SetLastError(0xdeadbeef);
2674 ret
= ClosePrinter(hprn
);
2675 ok(ret
, "ClosePrinter error %d\n", GetLastError());
2678 static void test_DEVMODEA(const DEVMODEA
*dm
, LONG dmSize
, LPCSTR exp_prn_name
)
2680 /* On NT3.51, some fields in DEVMODEA are empty/zero
2681 (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
2682 We skip the Tests on this Platform */
2683 if (dm
->dmSpecVersion
|| dm
->dmDriverVersion
|| dm
->dmDriverExtra
) {
2684 /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
2685 ok(!strncmp(exp_prn_name
, (LPCSTR
)dm
->dmDeviceName
, CCHDEVICENAME
-1) ||
2686 !strncmp(exp_prn_name
, (LPCSTR
)dm
->dmDeviceName
, CCHDEVICENAME
-2), /* XP+ */
2687 "expected '%s', got '%s'\n", exp_prn_name
, dm
->dmDeviceName
);
2688 ok(dm
->dmSize
+ dm
->dmDriverExtra
== dmSize
,
2689 "%u != %d\n", dm
->dmSize
+ dm
->dmDriverExtra
, dmSize
);
2691 trace("dmFields %08x\n", dm
->dmFields
);
2694 static void test_DocumentProperties(void)
2699 char empty_str
[] = "";
2701 if (!default_printer
)
2703 skip("There is no default printer installed\n");
2708 ret
= OpenPrinterA(default_printer
, &hprn
, NULL
);
2711 skip("Unable to open the default printer (%s)\n", default_printer
);
2714 ok(hprn
!= 0, "wrong hprn %p\n", hprn
);
2716 dm_size
= DocumentPropertiesA(0, hprn
, NULL
, NULL
, NULL
, 0);
2717 trace("DEVMODEA required size %d\n", dm_size
);
2718 ok(dm_size
>= sizeof(DEVMODEA
), "unexpected DocumentPropertiesA ret value %d\n", dm_size
);
2720 dm
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dm_size
);
2722 ret
= DocumentPropertiesA(0, hprn
, NULL
, dm
, dm
, DM_OUT_BUFFER
);
2723 ok(ret
== IDOK
, "DocumentPropertiesA ret value %d != expected IDOK\n", ret
);
2725 ret
= DocumentPropertiesA(0, hprn
, empty_str
, dm
, dm
, DM_OUT_BUFFER
);
2726 ok(ret
== IDOK
, "DocumentPropertiesA ret value %d != expected IDOK\n", ret
);
2728 test_DEVMODEA(dm
, dm_size
, default_printer
);
2730 HeapFree(GetProcessHeap(), 0, dm
);
2732 SetLastError(0xdeadbeef);
2733 ret
= ClosePrinter(hprn
);
2734 ok(ret
, "ClosePrinter error %d\n", GetLastError());
2737 static void test_EnumPrinters(void)
2739 DWORD neededA
, neededW
, num
;
2742 SetLastError(0xdeadbeef);
2744 ret
= EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &neededA
, &num
);
2745 if (is_spooler_deactivated(ret
, GetLastError())) return;
2748 /* We have 1 or more printers */
2749 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "gle %d\n", GetLastError());
2750 ok(neededA
> 0, "Expected neededA to show the number of needed bytes\n");
2754 /* We don't have any printers defined */
2755 ok(GetLastError() == S_OK
, "gle %d\n", GetLastError());
2756 ok(neededA
== 0, "Expected neededA to be zero\n");
2758 ok(num
== 0, "num %d\n", num
);
2760 SetLastError(0xdeadbeef);
2762 ret
= EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &neededW
, &num
);
2763 /* EnumPrintersW is not supported on all platforms */
2764 if (!ret
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
2766 win_skip("EnumPrintersW is not implemented\n");
2772 /* We have 1 or more printers */
2773 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "gle %d\n", GetLastError());
2774 ok(neededW
> 0, "Expected neededW to show the number of needed bytes\n");
2778 /* We don't have any printers defined */
2779 ok(GetLastError() == S_OK
, "gle %d\n", GetLastError());
2780 ok(neededW
== 0, "Expected neededW to be zero\n");
2782 ok(num
== 0, "num %d\n", num
);
2784 /* Outlook2003 relies on the buffer size returned by EnumPrintersA being big enough
2785 to hold the buffer returned by EnumPrintersW */
2786 ok(neededA
== neededW
, "neededA %d neededW %d\n", neededA
, neededW
);
2789 static void test_DeviceCapabilities(void)
2792 BOOL (WINAPI
*pPrintDlgA
)(PRINTDLGA
*);
2796 const char *driver
, *device
, *port
;
2804 INT n_papers
, n_paper_size
, n_paper_names
, n_copies
, ret
;
2807 hComdlg32
= LoadLibraryA("comdlg32.dll");
2809 pPrintDlgA
= (void *)GetProcAddress(hComdlg32
, "PrintDlgA");
2812 memset(&prn_dlg
, 0, sizeof(prn_dlg
));
2813 prn_dlg
.lStructSize
= sizeof(prn_dlg
);
2814 prn_dlg
.Flags
= PD_RETURNDEFAULT
;
2815 ret
= pPrintDlgA(&prn_dlg
);
2816 FreeLibrary(hComdlg32
);
2819 skip("PrintDlg returned no default printer\n");
2822 ok(prn_dlg
.hDevMode
!= 0, "PrintDlg returned hDevMode == NULL\n");
2823 ok(prn_dlg
.hDevNames
!= 0, "PrintDlg returned hDevNames == NULL\n");
2825 dm
= GlobalLock(prn_dlg
.hDevMode
);
2826 ok(dm
!= NULL
, "GlobalLock(prn_dlg.hDevMode) failed\n");
2827 trace("dmDeviceName \"%s\"\n", dm
->dmDeviceName
);
2829 dn
= GlobalLock(prn_dlg
.hDevNames
);
2830 ok(dn
!= NULL
, "GlobalLock(prn_dlg.hDevNames) failed\n");
2831 ok(dn
->wDriverOffset
, "expected not 0 wDriverOffset\n");
2832 ok(dn
->wDeviceOffset
, "expected not 0 wDeviceOffset\n");
2833 ok(dn
->wOutputOffset
, "expected not 0 wOutputOffset\n");
2834 ok(dn
->wDefault
== DN_DEFAULTPRN
, "expected DN_DEFAULTPRN got %x\n", dn
->wDefault
);
2835 driver
= (const char *)dn
+ dn
->wDriverOffset
;
2836 device
= (const char *)dn
+ dn
->wDeviceOffset
;
2837 port
= (const char *)dn
+ dn
->wOutputOffset
;
2838 trace("driver \"%s\" device \"%s\" port \"%s\"\n", driver
, device
, port
);
2840 test_DEVMODEA(dm
, dm
->dmSize
+ dm
->dmDriverExtra
, device
);
2842 n_papers
= DeviceCapabilitiesA(device
, port
, DC_PAPERS
, NULL
, NULL
);
2843 ok(n_papers
> 0, "DeviceCapabilitiesA DC_PAPERS failed\n");
2844 papers
= HeapAlloc(GetProcessHeap(), 0, sizeof(*papers
) * n_papers
);
2845 ret
= DeviceCapabilitiesA(device
, port
, DC_PAPERS
, (LPSTR
)papers
, NULL
);
2846 ok(ret
== n_papers
, "expected %d, got %d\n", n_papers
, ret
);
2848 for (ret
= 0; ret
< n_papers
; ret
++)
2849 trace("papers[%d] = %d\n", ret
, papers
[ret
]);
2851 HeapFree(GetProcessHeap(), 0, papers
);
2853 n_paper_size
= DeviceCapabilitiesA(device
, port
, DC_PAPERSIZE
, NULL
, NULL
);
2854 ok(n_paper_size
> 0, "DeviceCapabilitiesA DC_PAPERSIZE failed\n");
2855 ok(n_paper_size
== n_papers
, "n_paper_size %d != n_papers %d\n", n_paper_size
, n_papers
);
2856 paper_size
= HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_size
) * n_paper_size
);
2857 ret
= DeviceCapabilitiesA(device
, port
, DC_PAPERSIZE
, (LPSTR
)paper_size
, NULL
);
2858 ok(ret
== n_paper_size
, "expected %d, got %d\n", n_paper_size
, ret
);
2860 for (ret
= 0; ret
< n_paper_size
; ret
++)
2861 trace("paper_size[%d] = %d x %d\n", ret
, paper_size
[ret
].x
, paper_size
[ret
].y
);
2863 HeapFree(GetProcessHeap(), 0, paper_size
);
2865 n_paper_names
= DeviceCapabilitiesA(device
, port
, DC_PAPERNAMES
, NULL
, NULL
);
2866 ok(n_paper_names
> 0, "DeviceCapabilitiesA DC_PAPERNAMES failed\n");
2867 ok(n_paper_names
== n_papers
, "n_paper_names %d != n_papers %d\n", n_paper_names
, n_papers
);
2868 paper_name
= HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_name
) * n_paper_names
);
2869 ret
= DeviceCapabilitiesA(device
, port
, DC_PAPERNAMES
, (LPSTR
)paper_name
, NULL
);
2870 ok(ret
== n_paper_names
, "expected %d, got %d\n", n_paper_names
, ret
);
2872 for (ret
= 0; ret
< n_paper_names
; ret
++)
2873 trace("paper_name[%u] = %s\n", ret
, paper_name
[ret
].name
);
2875 HeapFree(GetProcessHeap(), 0, paper_name
);
2877 n_copies
= DeviceCapabilitiesA(device
, port
, DC_COPIES
, NULL
, dm
);
2878 ok(n_copies
> 0, "DeviceCapabilitiesA DC_COPIES failed\n");
2879 trace("n_copies = %d\n", n_copies
);
2881 /* these capabilities are not available on all printer drivers */
2884 ret
= DeviceCapabilitiesA(device
, port
, DC_MAXEXTENT
, NULL
, NULL
);
2885 ok(ret
!= -1, "DeviceCapabilitiesA DC_MAXEXTENT failed\n");
2886 ext
= MAKEPOINTS(ret
);
2887 trace("max ext = %d x %d\n", ext
.x
, ext
.y
);
2889 ret
= DeviceCapabilitiesA(device
, port
, DC_MINEXTENT
, NULL
, NULL
);
2890 ok(ret
!= -1, "DeviceCapabilitiesA DC_MINEXTENT failed\n");
2891 ext
= MAKEPOINTS(ret
);
2892 trace("min ext = %d x %d\n", ext
.x
, ext
.y
);
2895 fields
= DeviceCapabilitiesA(device
, port
, DC_FIELDS
, NULL
, NULL
);
2896 ok(fields
!= (DWORD
)-1, "DeviceCapabilitiesA DC_FIELDS failed\n");
2897 ok(fields
== (dm
->dmFields
| DM_FORMNAME
) ||
2898 fields
== ((dm
->dmFields
| DM_FORMNAME
| DM_PAPERSIZE
) & ~(DM_PAPERLENGTH
|DM_PAPERWIDTH
)) ||
2899 broken(fields
== dm
->dmFields
), /* Win9x/WinMe */
2900 "fields %x, dm->dmFields %x\n", fields
, dm
->dmFields
);
2902 GlobalUnlock(prn_dlg
.hDevMode
);
2903 GlobalFree(prn_dlg
.hDevMode
);
2904 GlobalUnlock(prn_dlg
.hDevNames
);
2905 GlobalFree(prn_dlg
.hDevNames
);
2908 static void test_IsValidDevmodeW(void)
2912 if (!pIsValidDevmodeW
)
2914 win_skip("IsValidDevmodeW not implemented.\n");
2918 br
= pIsValidDevmodeW(NULL
, 0);
2919 ok(br
== FALSE
, "Got %d\n", br
);
2921 br
= pIsValidDevmodeW(NULL
, 1);
2922 ok(br
== FALSE
, "Got %d\n", br
);
2924 br
= pIsValidDevmodeW(NULL
, sizeof(DEVMODEW
));
2925 ok(br
== FALSE
, "Got %d\n", br
);
2928 static void test_OpenPrinter_defaults(void)
2934 ADDJOB_INFO_1A
*add_job
;
2935 JOB_INFO_2A
*job_info
;
2937 PRINTER_DEFAULTSA prn_def
;
2938 PRINTER_INFO_2A
*pi
;
2940 if (!default_printer
)
2942 skip("There is no default printer installed\n");
2946 /* Printer opened with NULL defaults. Retrieve default paper size
2947 and confirm that jobs have this size. */
2949 ret
= OpenPrinterA( default_printer
, &printer
, NULL
);
2952 skip("Unable to open the default printer (%s)\n", default_printer
);
2956 ret
= GetPrinterA( printer
, 2, NULL
, 0, &needed
);
2957 ok( !ret
, "got %d\n", ret
);
2958 pi
= HeapAlloc( GetProcessHeap(), 0, needed
);
2959 ret
= GetPrinterA( printer
, 2, (BYTE
*)pi
, needed
, &needed
);
2960 ok( ret
, "GetPrinterA() failed le=%d\n", GetLastError() );
2961 default_size
= pi
->pDevMode
->u1
.s1
.dmPaperSize
;
2962 HeapFree( GetProcessHeap(), 0, pi
);
2965 SetLastError( 0xdeadbeef );
2966 ret
= AddJobA( printer
, 1, NULL
, 0, &needed
);
2967 ok( !ret
, "got %d\n", ret
);
2968 if (GetLastError() == ERROR_NOT_SUPPORTED
) /* win8 */
2970 win_skip( "AddJob is not supported on this platform\n" );
2971 ClosePrinter( printer
);
2974 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError() );
2975 ok( needed
> sizeof(ADDJOB_INFO_1A
), "AddJob needs %u bytes\n", needed
);
2976 add_job
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, needed
);
2977 ret
= AddJobA( printer
, 1, (BYTE
*)add_job
, needed
, &needed
);
2978 ok( ret
, "AddJobA() failed le=%d\n", GetLastError() );
2980 ret
= GetJobA( printer
, add_job
->JobId
, 2, NULL
, 0, &needed
);
2981 ok( !ret
, "got %d\n", ret
);
2982 job_info
= HeapAlloc( GetProcessHeap(), 0, needed
);
2983 ret
= GetJobA( printer
, add_job
->JobId
, 2, (BYTE
*)job_info
, needed
, &needed
);
2984 ok( ret
, "GetJobA() failed le=%d\n", GetLastError() );
2987 ok( job_info
->pDevMode
!= NULL
, "got NULL DEVMODEA\n");
2988 if (job_info
->pDevMode
)
2989 ok( job_info
->pDevMode
->u1
.s1
.dmPaperSize
== default_size
, "got %d default %d\n",
2990 job_info
->pDevMode
->u1
.s1
.dmPaperSize
, default_size
);
2992 HeapFree( GetProcessHeap(), 0, job_info
);
2993 ScheduleJob( printer
, add_job
->JobId
); /* remove the empty job */
2994 HeapFree( GetProcessHeap(), 0, add_job
);
2995 ClosePrinter( printer
);
2997 /* Printer opened with something other than the default paper size. */
2999 memset( &my_dm
, 0, sizeof(my_dm
) );
3000 my_dm
.dmSize
= sizeof(my_dm
);
3001 my_dm
.dmFields
= DM_PAPERSIZE
;
3002 my_dm
.u1
.s1
.dmPaperSize
= (default_size
== DMPAPER_A4
) ? DMPAPER_LETTER
: DMPAPER_A4
;
3004 prn_def
.pDatatype
= NULL
;
3005 prn_def
.pDevMode
= &my_dm
;
3006 prn_def
.DesiredAccess
= PRINTER_ACCESS_USE
;
3008 ret
= OpenPrinterA( default_printer
, &printer
, &prn_def
);
3009 ok( ret
, "OpenPrinterA() failed le=%d\n", GetLastError() );
3011 /* GetPrinter stills returns default size */
3012 ret
= GetPrinterA( printer
, 2, NULL
, 0, &needed
);
3013 ok( !ret
, "got %d\n", ret
);
3014 pi
= HeapAlloc( GetProcessHeap(), 0, needed
);
3015 ret
= GetPrinterA( printer
, 2, (BYTE
*)pi
, needed
, &needed
);
3016 ok( ret
, "GetPrinterA() failed le=%d\n", GetLastError() );
3017 ok( pi
->pDevMode
->u1
.s1
.dmPaperSize
== default_size
, "got %d default %d\n",
3018 pi
->pDevMode
->u1
.s1
.dmPaperSize
, default_size
);
3020 HeapFree( GetProcessHeap(), 0, pi
);
3022 /* However the GetJobA has the new size */
3023 ret
= AddJobA( printer
, 1, NULL
, 0, &needed
);
3024 ok( !ret
, "got %d\n", ret
);
3025 add_job
= HeapAlloc( GetProcessHeap(), 0, needed
);
3026 ret
= AddJobA( printer
, 1, (BYTE
*)add_job
, needed
, &needed
);
3027 ok( ret
, "AddJobA() failed le=%d\n", GetLastError() );
3029 ret
= GetJobA( printer
, add_job
->JobId
, 2, NULL
, 0, &needed
);
3030 ok( !ret
, "got %d\n", ret
);
3031 job_info
= HeapAlloc( GetProcessHeap(), 0, needed
);
3032 ret
= GetJobA( printer
, add_job
->JobId
, 2, (BYTE
*)job_info
, needed
, &needed
);
3033 ok( ret
, "GetJobA() failed le=%d\n", GetLastError() );
3035 ok( job_info
->pDevMode
->dmFields
== DM_PAPERSIZE
, "got %08x\n",
3036 job_info
->pDevMode
->dmFields
);
3037 ok( job_info
->pDevMode
->u1
.s1
.dmPaperSize
== my_dm
.u1
.s1
.dmPaperSize
,
3038 "got %d new size %d\n",
3039 job_info
->pDevMode
->u1
.s1
.dmPaperSize
, my_dm
.u1
.s1
.dmPaperSize
);
3041 HeapFree( GetProcessHeap(), 0, job_info
);
3042 ScheduleJob( printer
, add_job
->JobId
); /* remove the empty job */
3043 HeapFree( GetProcessHeap(), 0, add_job
);
3044 ClosePrinter( printer
);
3049 hwinspool
= LoadLibraryA("winspool.drv");
3050 pAddPortExA
= (void *) GetProcAddress(hwinspool
, "AddPortExA");
3051 pEnumPrinterDriversW
= (void *) GetProcAddress(hwinspool
, "EnumPrinterDriversW");
3052 pGetDefaultPrinterA
= (void *) GetProcAddress(hwinspool
, "GetDefaultPrinterA");
3053 pGetPrinterDataExA
= (void *) GetProcAddress(hwinspool
, "GetPrinterDataExA");
3054 pGetPrinterDriverW
= (void *) GetProcAddress(hwinspool
, "GetPrinterDriverW");
3055 pGetPrinterW
= (void *) GetProcAddress(hwinspool
, "GetPrinterW");
3056 pSetDefaultPrinterA
= (void *) GetProcAddress(hwinspool
, "SetDefaultPrinterA");
3057 pXcvDataW
= (void *) GetProcAddress(hwinspool
, "XcvDataW");
3058 pIsValidDevmodeW
= (void *) GetProcAddress(hwinspool
, "IsValidDevmodeW");
3060 on_win9x
= check_win9x();
3062 win_skip("Several W-functions are not available on Win9x/WinMe\n");
3064 find_default_printer();
3065 find_local_server();
3071 test_ConfigurePort();
3072 test_ClosePrinter();
3073 test_DeleteMonitor();
3075 test_DeviceCapabilities();
3076 test_DocumentProperties();
3077 test_EnumForms(NULL
);
3078 if (default_printer
) test_EnumForms(default_printer
);
3079 test_EnumMonitors();
3081 test_EnumPrinterDrivers();
3082 test_EnumPrinters();
3083 test_EnumPrintProcessors();
3084 test_GetDefaultPrinter();
3085 test_GetPrinterDriverDirectory();
3086 test_GetPrintProcessorDirectory();
3087 test_IsValidDevmodeW();
3089 test_OpenPrinter_defaults();
3091 test_GetPrinterData();
3092 test_GetPrinterDataEx();
3093 test_GetPrinterDriver();
3094 test_SetDefaultPrinter();
3095 test_XcvDataW_MonitorUI();
3096 test_XcvDataW_PortIsValid();
3098 /* Cleanup our temporary file */
3099 DeleteFileA(tempfileA
);