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 WCHAR cmd_MonitorUIW
[] = {'M','o','n','i','t','o','r','U','I',0};
60 static WCHAR cmd_PortIsValidW
[] = {'P','o','r','t','I','s','V','a','l','i','d',0};
61 static WCHAR emptyW
[] = {0};
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 (RegOpenKeyEx(HKEY_CURRENT_USER
,
162 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
163 0, KEY_QUERY_VALUE
, &hwindows
) == NO_ERROR
) {
165 needed
= sizeof(buffer
);
166 if (RegQueryValueEx(hwindows
, "device", NULL
,
167 &type
, (LPBYTE
)buffer
, &needed
) == NO_ERROR
) {
169 ptr
= strchr(buffer
, ',');
172 default_printer
= buffer
;
175 RegCloseKey(hwindows
);
177 trace("default_printer: '%s'\n", default_printer
? default_printer
: "(null)");
179 if (default_printer
== NULL
)
182 needed
= sizeof(buffer
);
183 res
= GetProfileStringA("windows", "device", "*", buffer
, needed
);
185 ptr
= strchr(buffer
, ',');
188 default_printer
= buffer
;
191 trace("default_printer: '%s'\n", default_printer
? default_printer
: "(null)");
196 static struct monitor_entry
* find_installed_monitor(void)
198 MONITOR_INFO_2A mi2a
;
199 static struct monitor_entry
* entry
= NULL
;
203 static struct monitor_entry monitor_table
[] = {
204 {env_win9x_case
, "localspl.dll"},
205 {env_x86
, "localspl.dll"},
206 {env_x64
, "localspl.dll"},
207 {env_win9x_case
, "localmon.dll"},
208 {env_x86
, "localmon.dll"},
209 {env_win9x_case
, "tcpmon.dll"},
210 {env_x86
, "tcpmon.dll"},
211 {env_win9x_case
, "usbmon.dll"},
212 {env_x86
, "usbmon.dll"},
213 {env_win9x_case
, "mspp32.dll"},
214 {env_x86
, "win32spl.dll"},
215 {env_x86
, "redmonnt.dll"},
216 {env_x86
, "redmon35.dll"},
217 {env_win9x_case
, "redmon95.dll"},
218 {env_x86
, "pdfcmnnt.dll"},
219 {env_win9x_case
, "pdfcmn95.dll"},
222 if (entry
) return entry
;
224 num_tests
= (sizeof(monitor_table
)/sizeof(struct monitor_entry
));
227 DeleteMonitorA(NULL
, env_x64
, winetest
);
228 DeleteMonitorA(NULL
, env_x86
, winetest
);
229 DeleteMonitorA(NULL
, env_win9x_case
, winetest
);
231 /* find a usable monitor from the table */
232 mi2a
.pName
= winetest
;
233 while ((entry
== NULL
) && (i
< num_tests
)) {
234 entry
= &monitor_table
[i
];
236 mi2a
.pEnvironment
= entry
->env
;
237 mi2a
.pDLLName
= entry
->dllname
;
239 if (AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
)) {
241 trace("using '%s', '%s'\n", entry
->env
, entry
->dllname
);
242 DeleteMonitorA(NULL
, entry
->env
, winetest
);
253 /* ########################### */
255 static void find_local_server(VOID
)
257 static char buffer
[MAX_PATH
];
261 size
= sizeof(buffer
) - 3 ;
266 SetLastError(0xdeadbeef);
267 res
= GetComputerNameA(&buffer
[2], &size
);
268 trace("returned %d with %d and %d: '%s'\n", res
, GetLastError(), size
, buffer
);
270 ok( res
!= 0, "returned %d with %d and %d: '%s' (expected '!= 0')\n",
271 res
, GetLastError(), size
, buffer
);
273 if (res
) local_server
= buffer
;
276 /* ########################### */
278 static void find_tempfile(VOID
)
280 static CHAR buffer_dirA
[MAX_PATH
];
281 static CHAR buffer_fileA
[MAX_PATH
];
282 static WCHAR buffer_dirW
[MAX_PATH
];
283 static WCHAR buffer_fileW
[MAX_PATH
];
287 memset(buffer_dirA
, 0, MAX_PATH
- 1);
288 buffer_dirA
[MAX_PATH
- 1] = '\0';
289 SetLastError(0xdeadbeef);
290 res
= GetTempPathA(MAX_PATH
, buffer_dirA
);
291 ok(res
, "returned %u with %u and '%s' (expected '!= 0')\n", res
, GetLastError(), buffer_dirA
);
292 if (res
== 0) return;
294 memset(buffer_fileA
, 0, MAX_PATH
- 1);
295 buffer_fileA
[MAX_PATH
- 1] = '\0';
296 SetLastError(0xdeadbeef);
297 res
= GetTempFileNameA(buffer_dirA
, winetest
, 0, buffer_fileA
);
298 ok(res
, "returned %u with %u and '%s' (expected '!= 0')\n", res
, GetLastError(), buffer_fileA
);
299 if (res
== 0) return;
301 SetLastError(0xdeadbeef);
302 resint
= MultiByteToWideChar(CP_ACP
, 0, buffer_dirA
, -1, buffer_dirW
, MAX_PATH
);
303 ok(res
, "returned %u with %u (expected '!= 0')\n", resint
, GetLastError());
304 if (resint
== 0) return;
306 SetLastError(0xdeadbeef);
307 resint
= MultiByteToWideChar(CP_ACP
, 0, buffer_fileA
, -1, buffer_fileW
, MAX_PATH
);
308 ok(res
, "returned %u with %u (expected '!= 0')\n", resint
, GetLastError());
309 if (resint
== 0) return;
311 tempdirA
= buffer_dirA
;
312 tempfileA
= buffer_fileA
;
313 tempdirW
= buffer_dirW
;
314 tempfileW
= buffer_fileW
;
315 trace("tempfile: '%s'\n", tempfileA
);
318 /* ########################### */
320 static void test_AddMonitor(void)
322 MONITOR_INFO_2A mi2a
;
323 struct monitor_entry
* entry
= NULL
;
326 entry
= find_installed_monitor();
328 SetLastError(MAGIC_DEAD
);
329 res
= AddMonitorA(NULL
, 1, NULL
);
330 ok(!res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
331 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
332 res
, GetLastError());
334 SetLastError(MAGIC_DEAD
);
335 res
= AddMonitorA(NULL
, 3, NULL
);
336 ok(!res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
337 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
338 res
, GetLastError());
342 /* This test crashes win9x on vmware (works with win9x on qemu 0.8.1) */
343 SetLastError(MAGIC_DEAD
);
344 res
= AddMonitorA(NULL
, 2, NULL
);
345 /* NT: unchanged, 9x: ERROR_PRIVILEGE_NOT_HELD */
347 ((GetLastError() == MAGIC_DEAD
) ||
348 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD
)),
349 "returned %d with %d (expected '0' with: MAGIC_DEAD or "
350 "ERROR_PRIVILEGE_NOT_HELD)\n", res
, GetLastError());
353 ZeroMemory(&mi2a
, sizeof(MONITOR_INFO_2A
));
354 SetLastError(MAGIC_DEAD
);
355 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
356 if (is_spooler_deactivated(res
, GetLastError())) return;
357 if (is_access_denied(res
, GetLastError())) return;
359 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_INVALID_ENVIRONMENT */
360 ok(!res
&& ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
361 (GetLastError() == ERROR_INVALID_ENVIRONMENT
)),
362 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
363 "ERROR_INVALID_ENVIRONMENT)\n", res
, GetLastError());
366 skip("No usable Monitor found\n");
372 /* The test is deactivated, because when mi2a.pName is NULL, the subkey
373 HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM
374 or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì
375 is created on win9x and we do not want to hit this bug here. */
377 mi2a
.pEnvironment
= entry
->env
;
378 SetLastError(MAGIC_DEAD
);
379 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
380 ok(res
, "AddMonitor error %d\n", GetLastError());
381 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
384 mi2a
.pEnvironment
= entry
->env
;
386 SetLastError(MAGIC_DEAD
);
387 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
388 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
390 ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
391 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD
)),
392 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
393 "ERROR_PRIVILEGE_NOT_HELD)\n",
394 res
, GetLastError());
396 mi2a
.pName
= winetest
;
397 SetLastError(MAGIC_DEAD
);
398 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
399 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
401 ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
402 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD
)),
403 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
404 "ERROR_PRIVILEGE_NOT_HELD)\n",
405 res
, GetLastError());
407 mi2a
.pDLLName
= empty
;
408 SetLastError(MAGIC_DEAD
);
409 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
410 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
411 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
412 res
, GetLastError());
414 mi2a
.pDLLName
= does_not_exist_dll
;
415 SetLastError(MAGIC_DEAD
);
416 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
417 /* NT: ERROR_MOD_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
419 ((GetLastError() == ERROR_MOD_NOT_FOUND
) ||
420 (GetLastError() == ERROR_INVALID_PARAMETER
)),
421 "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or "
422 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
424 mi2a
.pDLLName
= version_dll
;
425 SetLastError(MAGIC_DEAD
);
426 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
427 /* NT: ERROR_PROC_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
429 ((GetLastError() == ERROR_PROC_NOT_FOUND
) ||
430 (GetLastError() == ERROR_INVALID_PARAMETER
)),
431 "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or "
432 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
433 if (res
) DeleteMonitorA(NULL
, entry
->env
, winetest
);
435 /* Test AddMonitor with real options */
436 mi2a
.pDLLName
= entry
->dllname
;
437 SetLastError(MAGIC_DEAD
);
438 res
= AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
439 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
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_DeleteMonitor(void)
679 MONITOR_INFO_2A mi2a
;
680 struct monitor_entry
* entry
= NULL
;
684 entry
= find_installed_monitor();
687 skip("No usable Monitor found\n");
691 mi2a
.pName
= winetest
;
692 mi2a
.pEnvironment
= entry
->env
;
693 mi2a
.pDLLName
= entry
->dllname
;
695 /* Testing DeleteMonitor with real options */
696 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
698 SetLastError(MAGIC_DEAD
);
699 res
= DeleteMonitorA(NULL
, entry
->env
, winetest
);
700 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
702 /* Delete the Monitor twice */
703 SetLastError(MAGIC_DEAD
);
704 res
= DeleteMonitorA(NULL
, entry
->env
, winetest
);
705 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
707 ((GetLastError() == ERROR_UNKNOWN_PRINT_MONITOR
) ||
708 (GetLastError() == ERROR_INVALID_PARAMETER
)),
709 "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR"
710 " or ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
712 /* the environment */
713 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
714 SetLastError(MAGIC_DEAD
);
715 res
= DeleteMonitorA(NULL
, NULL
, winetest
);
716 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
718 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
719 SetLastError(MAGIC_DEAD
);
720 res
= DeleteMonitorA(NULL
, empty
, winetest
);
721 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
723 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
724 SetLastError(MAGIC_DEAD
);
725 res
= DeleteMonitorA(NULL
, invalid_env
, winetest
);
727 (!res
&& GetLastError() == ERROR_INVALID_ENVIRONMENT
) /* Vista/W2K8 */,
728 "returned %d with %d\n", res
, GetLastError());
730 /* the monitor-name */
731 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
732 SetLastError(MAGIC_DEAD
);
733 res
= DeleteMonitorA(NULL
, entry
->env
, NULL
);
734 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
736 ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
737 (GetLastError() == ERROR_INVALID_NAME
)),
738 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
739 "ERROR_INVALID_NAME)\n", res
, GetLastError());
741 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
742 SetLastError(MAGIC_DEAD
);
743 res
= DeleteMonitorA(NULL
, entry
->env
, empty
);
744 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
746 ((GetLastError() == ERROR_INVALID_PARAMETER
) ||
747 (GetLastError() == ERROR_INVALID_NAME
)),
748 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
749 "ERROR_INVALID_NAME)\n", res
, GetLastError());
751 AddMonitorA(NULL
, 2, (LPBYTE
) &mi2a
);
752 SetLastError(MAGIC_DEAD
);
753 res
= DeleteMonitorA(empty
, entry
->env
, winetest
);
754 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
757 DeleteMonitorA(NULL
, entry
->env
, winetest
);
760 /* ########################### */
762 static void test_DeletePort(void)
766 SetLastError(0xdeadbeef);
767 res
= DeletePortA(NULL
, 0, NULL
);
768 if (is_spooler_deactivated(res
, GetLastError())) return;
770 SetLastError(0xdeadbeef);
771 res
= DeletePortA(NULL
, 0, empty
);
772 /* Allowed only for (Printer-)Administrators */
773 if (is_access_denied(res
, GetLastError())) return;
775 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
776 ok( !res
&& ((GetLastError() == ERROR_NOT_SUPPORTED
) ||
777 (GetLastError() == ERROR_INVALID_PARAMETER
)),
778 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
779 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
782 SetLastError(0xdeadbeef);
783 res
= DeletePortA(NULL
, 0, does_not_exist
);
784 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
785 ok( !res
&& ((GetLastError() == ERROR_NOT_SUPPORTED
) ||
786 (GetLastError() == ERROR_INVALID_PARAMETER
)),
787 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
788 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
792 /* ########################### */
794 static void test_EnumForms(LPSTR pName
)
804 const char *formtype
;
805 static const char * const formtypes
[] = { "FORM_USER", "FORM_BUILTIN", "FORM_PRINTER", "FORM_flag_unknown" };
806 #define FORMTYPE_MAX 2
807 PFORM_INFO_1A pFI_1a
;
808 PFORM_INFO_2A pFI_2a
;
810 res
= OpenPrinter(pName
, &hprinter
, NULL
);
811 if (is_spooler_deactivated(res
, GetLastError())) return;
812 if (!res
|| !hprinter
)
814 /* opening the local Printserver is not supported on win9x */
815 if (pName
) skip("Failed to open '%s' (not supported on win9x)\n", pName
);
819 /* valid levels are 1 and 2 */
820 for(level
= 0; level
< 4; level
++) {
822 pcReturned
= 0xdeadbeef;
823 SetLastError(0xdeadbeef);
824 res
= EnumFormsA(hprinter
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
826 /* EnumForms is not implemented on win9x */
827 if (!res
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)) continue;
829 /* EnumForms for the server is not implemented on all NT-versions */
830 if (!res
&& (GetLastError() == ERROR_INVALID_HANDLE
) && !pName
) continue;
832 /* Level 2 for EnumForms is not supported on all systems */
833 if (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
) && (level
== 2)) continue;
835 /* use only a short test when testing an invalid level */
836 if(!level
|| (level
> 2)) {
837 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
838 (res
&& (pcReturned
== 0)),
839 "(%d) returned %d with %d and 0x%08x (expected '0' with "
840 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
841 level
, res
, GetLastError(), pcReturned
);
845 ok((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
846 "(%d) returned %d with %d (expected '0' with "
847 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
849 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
*2);
850 if (buffer
== NULL
) continue;
852 SetLastError(0xdeadbeef);
853 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
854 ok(res
, "(%d) returned %d with %d (expected '!=0')\n",
855 level
, res
, GetLastError());
857 if (winetest_debug
> 1) {
858 trace("dumping %d forms level %d\n", pcReturned
, level
);
859 pFI_1a
= (PFORM_INFO_1A
)buffer
;
860 pFI_2a
= (PFORM_INFO_2A
)buffer
;
861 for (i
= 0; i
< pcReturned
; i
++)
863 /* first part is same in FORM_INFO_1 and FORM_INFO_2 */
864 formtype
= (pFI_1a
->Flags
<= FORMTYPE_MAX
) ? formtypes
[pFI_1a
->Flags
] : formtypes
[3];
865 trace("%u (%s): %.03fmm x %.03fmm, %s\n", i
, pFI_1a
->pName
,
866 (float)pFI_1a
->Size
.cx
/1000, (float)pFI_1a
->Size
.cy
/1000, formtype
);
868 if (level
== 1) pFI_1a
++;
870 /* output additional FORM_INFO_2 fields */
871 trace("\tkeyword=%s strtype=%u muidll=%s resid=%u dispname=%s langid=%u\n",
872 pFI_2a
->pKeyword
, pFI_2a
->StringType
, pFI_2a
->pMuiDll
,
873 pFI_2a
->dwResourceId
, pFI_2a
->pDisplayName
, pFI_2a
->wLangId
);
875 /* offset pointer pFI_1a by 1*sizeof(FORM_INFO_2A) Bytes */
877 pFI_1a
= (PFORM_INFO_1A
)pFI_2a
;
882 SetLastError(0xdeadbeef);
883 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
884 ok( res
, "(%d) returned %d with %d (expected '!=0')\n",
885 level
, res
, GetLastError());
887 SetLastError(0xdeadbeef);
888 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
889 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
890 "(%d) returned %d with %d (expected '0' with "
891 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
894 SetLastError(0xdeadbeef);
895 res
= EnumFormsA(hprinter
, level
, NULL
, cbBuf
, &pcbNeeded
, &pcReturned
);
896 ok( !res
&& (GetLastError() == ERROR_INVALID_USER_BUFFER
) ,
897 "(%d) returned %d with %d (expected '0' with "
898 "ERROR_INVALID_USER_BUFFER)\n", level
, res
, GetLastError());
901 SetLastError(0xdeadbeef);
902 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
903 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
) ,
904 "(%d) returned %d with %d (expected '0' with "
905 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
907 SetLastError(0xdeadbeef);
908 res
= EnumFormsA(hprinter
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
909 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
) ,
910 "(%d) returned %d with %d (expected '0' with "
911 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
913 SetLastError(0xdeadbeef);
914 res
= EnumFormsA(0, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
915 ok( !res
&& (GetLastError() == ERROR_INVALID_HANDLE
) ,
916 "(%d) returned %d with %d (expected '0' with "
917 "ERROR_INVALID_HANDLE)\n", level
, res
, GetLastError());
919 HeapFree(GetProcessHeap(), 0, buffer
);
920 } /* for(level ... */
922 ClosePrinter(hprinter
);
925 /* ########################### */
927 static void test_EnumMonitors(void)
936 /* valid levels are 1 and 2 */
937 for(level
= 0; level
< 4; level
++) {
939 pcReturned
= MAGIC_DEAD
;
940 SetLastError(MAGIC_DEAD
);
941 res
= EnumMonitorsA(NULL
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
942 if (is_spooler_deactivated(res
, GetLastError())) return;
943 /* not implemented yet in wine */
944 if (!res
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)) continue;
947 /* use only a short test when testing an invalid level */
948 if(!level
|| (level
> 2)) {
949 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
950 (res
&& (pcReturned
== 0)),
951 "(%d) returned %d with %d and 0x%08x (expected '0' with "
952 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
953 level
, res
, GetLastError(), pcReturned
);
957 /* Level 2 is not supported on win9x */
958 if (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) {
959 skip("Level %d not supported\n", level
);
963 ok((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
964 "(%d) returned %d with %d (expected '0' with "
965 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
968 skip("no valid buffer size returned\n");
972 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
*2);
973 if (buffer
== NULL
) continue;
975 SetLastError(MAGIC_DEAD
);
976 pcbNeeded
= MAGIC_DEAD
;
977 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
978 ok(res
, "(%d) returned %d with %d (expected '!=0')\n",
979 level
, res
, GetLastError());
980 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n",
981 level
, pcbNeeded
, cbBuf
);
982 /* We can validate the returned Data with the Registry here */
985 SetLastError(MAGIC_DEAD
);
986 pcReturned
= MAGIC_DEAD
;
987 pcbNeeded
= MAGIC_DEAD
;
988 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
989 ok(res
, "(%d) returned %d with %d (expected '!=0')\n", level
,
990 res
, GetLastError());
991 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
,
994 SetLastError(MAGIC_DEAD
);
995 pcbNeeded
= MAGIC_DEAD
;
996 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
997 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
998 "(%d) returned %d with %d (expected '0' with "
999 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
1001 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
,
1005 Do not add the next test:
1006 w2k+: RPC_X_NULL_REF_POINTER
1007 NT3.5: ERROR_INVALID_USER_BUFFER
1008 win9x: crash in winspool.drv
1010 res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1013 SetLastError(MAGIC_DEAD
);
1014 pcbNeeded
= MAGIC_DEAD
;
1015 pcReturned
= MAGIC_DEAD
;
1016 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
1017 ok( res
|| (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
)) ,
1018 "(%d) returned %d with %d (expected '!=0' or '0' with "
1019 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
1021 pcbNeeded
= MAGIC_DEAD
;
1022 pcReturned
= MAGIC_DEAD
;
1023 SetLastError(MAGIC_DEAD
);
1024 res
= EnumMonitorsA(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
1025 ok( res
|| (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
)) ,
1026 "(%d) returned %d with %d (expected '!=0' or '0' with "
1027 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
1029 HeapFree(GetProcessHeap(), 0, buffer
);
1030 } /* for(level ... */
1033 /* ########################### */
1035 static void test_EnumPorts(void)
1044 /* valid levels are 1 and 2 */
1045 for(level
= 0; level
< 4; level
++) {
1048 pcReturned
= 0xdeadbeef;
1049 SetLastError(0xdeadbeef);
1050 res
= EnumPortsA(NULL
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
1051 if (is_spooler_deactivated(res
, GetLastError())) return;
1053 /* use only a short test when testing an invalid level */
1054 if(!level
|| (level
> 2)) {
1055 /* NT: ERROR_INVALID_LEVEL, 9x: success */
1056 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
1057 (res
&& (pcReturned
== 0)),
1058 "(%d) returned %d with %d and 0x%08x (expected '0' with "
1059 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1060 level
, res
, GetLastError(), pcReturned
);
1065 /* Level 2 is not supported on NT 3.x */
1066 if (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) {
1067 skip("Level %d not supported\n", level
);
1071 ok((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1072 "(%d) returned %d with %d (expected '0' with "
1073 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
1075 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
*2);
1076 if (buffer
== NULL
) continue;
1078 pcbNeeded
= 0xdeadbeef;
1079 SetLastError(0xdeadbeef);
1080 res
= EnumPortsA(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1081 ok(res
, "(%d) returned %d with %d (expected '!=0')\n", level
, res
, GetLastError());
1082 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
, pcbNeeded
, cbBuf
);
1083 /* ToDo: Compare the returned Data with the Registry / "win.ini",[Ports] here */
1085 pcbNeeded
= 0xdeadbeef;
1086 pcReturned
= 0xdeadbeef;
1087 SetLastError(0xdeadbeef);
1088 res
= EnumPortsA(NULL
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
1089 ok(res
, "(%d) returned %d with %d (expected '!=0')\n", level
, res
, GetLastError());
1090 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
, pcbNeeded
, cbBuf
);
1092 pcbNeeded
= 0xdeadbeef;
1093 SetLastError(0xdeadbeef);
1094 res
= EnumPortsA(NULL
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
1095 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1096 "(%d) returned %d with %d (expected '0' with "
1097 "ERROR_INSUFFICIENT_BUFFER)\n", level
, res
, GetLastError());
1098 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
, pcbNeeded
, cbBuf
);
1101 Do not add this test:
1102 res = EnumPortsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1103 w2k+: RPC_X_NULL_REF_POINTER
1104 NT3.5: ERROR_INVALID_USER_BUFFER
1105 win9x: crash in winspool.drv
1108 SetLastError(0xdeadbeef);
1109 res
= EnumPorts(NULL
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
1110 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
1111 ok( (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
) ) ||
1112 ( res
&& (GetLastError() == ERROR_SUCCESS
) ),
1113 "(%d) returned %d with %d (expected '0' with "
1114 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1115 level
, res
, GetLastError());
1118 SetLastError(0xdeadbeef);
1119 res
= EnumPorts(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
1120 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
1121 ok( (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
) ) ||
1122 ( res
&& (GetLastError() == ERROR_SUCCESS
) ),
1123 "(%d) returned %d with %d (expected '0' with "
1124 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1125 level
, res
, GetLastError());
1127 HeapFree(GetProcessHeap(), 0, buffer
);
1131 /* ########################### */
1133 static void test_EnumPrinterDrivers(void)
1135 static char env_all
[] = "all";
1144 /* 1-3 for w95/w98/NT4; 1-3+6 for me; 1-6 for w2k/xp/2003; 1-6+8 for vista */
1145 for(level
= 0; level
< 10; level
++) {
1147 pcReturned
= 0xdeadbeef;
1148 SetLastError(0xdeadbeef);
1149 res
= EnumPrinterDriversA(NULL
, NULL
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
1150 if (is_spooler_deactivated(res
, GetLastError())) return;
1152 /* use only a short test when testing an invalid level */
1153 if(!level
|| (level
== 7) || (level
> 8)) {
1155 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
1156 (res
&& (pcReturned
== 0)),
1157 "(%d) got %u with %u and 0x%x "
1158 "(expected '0' with ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1159 level
, res
, GetLastError(), pcReturned
);
1163 /* some levels are not supported on all windows versions */
1164 if (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) {
1165 skip("Level %d not supported\n", level
);
1169 ok( ((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) ||
1170 (res
&& (default_printer
== NULL
)),
1171 "(%u) got %u with %u for %s (expected '0' with "
1172 "ERROR_INSUFFICIENT_BUFFER or '!= 0' without a printer)\n",
1173 level
, res
, GetLastError(), default_printer
);
1176 skip("no valid buffer size returned\n");
1180 /* EnumPrinterDriversA returns the same number of bytes as EnumPrinterDriversW */
1181 if (!on_win9x
&& pEnumPrinterDriversW
)
1183 DWORD double_needed
;
1184 DWORD double_returned
;
1185 pEnumPrinterDriversW(NULL
, NULL
, level
, NULL
, 0, &double_needed
, &double_returned
);
1186 ok(double_needed
== cbBuf
, "level %d: EnumPrinterDriversA returned different size %d than EnumPrinterDriversW (%d)\n", level
, cbBuf
, double_needed
);
1189 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
+ 4);
1190 if (buffer
== NULL
) continue;
1192 SetLastError(0xdeadbeef);
1193 pcbNeeded
= 0xdeadbeef;
1194 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1195 ok(res
, "(%u) got %u with %u (expected '!=0')\n", level
, res
, GetLastError());
1196 ok(pcbNeeded
== cbBuf
, "(%d) returned %d (expected %d)\n", level
, pcbNeeded
, cbBuf
);
1198 /* validate the returned data here */
1200 LPDRIVER_INFO_2A di
= (LPDRIVER_INFO_2A
) buffer
;
1202 ok( strrchr(di
->pDriverPath
, '\\') != NULL
,
1203 "(%u) got %s for %s (expected a full path)\n",
1204 level
, di
->pDriverPath
, di
->pName
);
1208 SetLastError(0xdeadbeef);
1209 pcReturned
= 0xdeadbeef;
1210 pcbNeeded
= 0xdeadbeef;
1211 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
1212 ok(res
, "(%u) got %u with %u (expected '!=0')\n", level
, res
, GetLastError());
1213 ok(pcbNeeded
== cbBuf
, "(%u) returned %u (expected %u)\n", level
, pcbNeeded
, cbBuf
);
1215 SetLastError(0xdeadbeef);
1216 pcbNeeded
= 0xdeadbeef;
1217 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
1218 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1219 "(%u) got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1220 level
, res
, GetLastError());
1221 ok(pcbNeeded
== cbBuf
, "(%u) returned %u (expected %u)\n", level
, pcbNeeded
, cbBuf
);
1224 Do not add the next test:
1225 NT: ERROR_INVALID_USER_BUFFER
1226 win9x: crash or 100% CPU
1228 res = EnumPrinterDriversA(NULL, NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1231 SetLastError(0xdeadbeef);
1232 pcbNeeded
= 0xdeadbeef;
1233 pcReturned
= 0xdeadbeef;
1234 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
1235 ok( res
|| (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
)) ,
1236 "(%u) got %u with %u (expected '!=0' or '0' with "
1237 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
1239 pcbNeeded
= 0xdeadbeef;
1240 pcReturned
= 0xdeadbeef;
1241 SetLastError(0xdeadbeef);
1242 res
= EnumPrinterDriversA(NULL
, NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
1243 ok( res
|| (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
)) ,
1244 "(%u) got %u with %u (expected '!=0' or '0' with "
1245 "RPC_X_NULL_REF_POINTER)\n", level
, res
, GetLastError());
1247 HeapFree(GetProcessHeap(), 0, buffer
);
1248 } /* for(level ... */
1252 SetLastError(0xdeadbeef);
1253 res
= EnumPrinterDriversA(NULL
, env_all
, 1, NULL
, 0, &pcbNeeded
, &pcReturned
);
1256 skip("no printer drivers found\n");
1259 if (GetLastError() == ERROR_INVALID_ENVIRONMENT
)
1261 win_skip("NT4 and below don't support the 'all' environment value\n");
1264 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "unexpected error %u\n", GetLastError());
1266 buffer
= HeapAlloc(GetProcessHeap(), 0, pcbNeeded
);
1267 res
= EnumPrinterDriversA(NULL
, env_all
, 1, buffer
, pcbNeeded
, &pcbNeeded
, &pcReturned
);
1268 ok(res
, "EnumPrinterDriversA failed %u\n", GetLastError());
1269 if (res
&& pcReturned
> 0)
1271 DRIVER_INFO_1
*di_1
= (DRIVER_INFO_1
*)buffer
;
1272 ok((LPBYTE
) di_1
->pName
== NULL
|| (LPBYTE
) di_1
->pName
< buffer
||
1273 (LPBYTE
) di_1
->pName
>= (LPBYTE
)(di_1
+ pcReturned
),
1274 "Driver Information not in sequence; pName %p, top of data %p\n",
1275 di_1
->pName
, di_1
+ pcReturned
);
1278 HeapFree(GetProcessHeap(), 0, buffer
);
1281 /* ########################### */
1283 static void test_EnumPrintProcessors(void)
1293 pcReturned
= 0xdeadbeef;
1294 SetLastError(0xdeadbeef);
1295 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, NULL
, 0, &cbBuf
, &pcReturned
);
1296 if (is_spooler_deactivated(res
, GetLastError())) return;
1298 if (res
&& !cbBuf
) {
1299 skip("No Printprocessor installed\n");
1303 ok((!res
) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1304 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1305 res
, GetLastError());
1307 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
+ 4);
1311 SetLastError(0xdeadbeef);
1312 pcbNeeded
= 0xdeadbeef;
1313 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1314 ok(res
, "got %u with %u (expected '!=0')\n", res
, GetLastError());
1315 /* validate the returned data here. */
1318 SetLastError(0xdeadbeef);
1319 pcReturned
= 0xdeadbeef;
1320 pcbNeeded
= 0xdeadbeef;
1321 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
1322 ok(res
, "got %u with %u (expected '!=0')\n", res
, GetLastError());
1324 SetLastError(0xdeadbeef);
1325 pcbNeeded
= 0xdeadbeef;
1326 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
1327 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1328 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1329 res
, GetLastError());
1331 /* only level 1 is valid */
1333 /* both tests crash on win98se */
1334 SetLastError(0xdeadbeef);
1335 pcbNeeded
= 0xdeadbeef;
1336 pcReturned
= 0xdeadbeef;
1337 res
= EnumPrintProcessorsA(NULL
, NULL
, 0, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1338 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
1339 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1340 res
, GetLastError());
1342 SetLastError(0xdeadbeef);
1343 pcbNeeded
= 0xdeadbeef;
1344 res
= EnumPrintProcessorsA(NULL
, NULL
, 2, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1345 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
1346 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1347 res
, GetLastError());
1350 /* an empty environment is ignored */
1351 SetLastError(0xdeadbeef);
1352 pcbNeeded
= 0xdeadbeef;
1353 res
= EnumPrintProcessorsA(NULL
, empty
, 1, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1354 ok(res
, "got %u with %u (expected '!=0')\n", res
, GetLastError());
1356 /* the environment is checked */
1357 SetLastError(0xdeadbeef);
1358 pcbNeeded
= 0xdeadbeef;
1359 res
= EnumPrintProcessorsA(NULL
, invalid_env
, 1, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
1360 /* NT5: ERROR_INVALID_ENVIRONMENT, NT4: res != 0, 9x: ERROR_INVALID_PARAMETER */
1361 ok( broken(res
) || /* NT4 */
1362 (GetLastError() == ERROR_INVALID_ENVIRONMENT
) ||
1363 (GetLastError() == ERROR_INVALID_PARAMETER
),
1364 "got %u with %u (expected '0' with ERROR_INVALID_ENVIRONMENT or "
1365 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1368 /* failure-Codes for NULL */
1370 /* this test crashes on win98se */
1371 SetLastError(0xdeadbeef);
1372 pcbNeeded
= 0xdeadbeef;
1373 pcReturned
= 0xdeadbeef;
1374 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, NULL
, cbBuf
, &pcbNeeded
, &pcReturned
);
1375 ok( !res
&& (GetLastError() == ERROR_INVALID_USER_BUFFER
) ,
1376 "got %u with %u (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1377 res
, GetLastError());
1380 SetLastError(0xdeadbeef);
1381 pcbNeeded
= 0xdeadbeef;
1382 pcReturned
= 0xdeadbeef;
1383 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
, NULL
, &pcReturned
);
1384 /* the NULL is ignored on win9x */
1385 ok( broken(res
) || (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
)),
1386 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1387 res
, GetLastError());
1389 pcbNeeded
= 0xdeadbeef;
1390 pcReturned
= 0xdeadbeef;
1391 SetLastError(0xdeadbeef);
1392 res
= EnumPrintProcessorsA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
, NULL
);
1393 /* the NULL is ignored on win9x */
1394 ok( broken(res
) || (!res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
)),
1395 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1396 res
, GetLastError());
1398 HeapFree(GetProcessHeap(), 0, buffer
);
1402 /* ########################### */
1404 static void test_GetDefaultPrinter(void)
1407 DWORD exact
= DEFAULT_PRINTER_SIZE
;
1409 char buffer
[DEFAULT_PRINTER_SIZE
];
1411 if (!pGetDefaultPrinterA
) return;
1412 /* only supported on NT like OSes starting with win2k */
1414 SetLastError(ERROR_SUCCESS
);
1415 retval
= pGetDefaultPrinterA(buffer
, &exact
);
1416 if (!retval
|| !exact
|| !strlen(buffer
) ||
1417 (ERROR_SUCCESS
!= GetLastError())) {
1418 if ((ERROR_FILE_NOT_FOUND
== GetLastError()) ||
1419 (ERROR_INVALID_NAME
== GetLastError()))
1420 trace("this test requires a default printer to be set\n");
1422 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
1423 "function returned %s\n"
1424 "last error 0x%08x\n"
1425 "returned buffer size 0x%08x\n"
1426 "returned buffer content %s\n",
1427 retval
? "true" : "false", GetLastError(), exact
, buffer
);
1431 SetLastError(ERROR_SUCCESS
);
1432 retval
= pGetDefaultPrinterA(NULL
, NULL
);
1433 ok( !retval
, "function result wrong! False expected\n");
1434 ok( ERROR_INVALID_PARAMETER
== GetLastError(),
1435 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1438 SetLastError(ERROR_SUCCESS
);
1439 retval
= pGetDefaultPrinterA(buffer
, NULL
);
1440 ok( !retval
, "function result wrong! False expected\n");
1441 ok( ERROR_INVALID_PARAMETER
== GetLastError(),
1442 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1445 SetLastError(ERROR_SUCCESS
);
1447 retval
= pGetDefaultPrinterA(NULL
, &size
);
1448 ok( !retval
, "function result wrong! False expected\n");
1449 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
1450 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1452 ok( size
== exact
, "Parameter size wrong! %d expected got %d\n",
1455 SetLastError(ERROR_SUCCESS
);
1456 size
= DEFAULT_PRINTER_SIZE
;
1457 retval
= pGetDefaultPrinterA(NULL
, &size
);
1458 ok( !retval
, "function result wrong! False expected\n");
1459 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
1460 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1462 ok( size
== exact
, "Parameter size wrong! %d expected got %d\n",
1466 retval
= pGetDefaultPrinterA(buffer
, &size
);
1467 ok( !retval
, "function result wrong! False expected\n");
1468 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
1469 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1471 ok( size
== exact
, "Parameter size wrong! %d expected got %d\n",
1475 retval
= pGetDefaultPrinterA(buffer
, &size
);
1476 ok( retval
, "function result wrong! True expected\n");
1477 ok( size
== exact
, "Parameter size wrong! %d expected got %d\n",
1481 static void test_GetPrinterDriverDirectory(void)
1483 LPBYTE buffer
= NULL
;
1484 DWORD cbBuf
= 0, pcbNeeded
= 0;
1488 SetLastError(MAGIC_DEAD
);
1489 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, NULL
, 0, &cbBuf
);
1490 if (is_spooler_deactivated(res
, GetLastError())) return;
1492 trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
1493 res
, GetLastError(), cbBuf
);
1495 ok((res
== 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1496 "returned %d with lasterror=%d (expected '0' with "
1497 "ERROR_INSUFFICIENT_BUFFER)\n", res
, GetLastError());
1500 skip("no valid buffer size returned\n");
1504 buffer
= HeapAlloc( GetProcessHeap(), 0, cbBuf
*2);
1505 if (buffer
== NULL
) return ;
1507 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
);
1508 ok( res
, "expected result != 0, got %d\n", res
);
1509 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %d instead of %d\n",
1512 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1513 ok( res
, "expected result != 0, got %d\n", res
);
1514 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %d instead of %d\n",
1517 SetLastError(MAGIC_DEAD
);
1518 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
-1, &pcbNeeded
);
1519 ok( !res
, "expected result == 0, got %d\n", res
);
1520 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %d instead of %d\n",
1523 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
1524 "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
1528 Do not add the next test:
1529 XPsp2: crash in this app, when the spooler is not running
1530 NT3.5: ERROR_INVALID_USER_BUFFER
1531 win9x: ERROR_INVALID_PARAMETER
1533 pcbNeeded = MAGIC_DEAD;
1534 SetLastError(MAGIC_DEAD);
1535 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1538 SetLastError(MAGIC_DEAD
);
1539 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
, NULL
);
1540 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1541 NT: RPC_X_NULL_REF_POINTER */
1542 ok( res
|| (GetLastError() == RPC_X_NULL_REF_POINTER
) ||
1543 (GetLastError() == ERROR_INVALID_PARAMETER
),
1544 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1545 "or '0' with ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1547 SetLastError(MAGIC_DEAD
);
1548 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, NULL
, cbBuf
, NULL
);
1549 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1550 NT: RPC_X_NULL_REF_POINTER */
1551 ok( res
|| (GetLastError() == RPC_X_NULL_REF_POINTER
) ||
1552 (GetLastError() == ERROR_INVALID_PARAMETER
),
1553 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1554 "or '0' with ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1556 /* with a valid buffer, but level is too large */
1558 SetLastError(MAGIC_DEAD
);
1559 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 2, buffer
, cbBuf
, &pcbNeeded
);
1561 /* Level not checked in win9x and wine:*/
1562 if((res
!= FALSE
) && buffer
[0])
1564 trace("Level '2' not checked '%s'\n", buffer
);
1568 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
1569 "returned %d with lasterror=%d (expected '0' with "
1570 "ERROR_INVALID_LEVEL)\n", res
, GetLastError());
1573 /* printing environments are case insensitive */
1574 /* "Windows 4.0" is valid for win9x and NT */
1576 SetLastError(MAGIC_DEAD
);
1577 res
= GetPrinterDriverDirectoryA(NULL
, env_win9x_case
, 1,
1578 buffer
, cbBuf
*2, &pcbNeeded
);
1580 if(!res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
1582 buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, cbBuf
*2);
1583 if (buffer
== NULL
) return ;
1585 SetLastError(MAGIC_DEAD
);
1586 res
= GetPrinterDriverDirectoryA(NULL
, env_win9x_case
, 1,
1587 buffer
, cbBuf
*2, &pcbNeeded
);
1590 ok(res
&& buffer
[0], "returned %d with "
1591 "lasterror=%d and len=%d (expected '1' with 'len > 0')\n",
1592 res
, GetLastError(), lstrlenA((char *)buffer
));
1595 SetLastError(MAGIC_DEAD
);
1596 res
= GetPrinterDriverDirectoryA(NULL
, env_x86
, 1,
1597 buffer
, cbBuf
*2, &pcbNeeded
);
1599 if(!res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
1601 buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, cbBuf
*2);
1602 if (buffer
== NULL
) return ;
1605 SetLastError(MAGIC_DEAD
);
1606 res
= GetPrinterDriverDirectoryA(NULL
, env_x86
, 1,
1607 buffer
, cbBuf
*2, &pcbNeeded
);
1610 /* "Windows NT x86" is invalid for win9x */
1611 ok( (res
&& buffer
[0]) ||
1612 (!res
&& (GetLastError() == ERROR_INVALID_ENVIRONMENT
)),
1613 "returned %d with lasterror=%d and len=%d (expected '!= 0' with "
1614 "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
1615 res
, GetLastError(), lstrlenA((char *)buffer
));
1617 /* A setup program (PDFCreator_0.8.0) use empty strings */
1618 SetLastError(MAGIC_DEAD
);
1619 res
= GetPrinterDriverDirectoryA(empty
, empty
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1620 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError() );
1622 SetLastError(MAGIC_DEAD
);
1623 res
= GetPrinterDriverDirectoryA(NULL
, empty
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1624 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError() );
1626 SetLastError(MAGIC_DEAD
);
1627 res
= GetPrinterDriverDirectoryA(empty
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1628 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError() );
1630 HeapFree( GetProcessHeap(), 0, buffer
);
1635 static void test_GetPrintProcessorDirectory(void)
1637 LPBYTE buffer
= NULL
;
1639 DWORD pcbNeeded
= 0;
1643 SetLastError(0xdeadbeef);
1644 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 1, NULL
, 0, &cbBuf
);
1645 if (is_spooler_deactivated(res
, GetLastError())) return;
1647 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1648 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1649 res
, GetLastError());
1651 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
*2);
1652 if(buffer
== NULL
) return;
1655 SetLastError(0xdeadbeef);
1656 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
);
1657 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1659 SetLastError(0xdeadbeef);
1661 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1662 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1664 /* Buffer to small */
1666 SetLastError(0xdeadbeef);
1667 res
= GetPrintProcessorDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
-1, &pcbNeeded
);
1668 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
1669 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1670 res
, GetLastError());
1674 /* XPsp2: the program will crash here, when the spooler is not running */
1675 /* GetPrinterDriverDirectory has the same bug */
1677 SetLastError(0xdeadbeef);
1678 res
= GetPrintProcessorDirectoryA( NULL
, NULL
, 1, NULL
, cbBuf
, &pcbNeeded
);
1679 /* NT: ERROR_INVALID_USER_BUFFER, 9x: res != 0 */
1680 ok( (!res
&& (GetLastError() == ERROR_INVALID_USER_BUFFER
)) ||
1682 "returned %d with %d (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1683 res
, GetLastError());
1687 SetLastError(0xdeadbeef);
1688 res
= GetPrintProcessorDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
, NULL
);
1689 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1690 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1691 ok( !res
&& ((GetLastError() == RPC_X_NULL_REF_POINTER
) ||
1692 (GetLastError() == ERROR_INVALID_PARAMETER
)),
1693 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1694 "or with ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1697 SetLastError(0xdeadbeef);
1698 res
= GetPrintProcessorDirectoryA( NULL
, NULL
, 1, NULL
, cbBuf
, NULL
);
1699 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1700 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1701 ok( !res
&& ((GetLastError() == RPC_X_NULL_REF_POINTER
) ||
1702 (GetLastError() == ERROR_INVALID_PARAMETER
)),
1703 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1704 "or with ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1706 /* with a valid buffer, but level is invalid */
1708 SetLastError(0xdeadbeef);
1709 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 0, buffer
, cbBuf
, &pcbNeeded
);
1710 /* Level is ignored in win9x*/
1711 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
1712 broken(res
&& buffer
[0]),
1713 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1714 res
, GetLastError());
1717 SetLastError(0xdeadbeef);
1718 res
= GetPrintProcessorDirectoryA(NULL
, NULL
, 2, buffer
, cbBuf
, &pcbNeeded
);
1719 /* Level is ignored on win9x*/
1720 ok( (!res
&& (GetLastError() == ERROR_INVALID_LEVEL
)) ||
1721 broken(res
&& buffer
[0]),
1722 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1723 res
, GetLastError());
1725 /* Empty environment is the same as the default environment */
1727 SetLastError(0xdeadbeef);
1728 res
= GetPrintProcessorDirectoryA(NULL
, empty
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1729 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1731 /* "Windows 4.0" is valid for win9x and NT */
1733 SetLastError(0xdeadbeef);
1734 res
= GetPrintProcessorDirectoryA(NULL
, env_win9x_case
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1735 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1738 /* "Windows NT x86" is invalid for win9x */
1740 SetLastError(0xdeadbeef);
1741 res
= GetPrintProcessorDirectoryA(NULL
, env_x86
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1742 ok( res
|| (GetLastError() == ERROR_INVALID_ENVIRONMENT
),
1743 "returned %d with %d (expected '!= 0' or '0' with "
1744 "ERROR_INVALID_ENVIRONMENT)\n", res
, GetLastError());
1746 /* invalid on all systems */
1748 SetLastError(0xdeadbeef);
1749 res
= GetPrintProcessorDirectoryA(NULL
, invalid_env
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1750 ok( !res
&& (GetLastError() == ERROR_INVALID_ENVIRONMENT
),
1751 "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
1752 res
, GetLastError());
1754 /* Empty servername is the same as the local computer */
1756 SetLastError(0xdeadbeef);
1757 res
= GetPrintProcessorDirectoryA(empty
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1758 ok(res
, "returned %d with %d (expected '!= 0')\n", res
, GetLastError());
1760 /* invalid on all systems */
1762 SetLastError(0xdeadbeef);
1763 res
= GetPrintProcessorDirectoryA(server_does_not_exist
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
1764 ok( !res
, "expected failure\n");
1765 ok( GetLastError() == RPC_S_SERVER_UNAVAILABLE
|| /* NT */
1766 GetLastError() == ERROR_INVALID_PARAMETER
|| /* 9x */
1767 GetLastError() == RPC_S_INVALID_NET_ADDR
, /* Some Vista */
1768 "unexpected last error %d\n", GetLastError());
1770 HeapFree(GetProcessHeap(), 0, buffer
);
1775 static void test_OpenPrinter(void)
1777 PRINTER_DEFAULTSA defaults
;
1781 SetLastError(MAGIC_DEAD
);
1782 res
= OpenPrinter(NULL
, NULL
, NULL
);
1783 if (is_spooler_deactivated(res
, GetLastError())) return;
1785 ok(!res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
1786 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1787 res
, GetLastError());
1790 /* Get Handle for the local Printserver (NT only)*/
1791 hprinter
= (HANDLE
) MAGIC_DEAD
;
1792 SetLastError(MAGIC_DEAD
);
1793 res
= OpenPrinter(NULL
, &hprinter
, NULL
);
1794 if (is_spooler_deactivated(res
, GetLastError())) return;
1795 ok(res
|| (!res
&& GetLastError() == ERROR_INVALID_PARAMETER
),
1796 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1797 res
, GetLastError());
1799 ClosePrinter(hprinter
);
1801 defaults
.pDatatype
=NULL
;
1802 defaults
.pDevMode
=NULL
;
1804 defaults
.DesiredAccess
=0;
1805 hprinter
= (HANDLE
) MAGIC_DEAD
;
1806 SetLastError(MAGIC_DEAD
);
1807 res
= OpenPrinter(NULL
, &hprinter
, &defaults
);
1808 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
1809 if (res
) ClosePrinter(hprinter
);
1811 defaults
.DesiredAccess
=-1;
1812 hprinter
= (HANDLE
) MAGIC_DEAD
;
1813 SetLastError(MAGIC_DEAD
);
1814 res
= OpenPrinter(NULL
, &hprinter
, &defaults
);
1816 ok(!res
&& GetLastError() == ERROR_ACCESS_DENIED
,
1817 "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n",
1818 res
, GetLastError());
1820 if (res
) ClosePrinter(hprinter
);
1825 if (local_server
!= NULL
) {
1826 hprinter
= (HANDLE
) 0xdeadbeef;
1827 SetLastError(0xdeadbeef);
1828 res
= OpenPrinter(local_server
, &hprinter
, NULL
);
1829 ok(res
|| (!res
&& GetLastError() == ERROR_INVALID_PARAMETER
),
1830 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1831 res
, GetLastError());
1832 if(res
) ClosePrinter(hprinter
);
1835 /* Invalid Printername */
1836 hprinter
= (HANDLE
) MAGIC_DEAD
;
1837 SetLastError(MAGIC_DEAD
);
1838 res
= OpenPrinter(illegal_name
, &hprinter
, NULL
);
1839 ok(!res
&& ((GetLastError() == ERROR_INVALID_PRINTER_NAME
) ||
1840 (GetLastError() == ERROR_INVALID_PARAMETER
) ),
1841 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or"
1842 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
1843 if(res
) ClosePrinter(hprinter
);
1845 hprinter
= (HANDLE
) MAGIC_DEAD
;
1846 SetLastError(MAGIC_DEAD
);
1847 res
= OpenPrinter(empty
, &hprinter
, NULL
);
1848 /* NT: ERROR_INVALID_PRINTER_NAME, 9x: ERROR_INVALID_PARAMETER */
1850 ((GetLastError() == ERROR_INVALID_PRINTER_NAME
) ||
1851 (GetLastError() == ERROR_INVALID_PARAMETER
) ),
1852 "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME"
1853 " or ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1854 if(res
) ClosePrinter(hprinter
);
1857 /* get handle for the default printer */
1858 if (default_printer
)
1860 hprinter
= (HANDLE
) MAGIC_DEAD
;
1861 SetLastError(MAGIC_DEAD
);
1862 res
= OpenPrinter(default_printer
, &hprinter
, NULL
);
1863 if((!res
) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE
))
1865 trace("The service 'Spooler' is required for '%s'\n", default_printer
);
1868 ok(res
, "returned %d with %d (expected '!=0')\n", res
, GetLastError());
1869 if(res
) ClosePrinter(hprinter
);
1871 SetLastError(MAGIC_DEAD
);
1872 res
= OpenPrinter(default_printer
, NULL
, NULL
);
1873 /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1874 ok(res
|| (GetLastError() == ERROR_INVALID_PARAMETER
),
1875 "returned %d with %d (expected '!=0' or '0' with "
1876 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
1878 defaults
.pDatatype
=NULL
;
1879 defaults
.pDevMode
=NULL
;
1880 defaults
.DesiredAccess
=0;
1882 hprinter
= (HANDLE
) MAGIC_DEAD
;
1883 SetLastError(MAGIC_DEAD
);
1884 res
= OpenPrinter(default_printer
, &hprinter
, &defaults
);
1885 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
1886 "returned %d with %d (expected '!=0' or '0' with "
1887 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
1888 if(res
) ClosePrinter(hprinter
);
1890 defaults
.pDatatype
= empty
;
1892 hprinter
= (HANDLE
) MAGIC_DEAD
;
1893 SetLastError(MAGIC_DEAD
);
1894 res
= OpenPrinter(default_printer
, &hprinter
, &defaults
);
1895 /* stop here, when a remote Printserver has no RPC-Service running */
1896 if (is_spooler_deactivated(res
, GetLastError())) return;
1897 ok(res
|| ((GetLastError() == ERROR_INVALID_DATATYPE
) ||
1898 (GetLastError() == ERROR_ACCESS_DENIED
)),
1899 "returned %d with %d (expected '!=0' or '0' with: "
1900 "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1901 res
, GetLastError());
1902 if(res
) ClosePrinter(hprinter
);
1905 defaults
.pDatatype
=NULL
;
1906 defaults
.DesiredAccess
=PRINTER_ACCESS_USE
;
1908 hprinter
= (HANDLE
) MAGIC_DEAD
;
1909 SetLastError(MAGIC_DEAD
);
1910 res
= OpenPrinter(default_printer
, &hprinter
, &defaults
);
1911 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
1912 "returned %d with %d (expected '!=0' or '0' with "
1913 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
1914 if(res
) ClosePrinter(hprinter
);
1917 defaults
.DesiredAccess
=PRINTER_ALL_ACCESS
;
1918 hprinter
= (HANDLE
) MAGIC_DEAD
;
1919 SetLastError(MAGIC_DEAD
);
1920 res
= OpenPrinter(default_printer
, &hprinter
, &defaults
);
1921 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
1922 "returned %d with %d (expected '!=0' or '0' with "
1923 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
1924 if(res
) ClosePrinter(hprinter
);
1930 static void test_SetDefaultPrinter(void)
1933 DWORD size
= DEFAULT_PRINTER_SIZE
;
1934 CHAR buffer
[DEFAULT_PRINTER_SIZE
];
1935 CHAR org_value
[DEFAULT_PRINTER_SIZE
];
1937 if (!default_printer
)
1939 skip("There is no default printer installed\n");
1943 if (!pSetDefaultPrinterA
) return;
1944 /* only supported on win2k and above */
1946 /* backup the original value */
1947 org_value
[0] = '\0';
1948 SetLastError(MAGIC_DEAD
);
1949 res
= GetProfileStringA("windows", "device", NULL
, org_value
, size
);
1950 ok(res
, "GetProfileString error %d\n", GetLastError());
1952 /* first part: with the default Printer */
1953 SetLastError(MAGIC_DEAD
);
1954 res
= pSetDefaultPrinterA("no_printer_with_this_name");
1955 if (is_spooler_deactivated(res
, GetLastError())) return;
1957 /* Not implemented in wine */
1958 if (!res
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)) {
1959 trace("SetDefaultPrinterA() not implemented yet.\n");
1963 ok(!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
),
1964 "returned %d with %d (expected '0' with "
1965 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
1967 WriteProfileStringA("windows", "device", org_value
);
1968 SetLastError(MAGIC_DEAD
);
1969 res
= pSetDefaultPrinterA("");
1970 ok(res
|| (!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
)),
1971 "returned %d with %d (expected '!=0' or '0' with "
1972 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
1974 WriteProfileStringA("windows", "device", org_value
);
1975 SetLastError(MAGIC_DEAD
);
1976 res
= pSetDefaultPrinterA(NULL
);
1977 ok(res
|| (!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
)),
1978 "returned %d with %d (expected '!=0' or '0' with "
1979 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
1981 WriteProfileStringA("windows", "device", org_value
);
1982 SetLastError(MAGIC_DEAD
);
1983 res
= pSetDefaultPrinterA(default_printer
);
1984 ok(res
|| (!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
)),
1985 "returned %d with %d (expected '!=0' or '0' with "
1986 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
1989 /* second part: always without a default Printer */
1990 WriteProfileStringA("windows", "device", NULL
);
1991 SetLastError(MAGIC_DEAD
);
1992 res
= pSetDefaultPrinterA("no_printer_with_this_name");
1994 ok(!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
),
1995 "returned %d with %d (expected '0' with "
1996 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
1998 WriteProfileStringA("windows", "device", NULL
);
1999 SetLastError(MAGIC_DEAD
);
2000 res
= pSetDefaultPrinterA("");
2001 if (is_spooler_deactivated(res
, GetLastError()))
2002 goto restore_old_printer
;
2004 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2005 ok(res
|| (!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
)),
2006 "returned %d with %d (expected '!=0' or '0' with "
2007 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2009 WriteProfileStringA("windows", "device", NULL
);
2010 SetLastError(MAGIC_DEAD
);
2011 res
= pSetDefaultPrinterA(NULL
);
2012 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2013 ok(res
|| (!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
)),
2014 "returned %d with %d (expected '!=0' or '0' with "
2015 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2017 WriteProfileStringA("windows", "device", NULL
);
2018 SetLastError(MAGIC_DEAD
);
2019 res
= pSetDefaultPrinterA(default_printer
);
2020 ok(res
|| (!res
&& (GetLastError() == ERROR_INVALID_PRINTER_NAME
)),
2021 "returned %d with %d (expected '!=0' or '0' with "
2022 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
2024 /* restore the original value */
2025 restore_old_printer
:
2026 res
= pSetDefaultPrinterA(default_printer
); /* the nice way */
2027 ok(res
, "SetDefaultPrinter error %d\n", GetLastError());
2028 WriteProfileStringA("windows", "device", org_value
); /* the old way */
2031 SetLastError(MAGIC_DEAD
);
2032 res
= GetProfileStringA("windows", "device", NULL
, buffer
, size
);
2033 ok(res
, "GetProfileString error %d\n", GetLastError());
2034 ok(!lstrcmpA(org_value
, buffer
), "'%s' (expected '%s')\n", buffer
, org_value
);
2038 /* ########################### */
2040 static void test_XcvDataW_MonitorUI(void)
2044 BYTE buffer
[MAX_PATH
+ 4];
2048 PRINTER_DEFAULTSA pd
;
2050 /* api is not present before w2k */
2051 if (pXcvDataW
== NULL
) return;
2053 pd
.pDatatype
= NULL
;
2055 pd
.DesiredAccess
= SERVER_ACCESS_ADMINISTER
;
2058 SetLastError(0xdeadbeef);
2059 res
= OpenPrinter(xcv_localport
, &hXcv
, &pd
);
2060 if (is_spooler_deactivated(res
, GetLastError())) return;
2061 if (is_access_denied(res
, GetLastError())) return;
2063 ok(res
, "returned %d with %u and handle %p (expected '!= 0')\n", res
, GetLastError(), hXcv
);
2066 /* ask for needed size */
2067 needed
= (DWORD
) 0xdeadbeef;
2068 status
= (DWORD
) 0xdeadbeef;
2069 SetLastError(0xdeadbeef);
2070 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, NULL
, 0, &needed
, &status
);
2071 ok( res
&& (status
== ERROR_INSUFFICIENT_BUFFER
) && (needed
<= MAX_PATH
),
2072 "returned %d with %u and %u for status %u (expected '!= 0' and "
2073 "'<= MAX_PATH' for status ERROR_INSUFFICIENT_BUFFER)\n",
2074 res
, GetLastError(), needed
, status
);
2076 if (needed
> MAX_PATH
) {
2078 skip("buffer overflow (%u)\n", needed
);
2081 len
= needed
; /* Size is in bytes */
2083 /* the command is required */
2084 needed
= (DWORD
) 0xdeadbeef;
2085 status
= (DWORD
) 0xdeadbeef;
2086 SetLastError(0xdeadbeef);
2087 res
= pXcvDataW(hXcv
, emptyW
, NULL
, 0, NULL
, 0, &needed
, &status
);
2088 ok( res
&& (status
== ERROR_INVALID_PARAMETER
),
2089 "returned %d with %u and %u for status %u (expected '!= 0' with "
2090 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError(), needed
, status
);
2092 needed
= (DWORD
) 0xdeadbeef;
2093 status
= (DWORD
) 0xdeadbeef;
2094 SetLastError(0xdeadbeef);
2095 res
= pXcvDataW(hXcv
, NULL
, NULL
, 0, buffer
, MAX_PATH
, &needed
, &status
);
2096 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
),
2097 "returned %d with %u and %u for status %u (expected '0' with "
2098 "RPC_X_NULL_REF_POINTER)\n", res
, GetLastError(), needed
, status
);
2100 /* "PDWORD needed" is checked before RPC-Errors */
2101 needed
= (DWORD
) 0xdeadbeef;
2102 status
= (DWORD
) 0xdeadbeef;
2103 SetLastError(0xdeadbeef);
2104 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, NULL
, &status
);
2105 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
2106 "returned %d with %u and %u for status %u (expected '0' with "
2107 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError(), needed
, status
);
2109 needed
= (DWORD
) 0xdeadbeef;
2110 status
= (DWORD
) 0xdeadbeef;
2111 SetLastError(0xdeadbeef);
2112 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, NULL
, len
, &needed
, &status
);
2113 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
),
2114 "returned %d with %u and %u for status %u (expected '0' with "
2115 "RPC_X_NULL_REF_POINTER)\n", res
, GetLastError(), needed
, status
);
2117 needed
= (DWORD
) 0xdeadbeef;
2118 status
= (DWORD
) 0xdeadbeef;
2119 SetLastError(0xdeadbeef);
2120 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, &needed
, NULL
);
2121 ok( !res
&& (GetLastError() == RPC_X_NULL_REF_POINTER
),
2122 "returned %d with %u and %u for status %u (expected '0' with "
2123 "RPC_X_NULL_REF_POINTER)\n", res
, GetLastError(), needed
, status
);
2125 /* off by one: larger */
2126 needed
= (DWORD
) 0xdeadbeef;
2127 status
= (DWORD
) 0xdeadbeef;
2128 SetLastError(0xdeadbeef);
2129 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
+1, &needed
, &status
);
2130 ok( res
&& (status
== ERROR_SUCCESS
),
2131 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2132 "ERROR_SUCCESS)\n", res
, GetLastError(), needed
, status
);
2134 /* off by one: smaller */
2135 /* the buffer is not modified for NT4, w2k, XP */
2136 needed
= (DWORD
) 0xdeadbeef;
2137 status
= (DWORD
) 0xdeadbeef;
2138 SetLastError(0xdeadbeef);
2139 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
-1, &needed
, &status
);
2140 ok( res
&& (status
== ERROR_INSUFFICIENT_BUFFER
),
2141 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2142 "ERROR_INSUFFICIENT_BUFFER)\n", res
, GetLastError(), needed
, status
);
2145 /* Normal use. The DLL-Name without a Path is returned */
2146 memset(buffer
, 0, len
);
2147 needed
= (DWORD
) 0xdeadbeef;
2148 status
= (DWORD
) 0xdeadbeef;
2149 SetLastError(0xdeadbeef);
2150 res
= pXcvDataW(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, &needed
, &status
);
2151 ok( res
&& (status
== ERROR_SUCCESS
),
2152 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2153 "ERROR_SUCCESS)\n", res
, GetLastError(), needed
, status
);
2158 /* ########################### */
2160 static void test_XcvDataW_PortIsValid(void)
2166 PRINTER_DEFAULTSA pd
;
2168 /* api is not present before w2k */
2169 if (pXcvDataW
== NULL
) return;
2171 pd
.pDatatype
= NULL
;
2173 pd
.DesiredAccess
= SERVER_ACCESS_ADMINISTER
;
2176 SetLastError(0xdeadbeef);
2177 res
= OpenPrinter(xcv_localport
, &hXcv
, &pd
);
2178 if (is_spooler_deactivated(res
, GetLastError())) return;
2179 if (is_access_denied(res
, GetLastError())) return;
2181 ok(res
, "returned %d with %u and handle %p (expected '!= 0')\n", res
, GetLastError(), hXcv
);
2185 /* "PDWORD needed" is always required */
2186 needed
= (DWORD
) 0xdeadbeef;
2187 status
= (DWORD
) 0xdeadbeef;
2188 SetLastError(0xdeadbeef);
2189 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
), NULL
, 0, NULL
, &status
);
2190 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
2191 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_INVALID_PARAMETER)\n",
2192 res
, GetLastError(), needed
, status
);
2194 /* an empty name is not allowed */
2195 needed
= (DWORD
) 0xdeadbeef;
2196 status
= (DWORD
) 0xdeadbeef;
2197 SetLastError(0xdeadbeef);
2198 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) emptyW
, sizeof(emptyW
), NULL
, 0, &needed
, &status
);
2199 ok( res
&& ((status
== ERROR_FILE_NOT_FOUND
) || (status
== ERROR_PATH_NOT_FOUND
)),
2200 "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2201 "ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND)\n",
2202 res
, GetLastError(), needed
, status
);
2204 /* a directory is not allowed */
2205 needed
= (DWORD
) 0xdeadbeef;
2206 status
= (DWORD
) 0xdeadbeef;
2207 SetLastError(0xdeadbeef);
2208 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) tempdirW
, (lstrlenW(tempdirW
) + 1) * sizeof(WCHAR
), NULL
, 0, &needed
, &status
);
2209 /* XP: ERROR_PATH_NOT_FOUND, w2k ERROR_ACCESS_DENIED */
2210 ok( res
&& ((status
== ERROR_PATH_NOT_FOUND
) || (status
== ERROR_ACCESS_DENIED
)),
2211 "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2212 "ERROR_PATH_NOT_FOUND or ERROR_ACCESS_DENIED)\n",
2213 res
, GetLastError(), needed
, status
);
2215 /* more valid well known ports */
2216 needed
= (DWORD
) 0xdeadbeef;
2217 status
= (DWORD
) 0xdeadbeef;
2218 SetLastError(0xdeadbeef);
2219 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
), NULL
, 0, &needed
, &status
);
2220 ok( res
&& (status
== ERROR_SUCCESS
),
2221 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2222 res
, GetLastError(), needed
, status
);
2224 needed
= (DWORD
) 0xdeadbeef;
2225 status
= (DWORD
) 0xdeadbeef;
2226 SetLastError(0xdeadbeef);
2227 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt2W
, sizeof(portname_lpt2W
), NULL
, 0, &needed
, &status
);
2228 ok( res
&& (status
== ERROR_SUCCESS
),
2229 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2230 res
, GetLastError(), needed
, status
);
2232 needed
= (DWORD
) 0xdeadbeef;
2233 status
= (DWORD
) 0xdeadbeef;
2234 SetLastError(0xdeadbeef);
2235 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_com1W
, sizeof(portname_com1W
), NULL
, 0, &needed
, &status
);
2236 ok( res
&& (status
== ERROR_SUCCESS
),
2237 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2238 res
, GetLastError(), needed
, status
);
2240 needed
= (DWORD
) 0xdeadbeef;
2241 status
= (DWORD
) 0xdeadbeef;
2242 SetLastError(0xdeadbeef);
2243 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_com2W
, sizeof(portname_com2W
), NULL
, 0, &needed
, &status
);
2244 ok( res
&& (status
== ERROR_SUCCESS
),
2245 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2246 res
, GetLastError(), needed
, status
);
2248 needed
= (DWORD
) 0xdeadbeef;
2249 status
= (DWORD
) 0xdeadbeef;
2250 SetLastError(0xdeadbeef);
2251 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_fileW
, sizeof(portname_fileW
), NULL
, 0, &needed
, &status
);
2252 ok( res
&& (status
== ERROR_SUCCESS
),
2253 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2254 res
, GetLastError(), needed
, status
);
2257 /* a normal, writable file is allowed */
2258 needed
= (DWORD
) 0xdeadbeef;
2259 status
= (DWORD
) 0xdeadbeef;
2260 SetLastError(0xdeadbeef);
2261 res
= pXcvDataW(hXcv
, cmd_PortIsValidW
, (PBYTE
) tempfileW
, (lstrlenW(tempfileW
) + 1) * sizeof(WCHAR
), NULL
, 0, &needed
, &status
);
2262 ok( res
&& (status
== ERROR_SUCCESS
),
2263 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2264 res
, GetLastError(), needed
, status
);
2269 /* ########################### */
2271 static void test_GetPrinter(void)
2277 DWORD needed
, filled
;
2279 if (!default_printer
)
2281 skip("There is no default printer installed\n");
2286 ret
= OpenPrinter(default_printer
, &hprn
, NULL
);
2289 skip("Unable to open the default printer (%s)\n", default_printer
);
2292 ok(hprn
!= 0, "wrong hprn %p\n", hprn
);
2294 for (level
= 1; level
<= 9; level
++)
2296 SetLastError(0xdeadbeef);
2298 ret
= GetPrinter(hprn
, level
, NULL
, 0, &needed
);
2301 win_skip("Level %d is not supported on Win9x/WinMe\n", level
);
2302 ok(GetLastError() == ERROR_SUCCESS
, "wrong error %d\n", GetLastError());
2303 ok(needed
== 0,"Expected 0, got %d\n", needed
);
2306 ok(!ret
, "level %d: GetPrinter should fail\n", level
);
2307 /* Not all levels are supported on all Windows-Versions */
2308 if (GetLastError() == ERROR_INVALID_LEVEL
||
2309 GetLastError() == ERROR_NOT_SUPPORTED
/* Win9x/WinMe */)
2311 skip("Level %d not supported\n", level
);
2314 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %d\n", GetLastError());
2315 ok(needed
> 0,"not expected needed buffer size %d\n", needed
);
2317 /* GetPrinterA returns the same number of bytes as GetPrinterW */
2318 if (!on_win9x
&& !ret
&& pGetPrinterW
&& level
!= 6 && level
!= 7)
2320 DWORD double_needed
;
2321 ret
= pGetPrinterW(hprn
, level
, NULL
, 0, &double_needed
);
2322 ok(!ret
, "level %d: GetPrinter error %d\n", level
, GetLastError());
2323 ok(double_needed
== needed
, "level %d: GetPrinterA returned different size %d than GetPrinterW (%d)\n", level
, needed
, double_needed
);
2326 buf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2328 SetLastError(0xdeadbeef);
2330 ret
= GetPrinter(hprn
, level
, buf
, needed
, &filled
);
2331 ok(ret
, "level %d: GetPrinter error %d\n", level
, GetLastError());
2332 ok(needed
== filled
, "needed %d != filled %d\n", needed
, filled
);
2336 PRINTER_INFO_2
*pi_2
= (PRINTER_INFO_2
*)buf
;
2338 ok(pi_2
->pPrinterName
!= NULL
, "not expected NULL ptr\n");
2339 ok(pi_2
->pDriverName
!= NULL
, "not expected NULL ptr\n");
2341 trace("pPrinterName %s\n", pi_2
->pPrinterName
);
2342 trace("pDriverName %s\n", pi_2
->pDriverName
);
2345 HeapFree(GetProcessHeap(), 0, buf
);
2348 SetLastError(0xdeadbeef);
2349 ret
= ClosePrinter(hprn
);
2350 ok(ret
, "ClosePrinter error %d\n", GetLastError());
2353 /* ########################### */
2355 static void test_GetPrinterData(void)
2360 CHAR buffer
[MAX_PATH
+ 1];
2364 /* ToDo: test parameter validation, test with the default printer */
2366 SetLastError(0xdeadbeef);
2367 res
= OpenPrinter(NULL
, &hprn
, NULL
);
2370 /* printserver not available on win9x */
2372 win_skip("Unable to open the printserver: %d\n", GetLastError());
2376 memset(buffer
, '#', sizeof(buffer
));
2377 buffer
[MAX_PATH
] = 0;
2379 needed
= 0xdeadbeef;
2380 SetLastError(0xdeadbeef);
2381 res
= GetPrinterDataA(hprn
, defaultspooldirectory
, &type
, (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2383 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2384 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2385 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2386 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2387 res
, type
, needed
, buffer
, len
);
2389 needed
= 0xdeadbeef;
2390 SetLastError(0xdeadbeef);
2391 res
= GetPrinterDataA(hprn
, defaultspooldirectory
, NULL
, NULL
, 0, &needed
);
2392 ok( (res
== ERROR_MORE_DATA
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2393 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res
, needed
, len
);
2395 /* ToDo: test SPLREG_* */
2397 SetLastError(0xdeadbeef);
2398 res
= ClosePrinter(hprn
);
2399 ok(res
, "ClosePrinter error %d\n", GetLastError());
2402 /* ########################### */
2404 static void test_GetPrinterDataEx(void)
2409 CHAR buffer
[MAX_PATH
+ 1];
2413 /* not present before w2k */
2414 if (!pGetPrinterDataExA
) {
2415 win_skip("GetPrinterDataEx not found\n");
2419 /* ToDo: test parameter validation, test with the default printer */
2421 SetLastError(0xdeadbeef);
2422 res
= OpenPrinter(NULL
, &hprn
, NULL
);
2425 win_skip("Unable to open the printserver: %d\n", GetLastError());
2429 /* keyname is ignored, when hprn is a HANDLE for a printserver */
2430 memset(buffer
, '#', sizeof(buffer
));
2431 buffer
[MAX_PATH
] = 0;
2433 needed
= 0xdeadbeef;
2434 SetLastError(0xdeadbeef);
2435 res
= pGetPrinterDataExA(hprn
, NULL
, defaultspooldirectory
, &type
,
2436 (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2438 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2439 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2440 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2441 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2442 res
, type
, needed
, buffer
, len
);
2444 memset(buffer
, '#', sizeof(buffer
));
2445 buffer
[MAX_PATH
] = 0;
2447 needed
= 0xdeadbeef;
2448 SetLastError(0xdeadbeef);
2449 res
= pGetPrinterDataExA(hprn
, "", defaultspooldirectory
, &type
,
2450 (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2451 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2452 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2453 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2454 res
, type
, needed
, buffer
, len
);
2456 memset(buffer
, '#', sizeof(buffer
));
2457 buffer
[MAX_PATH
] = 0;
2459 needed
= 0xdeadbeef;
2460 SetLastError(0xdeadbeef);
2461 /* Wine uses GetPrinterDataEx with "PrinterDriverData" to implement GetPrinterData */
2462 res
= pGetPrinterDataExA(hprn
, "PrinterDriverData", defaultspooldirectory
,
2463 &type
, (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2464 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2465 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2466 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2467 res
, type
, needed
, buffer
, len
);
2470 memset(buffer
, '#', sizeof(buffer
));
2471 buffer
[MAX_PATH
] = 0;
2473 needed
= 0xdeadbeef;
2474 SetLastError(0xdeadbeef);
2475 res
= pGetPrinterDataExA(hprn
, does_not_exist
, defaultspooldirectory
, &type
,
2476 (LPBYTE
) buffer
, sizeof(buffer
), &needed
);
2477 len
= lstrlenA(buffer
) + sizeof(CHAR
);
2478 ok( !res
&& (type
== REG_SZ
) && ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2479 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2480 res
, type
, needed
, buffer
, len
);
2482 needed
= 0xdeadbeef;
2483 SetLastError(0xdeadbeef);
2484 /* vista and w2k8 have a bug in GetPrinterDataEx:
2485 the current LastError value is returned as result */
2486 res
= pGetPrinterDataExA(hprn
, NULL
, defaultspooldirectory
, NULL
, NULL
, 0, &needed
);
2487 ok( ((res
== ERROR_MORE_DATA
) || broken(res
== 0xdeadbeef)) &&
2488 ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2489 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res
, needed
, len
);
2491 needed
= 0xdeadbeef;
2492 SetLastError(0xdeaddead);
2493 res
= pGetPrinterDataExA(hprn
, NULL
, defaultspooldirectory
, NULL
, NULL
, 0, &needed
);
2494 ok( ((res
== ERROR_MORE_DATA
) || broken(res
== 0xdeaddead)) &&
2495 ((needed
== len
) || (needed
== (len
* sizeof(WCHAR
)))),
2496 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res
, needed
, len
);
2498 SetLastError(0xdeadbeef);
2499 res
= ClosePrinter(hprn
);
2500 ok(res
, "ClosePrinter error %d\n", GetLastError());
2503 /* ########################### */
2505 static void test_GetPrinterDriver(void)
2511 DWORD needed
, filled
;
2513 if (!default_printer
)
2515 skip("There is no default printer installed\n");
2520 ret
= OpenPrinter(default_printer
, &hprn
, NULL
);
2523 skip("Unable to open the default printer (%s)\n", default_printer
);
2526 ok(hprn
!= 0, "wrong hprn %p\n", hprn
);
2528 for (level
= -1; level
<= 7; level
++)
2530 SetLastError(0xdeadbeef);
2532 ret
= GetPrinterDriver(hprn
, NULL
, level
, NULL
, 0, &needed
);
2533 ok(!ret
, "level %d: GetPrinterDriver should fail\n", level
);
2534 if (level
>= 1 && level
<= 6)
2536 /* Not all levels are supported on all Windows-Versions */
2537 if(GetLastError() == ERROR_INVALID_LEVEL
) continue;
2538 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "wrong error %d\n", GetLastError());
2539 ok(needed
> 0,"not expected needed buffer size %d\n", needed
);
2543 /* ERROR_OUTOFMEMORY found on win9x */
2544 ok( ((GetLastError() == ERROR_INVALID_LEVEL
) ||
2545 (GetLastError() == ERROR_OUTOFMEMORY
)),
2546 "%d: returned %d with %d (expected '0' with: "
2547 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
2548 level
, ret
, GetLastError());
2549 /* needed is modified in win9x. The modified Value depends on the
2550 default Printer. testing for "needed == (DWORD)-1" will fail */
2554 /* GetPrinterDriverA returns the same number of bytes as GetPrinterDriverW */
2555 if (!on_win9x
&& !ret
&& pGetPrinterDriverW
)
2557 DWORD double_needed
;
2558 ret
= pGetPrinterDriverW(hprn
, NULL
, level
, NULL
, 0, &double_needed
);
2559 ok(!ret
, "level %d: GetPrinterDriver error %d\n", level
, GetLastError());
2560 ok(double_needed
== needed
, "GetPrinterDriverA returned different size %d than GetPrinterDriverW (%d)\n", needed
, double_needed
);
2563 buf
= HeapAlloc(GetProcessHeap(), 0, needed
);
2565 SetLastError(0xdeadbeef);
2567 ret
= GetPrinterDriver(hprn
, NULL
, level
, buf
, needed
, &filled
);
2568 ok(ret
, "level %d: GetPrinterDriver error %d\n", level
, GetLastError());
2569 ok(needed
== filled
, "needed %d != filled %d\n", needed
, filled
);
2573 DRIVER_INFO_2
*di_2
= (DRIVER_INFO_2
*)buf
;
2574 DWORD calculated
= sizeof(*di_2
);
2577 /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
2578 NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k-win7(Usermode): 3, win8 and above(Usermode): 4 */
2579 ok( (di_2
->cVersion
<= 4) ||
2580 (di_2
->cVersion
== 0x0400), "di_2->cVersion = %d\n", di_2
->cVersion
);
2581 ok(di_2
->pName
!= NULL
, "not expected NULL ptr\n");
2582 ok(di_2
->pEnvironment
!= NULL
, "not expected NULL ptr\n");
2583 ok(di_2
->pDriverPath
!= NULL
, "not expected NULL ptr\n");
2584 ok(di_2
->pDataFile
!= NULL
, "not expected NULL ptr\n");
2585 ok(di_2
->pConfigFile
!= NULL
, "not expected NULL ptr\n");
2587 trace("cVersion %d\n", di_2
->cVersion
);
2588 trace("pName %s\n", di_2
->pName
);
2589 calculated
+= strlen(di_2
->pName
) + 1;
2590 trace("pEnvironment %s\n", di_2
->pEnvironment
);
2591 calculated
+= strlen(di_2
->pEnvironment
) + 1;
2592 trace("pDriverPath %s\n", di_2
->pDriverPath
);
2593 calculated
+= strlen(di_2
->pDriverPath
) + 1;
2594 trace("pDataFile %s\n", di_2
->pDataFile
);
2595 calculated
+= strlen(di_2
->pDataFile
) + 1;
2596 trace("pConfigFile %s\n", di_2
->pConfigFile
);
2597 calculated
+= strlen(di_2
->pConfigFile
) + 1;
2599 hf
= CreateFileA(di_2
->pDriverPath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2600 if(hf
!= INVALID_HANDLE_VALUE
)
2603 ok(hf
!= INVALID_HANDLE_VALUE
, "Could not open %s\n", di_2
->pDriverPath
);
2605 hf
= CreateFileA(di_2
->pDataFile
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2606 if(hf
!= INVALID_HANDLE_VALUE
)
2608 ok(hf
!= INVALID_HANDLE_VALUE
, "Could not open %s\n", di_2
->pDataFile
);
2610 hf
= CreateFileA(di_2
->pConfigFile
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2611 if(hf
!= INVALID_HANDLE_VALUE
)
2614 ok(hf
!= INVALID_HANDLE_VALUE
, "Could not open %s\n", di_2
->pConfigFile
);
2616 /* XP allocates memory for both ANSI and unicode names */
2617 ok(filled
>= calculated
,"calculated %d != filled %d\n", calculated
, filled
);
2619 /* Obscure test - demonstrate that Windows zero fills the buffer, even on failure */
2620 ret
= GetPrinterDriver(hprn
, NULL
, level
, buf
, needed
- 2, &filled
);
2621 ok(!ret
, "level %d: GetPrinterDriver succeeded with less buffer than it should\n", level
);
2622 ok(di_2
->pDataFile
== NULL
||
2623 broken(di_2
->pDataFile
!= NULL
), /* Win9x/WinMe */
2624 "Even on failure, GetPrinterDriver clears the buffer to zeros\n");
2627 HeapFree(GetProcessHeap(), 0, buf
);
2630 SetLastError(0xdeadbeef);
2631 ret
= ClosePrinter(hprn
);
2632 ok(ret
, "ClosePrinter error %d\n", GetLastError());
2635 static void test_DEVMODE(const DEVMODE
*dm
, LONG dmSize
, LPCSTR exp_prn_name
)
2637 /* On NT3.51, some fields in DEVMODE are empty/zero
2638 (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
2639 We skip the Tests on this Platform */
2640 if (dm
->dmSpecVersion
|| dm
->dmDriverVersion
|| dm
->dmDriverExtra
) {
2641 /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
2642 ok(!strncmp(exp_prn_name
, (LPCSTR
)dm
->dmDeviceName
, CCHDEVICENAME
-1) ||
2643 !strncmp(exp_prn_name
, (LPCSTR
)dm
->dmDeviceName
, CCHDEVICENAME
-2), /* XP+ */
2644 "expected '%s', got '%s'\n", exp_prn_name
, dm
->dmDeviceName
);
2645 ok(dm
->dmSize
+ dm
->dmDriverExtra
== dmSize
,
2646 "%u != %d\n", dm
->dmSize
+ dm
->dmDriverExtra
, dmSize
);
2648 trace("dmFields %08x\n", dm
->dmFields
);
2651 static void test_DocumentProperties(void)
2656 char empty_str
[] = "";
2658 if (!default_printer
)
2660 skip("There is no default printer installed\n");
2665 ret
= OpenPrinter(default_printer
, &hprn
, NULL
);
2668 skip("Unable to open the default printer (%s)\n", default_printer
);
2671 ok(hprn
!= 0, "wrong hprn %p\n", hprn
);
2673 dm_size
= DocumentProperties(0, hprn
, NULL
, NULL
, NULL
, 0);
2674 trace("DEVMODE required size %d\n", dm_size
);
2675 ok(dm_size
>= sizeof(DEVMODE
), "unexpected DocumentProperties ret value %d\n", dm_size
);
2677 dm
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dm_size
);
2679 ret
= DocumentProperties(0, hprn
, NULL
, dm
, dm
, DM_OUT_BUFFER
);
2680 ok(ret
== IDOK
, "DocumentProperties ret value %d != expected IDOK\n", ret
);
2682 ret
= DocumentProperties(0, hprn
, empty_str
, dm
, dm
, DM_OUT_BUFFER
);
2683 ok(ret
== IDOK
, "DocumentProperties ret value %d != expected IDOK\n", ret
);
2685 test_DEVMODE(dm
, dm_size
, default_printer
);
2687 HeapFree(GetProcessHeap(), 0, dm
);
2689 SetLastError(0xdeadbeef);
2690 ret
= ClosePrinter(hprn
);
2691 ok(ret
, "ClosePrinter error %d\n", GetLastError());
2694 static void test_EnumPrinters(void)
2696 DWORD neededA
, neededW
, num
;
2699 SetLastError(0xdeadbeef);
2701 ret
= EnumPrintersA(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &neededA
, &num
);
2702 if (is_spooler_deactivated(ret
, GetLastError())) return;
2705 /* We have 1 or more printers */
2706 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "gle %d\n", GetLastError());
2707 ok(neededA
> 0, "Expected neededA to show the number of needed bytes\n");
2711 /* We don't have any printers defined */
2712 ok(GetLastError() == S_OK
, "gle %d\n", GetLastError());
2713 ok(neededA
== 0, "Expected neededA to be zero\n");
2715 ok(num
== 0, "num %d\n", num
);
2717 SetLastError(0xdeadbeef);
2719 ret
= EnumPrintersW(PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &neededW
, &num
);
2720 /* EnumPrintersW is not supported on all platforms */
2721 if (!ret
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
2723 win_skip("EnumPrintersW is not implemented\n");
2729 /* We have 1 or more printers */
2730 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "gle %d\n", GetLastError());
2731 ok(neededW
> 0, "Expected neededW to show the number of needed bytes\n");
2735 /* We don't have any printers defined */
2736 ok(GetLastError() == S_OK
, "gle %d\n", GetLastError());
2737 ok(neededW
== 0, "Expected neededW to be zero\n");
2739 ok(num
== 0, "num %d\n", num
);
2741 /* Outlook2003 relies on the buffer size returned by EnumPrintersA being big enough
2742 to hold the buffer returned by EnumPrintersW */
2743 ok(neededA
== neededW
, "neededA %d neededW %d\n", neededA
, neededW
);
2746 static void test_DeviceCapabilities(void)
2749 BOOL (WINAPI
*pPrintDlgA
)(PRINTDLGA
*);
2753 const char *driver
, *device
, *port
;
2761 INT n_papers
, n_paper_size
, n_paper_names
, n_copies
, ret
;
2764 hComdlg32
= LoadLibrary("comdlg32.dll");
2766 pPrintDlgA
= (void *)GetProcAddress(hComdlg32
, "PrintDlgA");
2769 memset(&prn_dlg
, 0, sizeof(prn_dlg
));
2770 prn_dlg
.lStructSize
= sizeof(prn_dlg
);
2771 prn_dlg
.Flags
= PD_RETURNDEFAULT
;
2772 ret
= pPrintDlgA(&prn_dlg
);
2773 FreeLibrary(hComdlg32
);
2776 skip("PrintDlg returned no default printer\n");
2779 ok(prn_dlg
.hDevMode
!= 0, "PrintDlg returned hDevMode == NULL\n");
2780 ok(prn_dlg
.hDevNames
!= 0, "PrintDlg returned hDevNames == NULL\n");
2782 dm
= GlobalLock(prn_dlg
.hDevMode
);
2783 ok(dm
!= NULL
, "GlobalLock(prn_dlg.hDevMode) failed\n");
2784 trace("dmDeviceName \"%s\"\n", dm
->dmDeviceName
);
2786 dn
= GlobalLock(prn_dlg
.hDevNames
);
2787 ok(dn
!= NULL
, "GlobalLock(prn_dlg.hDevNames) failed\n");
2788 ok(dn
->wDriverOffset
, "expected not 0 wDriverOffset\n");
2789 ok(dn
->wDeviceOffset
, "expected not 0 wDeviceOffset\n");
2790 ok(dn
->wOutputOffset
, "expected not 0 wOutputOffset\n");
2791 ok(dn
->wDefault
== DN_DEFAULTPRN
, "expected DN_DEFAULTPRN got %x\n", dn
->wDefault
);
2792 driver
= (const char *)dn
+ dn
->wDriverOffset
;
2793 device
= (const char *)dn
+ dn
->wDeviceOffset
;
2794 port
= (const char *)dn
+ dn
->wOutputOffset
;
2795 trace("driver \"%s\" device \"%s\" port \"%s\"\n", driver
, device
, port
);
2797 test_DEVMODE(dm
, dm
->dmSize
+ dm
->dmDriverExtra
, device
);
2799 n_papers
= DeviceCapabilities(device
, port
, DC_PAPERS
, NULL
, NULL
);
2800 ok(n_papers
> 0, "DeviceCapabilities DC_PAPERS failed\n");
2801 papers
= HeapAlloc(GetProcessHeap(), 0, sizeof(*papers
) * n_papers
);
2802 ret
= DeviceCapabilities(device
, port
, DC_PAPERS
, (LPSTR
)papers
, NULL
);
2803 ok(ret
== n_papers
, "expected %d, got %d\n", n_papers
, ret
);
2805 for (ret
= 0; ret
< n_papers
; ret
++)
2806 trace("papers[%d] = %d\n", ret
, papers
[ret
]);
2808 HeapFree(GetProcessHeap(), 0, papers
);
2810 n_paper_size
= DeviceCapabilities(device
, port
, DC_PAPERSIZE
, NULL
, NULL
);
2811 ok(n_paper_size
> 0, "DeviceCapabilities DC_PAPERSIZE failed\n");
2812 ok(n_paper_size
== n_papers
, "n_paper_size %d != n_papers %d\n", n_paper_size
, n_papers
);
2813 paper_size
= HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_size
) * n_paper_size
);
2814 ret
= DeviceCapabilities(device
, port
, DC_PAPERSIZE
, (LPSTR
)paper_size
, NULL
);
2815 ok(ret
== n_paper_size
, "expected %d, got %d\n", n_paper_size
, ret
);
2817 for (ret
= 0; ret
< n_paper_size
; ret
++)
2818 trace("paper_size[%d] = %d x %d\n", ret
, paper_size
[ret
].x
, paper_size
[ret
].y
);
2820 HeapFree(GetProcessHeap(), 0, paper_size
);
2822 n_paper_names
= DeviceCapabilities(device
, port
, DC_PAPERNAMES
, NULL
, NULL
);
2823 ok(n_paper_names
> 0, "DeviceCapabilities DC_PAPERNAMES failed\n");
2824 ok(n_paper_names
== n_papers
, "n_paper_names %d != n_papers %d\n", n_paper_names
, n_papers
);
2825 paper_name
= HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_name
) * n_paper_names
);
2826 ret
= DeviceCapabilities(device
, port
, DC_PAPERNAMES
, (LPSTR
)paper_name
, NULL
);
2827 ok(ret
== n_paper_names
, "expected %d, got %d\n", n_paper_names
, ret
);
2829 for (ret
= 0; ret
< n_paper_names
; ret
++)
2830 trace("paper_name[%u] = %s\n", ret
, paper_name
[ret
].name
);
2832 HeapFree(GetProcessHeap(), 0, paper_name
);
2834 n_copies
= DeviceCapabilities(device
, port
, DC_COPIES
, NULL
, dm
);
2835 ok(n_copies
> 0, "DeviceCapabilities DC_COPIES failed\n");
2836 trace("n_copies = %d\n", n_copies
);
2838 /* these capabilities are not available on all printer drivers */
2841 ret
= DeviceCapabilities(device
, port
, DC_MAXEXTENT
, NULL
, NULL
);
2842 ok(ret
!= -1, "DeviceCapabilities DC_MAXEXTENT failed\n");
2843 ext
= MAKEPOINTS(ret
);
2844 trace("max ext = %d x %d\n", ext
.x
, ext
.y
);
2846 ret
= DeviceCapabilities(device
, port
, DC_MINEXTENT
, NULL
, NULL
);
2847 ok(ret
!= -1, "DeviceCapabilities DC_MINEXTENT failed\n");
2848 ext
= MAKEPOINTS(ret
);
2849 trace("min ext = %d x %d\n", ext
.x
, ext
.y
);
2852 fields
= DeviceCapabilities(device
, port
, DC_FIELDS
, NULL
, NULL
);
2853 ok(fields
!= (DWORD
)-1, "DeviceCapabilities DC_FIELDS failed\n");
2854 ok(fields
== (dm
->dmFields
| DM_FORMNAME
) ||
2855 fields
== ((dm
->dmFields
| DM_FORMNAME
| DM_PAPERSIZE
) & ~(DM_PAPERLENGTH
|DM_PAPERWIDTH
)) ||
2856 broken(fields
== dm
->dmFields
), /* Win9x/WinMe */
2857 "fields %x, dm->dmFields %x\n", fields
, dm
->dmFields
);
2859 GlobalUnlock(prn_dlg
.hDevMode
);
2860 GlobalFree(prn_dlg
.hDevMode
);
2861 GlobalUnlock(prn_dlg
.hDevNames
);
2862 GlobalFree(prn_dlg
.hDevNames
);
2865 static void test_IsValidDevmodeW(void)
2869 if (!pIsValidDevmodeW
)
2871 win_skip("IsValidDevmodeW not implemented.\n");
2875 br
= pIsValidDevmodeW(NULL
, 0);
2876 ok(br
== FALSE
, "Got %d\n", br
);
2878 br
= pIsValidDevmodeW(NULL
, 1);
2879 ok(br
== FALSE
, "Got %d\n", br
);
2881 br
= pIsValidDevmodeW(NULL
, sizeof(DEVMODEW
));
2882 ok(br
== FALSE
, "Got %d\n", br
);
2885 static void test_OpenPrinter_defaults(void)
2891 ADDJOB_INFO_1
*add_job
;
2892 JOB_INFO_2
*job_info
;
2894 PRINTER_DEFAULTS prn_def
;
2897 if (!default_printer
)
2899 skip("There is no default printer installed\n");
2903 /* Printer opened with NULL defaults. Retrieve default paper size
2904 and confirm that jobs have this size. */
2906 ret
= OpenPrinter( default_printer
, &printer
, NULL
);
2909 skip("Unable to open the default printer (%s)\n", default_printer
);
2913 ret
= GetPrinter( printer
, 2, NULL
, 0, &needed
);
2914 ok( !ret
, "got %d\n", ret
);
2915 pi
= HeapAlloc( GetProcessHeap(), 0, needed
);
2916 ret
= GetPrinter( printer
, 2, (BYTE
*)pi
, needed
, &needed
);
2917 ok( ret
, "got %d\n", ret
);
2918 default_size
= pi
->pDevMode
->u1
.s1
.dmPaperSize
;
2919 HeapFree( GetProcessHeap(), 0, pi
);
2921 ret
= AddJob( printer
, 1, NULL
, 0, &needed
);
2922 ok( !ret
, "got %d\n", ret
);
2923 add_job
= HeapAlloc( GetProcessHeap(), 0, needed
);
2924 ret
= AddJob( printer
, 1, (BYTE
*)add_job
, needed
, &needed
);
2925 ok( ret
, "got %d\n", ret
);
2927 ret
= GetJob( printer
, add_job
->JobId
, 2, NULL
, 0, &needed
);
2928 ok( !ret
, "got %d\n", ret
);
2929 job_info
= HeapAlloc( GetProcessHeap(), 0, needed
);
2930 ret
= GetJob( printer
, add_job
->JobId
, 2, (BYTE
*)job_info
, needed
, &needed
);
2931 ok( ret
, "got %d\n", ret
);
2934 ok( job_info
->pDevMode
!= NULL
, "got NULL devmode\n");
2935 if (job_info
->pDevMode
)
2936 ok( job_info
->pDevMode
->u1
.s1
.dmPaperSize
== default_size
, "got %d default %d\n",
2937 job_info
->pDevMode
->u1
.s1
.dmPaperSize
, default_size
);
2939 HeapFree( GetProcessHeap(), 0, job_info
);
2940 ScheduleJob( printer
, add_job
->JobId
); /* remove the empty job */
2941 HeapFree( GetProcessHeap(), 0, add_job
);
2942 ClosePrinter( printer
);
2944 /* Printer opened with something other than the default paper size. */
2946 memset( &my_dm
, 0, sizeof(my_dm
) );
2947 my_dm
.dmSize
= sizeof(my_dm
);
2948 my_dm
.dmFields
= DM_PAPERSIZE
;
2949 my_dm
.u1
.s1
.dmPaperSize
= (default_size
== DMPAPER_A4
) ? DMPAPER_LETTER
: DMPAPER_A4
;
2951 prn_def
.pDatatype
= NULL
;
2952 prn_def
.pDevMode
= &my_dm
;
2953 prn_def
.DesiredAccess
= PRINTER_ACCESS_USE
;
2955 ret
= OpenPrinter( default_printer
, &printer
, &prn_def
);
2956 ok( ret
, "got %d\n", ret
);
2958 /* GetPrinter stills returns default size */
2959 ret
= GetPrinter( printer
, 2, NULL
, 0, &needed
);
2960 ok( !ret
, "got %d\n", ret
);
2961 pi
= HeapAlloc( GetProcessHeap(), 0, needed
);
2962 ret
= GetPrinter( printer
, 2, (BYTE
*)pi
, needed
, &needed
);
2963 ok( ret
, "got %d\n", ret
);
2964 ok( pi
->pDevMode
->u1
.s1
.dmPaperSize
== default_size
, "got %d default %d\n",
2965 pi
->pDevMode
->u1
.s1
.dmPaperSize
, default_size
);
2967 HeapFree( GetProcessHeap(), 0, pi
);
2969 /* However the GetJob has the new size */
2970 ret
= AddJob( printer
, 1, NULL
, 0, &needed
);
2971 ok( !ret
, "got %d\n", ret
);
2972 add_job
= HeapAlloc( GetProcessHeap(), 0, needed
);
2973 ret
= AddJob( printer
, 1, (BYTE
*)add_job
, needed
, &needed
);
2974 ok( ret
, "got %d\n", ret
);
2976 ret
= GetJob( printer
, add_job
->JobId
, 2, NULL
, 0, &needed
);
2977 ok( !ret
, "got %d\n", ret
);
2978 job_info
= HeapAlloc( GetProcessHeap(), 0, needed
);
2979 ret
= GetJob( printer
, add_job
->JobId
, 2, (BYTE
*)job_info
, needed
, &needed
);
2980 ok( ret
, "got %d\n", ret
);
2982 ok( job_info
->pDevMode
->dmFields
== DM_PAPERSIZE
, "got %08x\n",
2983 job_info
->pDevMode
->dmFields
);
2984 ok( job_info
->pDevMode
->u1
.s1
.dmPaperSize
== my_dm
.u1
.s1
.dmPaperSize
,
2985 "got %d new size %d\n",
2986 job_info
->pDevMode
->u1
.s1
.dmPaperSize
, my_dm
.u1
.s1
.dmPaperSize
);
2988 HeapFree( GetProcessHeap(), 0, job_info
);
2989 ScheduleJob( printer
, add_job
->JobId
); /* remove the empty job */
2990 HeapFree( GetProcessHeap(), 0, add_job
);
2991 ClosePrinter( printer
);
2996 hwinspool
= LoadLibrary("winspool.drv");
2997 pAddPortExA
= (void *) GetProcAddress(hwinspool
, "AddPortExA");
2998 pEnumPrinterDriversW
= (void *) GetProcAddress(hwinspool
, "EnumPrinterDriversW");
2999 pGetDefaultPrinterA
= (void *) GetProcAddress(hwinspool
, "GetDefaultPrinterA");
3000 pGetPrinterDataExA
= (void *) GetProcAddress(hwinspool
, "GetPrinterDataExA");
3001 pGetPrinterDriverW
= (void *) GetProcAddress(hwinspool
, "GetPrinterDriverW");
3002 pGetPrinterW
= (void *) GetProcAddress(hwinspool
, "GetPrinterW");
3003 pSetDefaultPrinterA
= (void *) GetProcAddress(hwinspool
, "SetDefaultPrinterA");
3004 pXcvDataW
= (void *) GetProcAddress(hwinspool
, "XcvDataW");
3005 pIsValidDevmodeW
= (void *) GetProcAddress(hwinspool
, "IsValidDevmodeW");
3007 on_win9x
= check_win9x();
3009 win_skip("Several W-functions are not available on Win9x/WinMe\n");
3011 find_default_printer();
3012 find_local_server();
3018 test_ConfigurePort();
3019 test_DeleteMonitor();
3021 test_DeviceCapabilities();
3022 test_DocumentProperties();
3023 test_EnumForms(NULL
);
3024 if (default_printer
) test_EnumForms(default_printer
);
3025 test_EnumMonitors();
3027 test_EnumPrinterDrivers();
3028 test_EnumPrinters();
3029 test_EnumPrintProcessors();
3030 test_GetDefaultPrinter();
3031 test_GetPrinterDriverDirectory();
3032 test_GetPrintProcessorDirectory();
3035 test_GetPrinterData();
3036 test_GetPrinterDataEx();
3037 test_GetPrinterDriver();
3038 test_SetDefaultPrinter();
3039 test_XcvDataW_MonitorUI();
3040 test_XcvDataW_PortIsValid();
3041 test_IsValidDevmodeW();
3042 test_OpenPrinter_defaults();
3044 /* Cleanup our temporary file */
3045 DeleteFileA(tempfileA
);