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
23 #include "wine/test.h"
32 #define MAGIC_DEAD 0xdeadbeef
33 #define DEFAULT_PRINTER_SIZE 1000
35 static CHAR does_not_exist_dll[]= "does_not_exists.dll";
36 static CHAR does_not_exist[] = "does_not_exists";
37 static CHAR empty[] = "";
38 static CHAR env_x86[] = "Windows NT x86";
39 static CHAR env_win9x_case[] = "windowS 4.0";
40 static CHAR illegal_name[] = "illegal,name";
41 static CHAR invalid_env[] = "invalid_env";
42 static CHAR invalid_server[] = "\\invalid_server";
43 static CHAR portname_com1[] = "COM1:";
44 static CHAR portname_file[] = "FILE:";
45 static CHAR portname_lpt1[] = "LPT1:";
46 static CHAR version_dll[] = "version.dll";
47 static CHAR winetest_monitor[] = "winetest";
49 static HANDLE hwinspool;
50 static FARPROC pGetDefaultPrinterA;
51 static FARPROC pSetDefaultPrinterA;
53 struct monitor_entry {
58 static LPSTR default_printer = NULL;
60 /* report common behavior only once */
61 static DWORD report_deactivated_spooler = 1;
62 #define RETURN_ON_DEACTIVATED_SPOOLER(res) \
63 if((res == 0) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE)) \
65 if(report_deactivated_spooler > 0) { \
66 report_deactivated_spooler--; \
67 trace("The Service 'Spooler' is required for many test\n"); \
73 static void find_default_printer(VOID)
75 static char buffer[DEFAULT_PRINTER_SIZE];
80 if ((default_printer == NULL) && (pGetDefaultPrinterA))
83 needed = sizeof(buffer);
84 res = pGetDefaultPrinterA(buffer, &needed);
85 if(res) default_printer = buffer;
86 trace("default_printer: '%s'\n", default_printer);
88 if (default_printer == NULL)
92 /* NT 3.x and above */
93 if (RegOpenKeyEx(HKEY_CURRENT_USER,
94 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
95 0, KEY_QUERY_VALUE, &hwindows) == NO_ERROR) {
97 needed = sizeof(buffer);
98 if (RegQueryValueEx(hwindows, "device", NULL,
99 &type, (LPBYTE)buffer, &needed) == NO_ERROR) {
101 ptr = strchr(buffer, ',');
104 default_printer = buffer;
107 RegCloseKey(hwindows);
109 trace("default_printer: '%s'\n", default_printer);
111 if (default_printer == NULL)
114 needed = sizeof(buffer);
115 res = GetProfileStringA("windows", "device", "*", buffer, needed);
117 ptr = strchr(buffer, ',');
120 default_printer = buffer;
123 trace("default_printer: '%s'\n", default_printer);
128 static struct monitor_entry * find_installed_monitor(void)
130 MONITOR_INFO_2A mi2a;
131 static struct monitor_entry * entry = NULL;
135 static struct monitor_entry monitor_table[] = {
136 {env_win9x_case, "localspl.dll"},
137 {env_x86, "localspl.dll"},
138 {env_win9x_case, "localmon.dll"},
139 {env_x86, "localmon.dll"},
140 {env_win9x_case, "tcpmon.dll"},
141 {env_x86, "tcpmon.dll"},
142 {env_win9x_case, "usbmon.dll"},
143 {env_x86, "usbmon.dll"},
144 {env_win9x_case, "mspp32.dll"},
145 {env_x86, "win32spl.dll"},
146 {env_x86, "redmonnt.dll"},
147 {env_x86, "redmon35.dll"},
148 {env_win9x_case, "redmon95.dll"},
149 {env_x86, "pdfcmnnt.dll"},
150 {env_win9x_case, "pdfcmn95.dll"},
153 if (entry) return entry;
155 num_tests = (sizeof(monitor_table)/sizeof(struct monitor_entry));
158 DeleteMonitorA(NULL, env_x86, winetest_monitor);
159 DeleteMonitorA(NULL, env_win9x_case, winetest_monitor);
161 /* find a usable monitor from the table */
162 mi2a.pName = winetest_monitor;
163 while ((entry == NULL) && (i < num_tests)) {
164 entry = &monitor_table[i];
166 mi2a.pEnvironment = entry->env;
167 mi2a.pDLLName = entry->dllname;
169 if (AddMonitorA(NULL, 2, (LPBYTE) &mi2a)) {
171 trace("using '%s', '%s'\n", entry->env, entry->dllname);
172 DeleteMonitorA(NULL, entry->env, winetest_monitor);
182 /* ########################### */
185 static void test_AddMonitor(void)
187 MONITOR_INFO_2A mi2a;
188 struct monitor_entry * entry = NULL;
191 entry = find_installed_monitor();
193 SetLastError(MAGIC_DEAD);
194 res = AddMonitorA(NULL, 1, NULL);
195 ok(!res && (GetLastError() == ERROR_INVALID_LEVEL),
196 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
197 res, GetLastError());
199 SetLastError(MAGIC_DEAD);
200 res = AddMonitorA(NULL, 3, NULL);
201 ok(!res && (GetLastError() == ERROR_INVALID_LEVEL),
202 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
203 res, GetLastError());
206 /* This test crash with win9x on vmware (works with win9x on qemu 0.8.1) */
207 SetLastError(MAGIC_DEAD);
208 res = AddMonitorA(NULL, 2, NULL);
209 /* NT: unchanged, 9x: ERROR_PRIVILEGE_NOT_HELD */
211 ((GetLastError() == MAGIC_DEAD) ||
212 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
213 "returned %d with %d (expected '0' with: MAGIC_DEAD or " \
214 "ERROR_PRIVILEGE_NOT_HELD)\n", res, GetLastError());
217 ZeroMemory(&mi2a, sizeof(MONITOR_INFO_2A));
218 SetLastError(MAGIC_DEAD);
219 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
220 RETURN_ON_DEACTIVATED_SPOOLER(res)
222 if (!res && (GetLastError() == ERROR_ACCESS_DENIED)) {
223 trace("skip tests (ACCESS_DENIED)\n");
227 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_INVALID_ENVIRONMENT */
228 ok(!res && ((GetLastError() == ERROR_INVALID_PARAMETER) ||
229 (GetLastError() == ERROR_INVALID_ENVIRONMENT)),
230 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
231 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
234 trace("No usable Monitor found: Skip tests\n");
239 /* The Test is deactivated, because when mi2a.pName is NULL, the subkey
240 HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM
241 or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì
242 is created on win9x and we do not want to hit this bug here. */
244 mi2a.pEnvironment = entry->env;
245 SetLastError(MAGIC_DEAD);
246 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
247 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
250 mi2a.pEnvironment = entry->env;
252 SetLastError(MAGIC_DEAD);
253 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
254 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
256 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
257 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
258 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
259 "ERROR_PRIVILEGE_NOT_HELD)\n",
260 res, GetLastError());
262 mi2a.pName = winetest_monitor;
263 SetLastError(MAGIC_DEAD);
264 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
265 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
267 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
268 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
269 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
270 "ERROR_PRIVILEGE_NOT_HELD)\n",
271 res, GetLastError());
273 mi2a.pDLLName = empty;
274 SetLastError(MAGIC_DEAD);
275 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
276 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
277 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
278 res, GetLastError());
280 mi2a.pDLLName = does_not_exist_dll;
281 SetLastError(MAGIC_DEAD);
282 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
283 /* NT: ERROR_MOD_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
285 ((GetLastError() == ERROR_MOD_NOT_FOUND) ||
286 (GetLastError() == ERROR_INVALID_PARAMETER)),
287 "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or " \
288 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
290 mi2a.pDLLName = version_dll;
291 SetLastError(MAGIC_DEAD);
292 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
293 /* NT: ERROR_PROC_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
295 ((GetLastError() == ERROR_PROC_NOT_FOUND) ||
296 (GetLastError() == ERROR_INVALID_PARAMETER)),
297 "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or " \
298 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
299 if (res) DeleteMonitorA(NULL, entry->env, winetest_monitor);
301 /* Test AddMonitor with real options */
302 mi2a.pDLLName = entry->dllname;
303 SetLastError(MAGIC_DEAD);
304 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
305 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
307 /* add a monitor twice */
308 SetLastError(MAGIC_DEAD);
309 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
310 /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */
312 ((GetLastError() == ERROR_PRINT_MONITOR_ALREADY_INSTALLED) ||
313 (GetLastError() == ERROR_ALREADY_EXISTS)),
314 "returned %d with %d (expected '0' with: " \
315 "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n",
316 res, GetLastError());
318 DeleteMonitorA(NULL, entry->env, winetest_monitor);
319 SetLastError(MAGIC_DEAD);
320 res = AddMonitorA(empty, 2, (LPBYTE) &mi2a);
321 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
324 DeleteMonitorA(NULL, entry->env, winetest_monitor);
328 /* ########################### */
330 static void test_AddPort(void)
334 SetLastError(0xdeadbeef);
335 res = AddPortA(NULL, 0, NULL);
336 RETURN_ON_DEACTIVATED_SPOOLER(res)
337 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
338 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) ||
339 (GetLastError() == ERROR_INVALID_PARAMETER)),
340 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " \
341 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
344 SetLastError(0xdeadbeef);
345 res = AddPortA(NULL, 0, empty);
346 /* Allowed only for (Printer-)Administrators */
347 if (!res && (GetLastError() == ERROR_ACCESS_DENIED)) {
348 trace("skip tests (ACCESS_DENIED)\n");
351 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
352 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
353 (GetLastError() == ERROR_INVALID_PARAMETER)),
354 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " \
355 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
358 SetLastError(0xdeadbeef);
359 res = AddPortA(NULL, 0, does_not_exist);
360 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
361 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
362 (GetLastError() == ERROR_INVALID_PARAMETER)),
363 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " \
364 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
368 /* ########################### */
370 static void test_ConfigurePort(void)
375 SetLastError(0xdeadbeef);
376 res = ConfigurePortA(NULL, 0, NULL);
377 RETURN_ON_DEACTIVATED_SPOOLER(res)
378 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
379 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) ||
380 (GetLastError() == ERROR_INVALID_PARAMETER)),
381 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " \
382 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
384 SetLastError(0xdeadbeef);
385 res = ConfigurePortA(NULL, 0, empty);
386 /* Allowed only for (Printer-)Administrators */
387 if (!res && (GetLastError() == ERROR_ACCESS_DENIED)) {
388 trace(" skip tests (ACCESS_DENIED)\n");
391 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
392 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
393 (GetLastError() == ERROR_INVALID_PARAMETER)),
394 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " \
395 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
398 SetLastError(0xdeadbeef);
399 res = ConfigurePortA(NULL, 0, does_not_exist);
400 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
401 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
402 (GetLastError() == ERROR_INVALID_PARAMETER)),
403 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " \
404 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
408 - Case of Portnames is ignored
409 - Portname without ":" => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
410 - Empty Servername (LPT1:) => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
412 - Port not present => 9x: ERROR_INVALID_PARAMETER, NT:ERROR_NOT_SUPPORTED
413 - "FILE:" => 9x:Success, NT:ERROR_CANCELED
414 - Cancel ("Local Port") => ERROR_CANCELED
415 - Cancel ("Redirected Port") => Success
417 if (winetest_interactive > 0) {
418 SetLastError(0xdeadbeef);
419 res = ConfigurePortA(NULL, 0, portname_com1);
420 trace("'%s' returned %d with %d\n", portname_com1, res, GetLastError());
422 SetLastError(0xdeadbeef);
423 res = ConfigurePortA(NULL, 0, portname_lpt1);
424 trace("'%s' returned %d with %d\n", portname_lpt1, res, GetLastError());
426 SetLastError(0xdeadbeef);
427 res = ConfigurePortA(NULL, 0, portname_file);
428 trace("'%s' returned %d with %d\n", portname_file, res, GetLastError());
432 /* ########################### */
434 static void test_DeleteMonitor(void)
436 MONITOR_INFO_2A mi2a;
437 struct monitor_entry * entry = NULL;
441 entry = find_installed_monitor();
444 trace("No usable Monitor found: Skip tests\n");
448 mi2a.pName = winetest_monitor;
449 mi2a.pEnvironment = entry->env;
450 mi2a.pDLLName = entry->dllname;
452 /* Testing DeleteMonitor with real options */
453 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
455 SetLastError(MAGIC_DEAD);
456 res = DeleteMonitorA(NULL, entry->env, winetest_monitor);
457 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
459 /* Delete the Monitor twice */
460 SetLastError(MAGIC_DEAD);
461 res = DeleteMonitorA(NULL, entry->env, winetest_monitor);
462 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
464 ((GetLastError() == ERROR_UNKNOWN_PRINT_MONITOR) ||
465 (GetLastError() == ERROR_INVALID_PARAMETER)),
466 "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR" \
467 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
469 /* the environment */
470 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
471 SetLastError(MAGIC_DEAD);
472 res = DeleteMonitorA(NULL, NULL, winetest_monitor);
473 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
475 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
476 SetLastError(MAGIC_DEAD);
477 res = DeleteMonitorA(NULL, empty, winetest_monitor);
478 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
480 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
481 SetLastError(MAGIC_DEAD);
482 res = DeleteMonitorA(NULL, invalid_env, winetest_monitor);
483 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
485 /* the monitor-name */
486 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
487 SetLastError(MAGIC_DEAD);
488 res = DeleteMonitorA(NULL, entry->env, NULL);
489 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
491 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
492 (GetLastError() == ERROR_INVALID_NAME)),
493 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
494 "ERROR_INVALID_NAME)\n", res, GetLastError());
496 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
497 SetLastError(MAGIC_DEAD);
498 res = DeleteMonitorA(NULL, entry->env, empty);
499 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
501 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
502 (GetLastError() == ERROR_INVALID_NAME)),
503 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
504 "ERROR_INVALID_NAME)\n", res, GetLastError());
506 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
507 SetLastError(MAGIC_DEAD);
508 res = DeleteMonitorA(empty, entry->env, winetest_monitor);
509 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
512 DeleteMonitorA(NULL, entry->env, winetest_monitor);
515 /* ########################### */
517 static void test_DeletePort(void)
521 SetLastError(0xdeadbeef);
522 res = DeletePortA(NULL, 0, NULL);
523 RETURN_ON_DEACTIVATED_SPOOLER(res)
525 SetLastError(0xdeadbeef);
526 res = DeletePortA(NULL, 0, empty);
527 /* Allowed only for (Printer-)Administrators */
528 if (!res && (GetLastError() == ERROR_ACCESS_DENIED)) {
529 trace("skip tests (ACCESS_DENIED)\n");
532 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
533 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
534 (GetLastError() == ERROR_INVALID_PARAMETER)),
535 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " \
536 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
539 SetLastError(0xdeadbeef);
540 res = DeletePortA(NULL, 0, does_not_exist);
541 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
542 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
543 (GetLastError() == ERROR_INVALID_PARAMETER)),
544 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " \
545 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
549 /* ########################### */
551 static void test_EnumForms(LPSTR pName)
562 res = OpenPrinter(pName, &hprinter, NULL);
563 RETURN_ON_DEACTIVATED_SPOOLER(res)
564 if (!res || !hprinter)
566 /* Open the local Prinserver is not supported on win9x */
567 if (pName) trace("Failed to open '%s', skiping the test\n", pName);
571 /* valid levels are 1 and 2 */
572 for(level = 0; level < 4; level++) {
574 pcReturned = 0xdeadbeef;
575 SetLastError(0xdeadbeef);
576 res = EnumFormsA(hprinter, level, NULL, 0, &cbBuf, &pcReturned);
578 /* EnumForms is not implemented in win9x */
579 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
581 /* EnumForms for the Server not implemented on all NT-Versions */
582 if (!res && (GetLastError() == ERROR_INVALID_HANDLE) && !pName) continue;
584 /* Level 2 for EnumForms is not supported on all systems */
585 if (!res && (GetLastError() == ERROR_INVALID_LEVEL) && (level == 2)) continue;
587 /* use only a short test, when we test with an invalid level */
588 if(!level || (level > 2)) {
589 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
590 (res && (pcReturned == 0)),
591 "(%d) returned %d with %d and 0x%08x (expected '0' with " \
592 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
593 level, res, GetLastError(), pcReturned);
597 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
598 "(%d) returned %d with %d (expected '0' with " \
599 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
601 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
602 if (buffer == NULL) continue;
604 SetLastError(0xdeadbeef);
605 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
606 ok(res, "(%d) returned %d with %d (expected '!=0')\n",
607 level, res, GetLastError());
608 /* We can dump the returned Data here */
611 SetLastError(0xdeadbeef);
612 res = EnumFormsA(hprinter, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
613 ok( res, "(%d) returned %d with %d (expected '!=0')\n",
614 level, res, GetLastError());
616 SetLastError(0xdeadbeef);
617 res = EnumFormsA(hprinter, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
618 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
619 "(%d) returned %d with %d (expected '0' with " \
620 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
623 SetLastError(0xdeadbeef);
624 res = EnumFormsA(hprinter, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
625 ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) ,
626 "(%d) returned %d with %d (expected '0' with "\
627 "ERROR_INVALID_USER_BUFFER)\n", level, res, GetLastError());
630 SetLastError(0xdeadbeef);
631 res = EnumFormsA(hprinter, level, buffer, cbBuf, NULL, &pcReturned);
632 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
633 "(%d) returned %d with %d (expected '0' with "\
634 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
636 SetLastError(0xdeadbeef);
637 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, NULL);
638 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
639 "(%d) returned %d with %d (expected '0' with "\
640 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
642 SetLastError(0xdeadbeef);
643 res = EnumFormsA(0, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
644 ok( !res && (GetLastError() == ERROR_INVALID_HANDLE) ,
645 "(%d) returned %d with %d (expected '0' with "\
646 "ERROR_INVALID_HANDLE)\n", level, res, GetLastError());
648 HeapFree(GetProcessHeap(), 0, buffer);
649 } /* for(level ... */
651 ClosePrinter(hprinter);
654 /* ########################### */
656 static void test_EnumMonitors(void)
665 /* valid levels are 1 and 2 */
666 for(level = 0; level < 4; level++) {
668 pcReturned = MAGIC_DEAD;
669 SetLastError(MAGIC_DEAD);
670 res = EnumMonitorsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
672 RETURN_ON_DEACTIVATED_SPOOLER(res)
674 /* not implemented yet in wine */
675 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
678 /* use only a short test, when we test with an invalid level */
679 if(!level || (level > 2)) {
680 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
681 (res && (pcReturned == 0)),
682 "(%d) returned %d with %d and 0x%08x (expected '0' with " \
683 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
684 level, res, GetLastError(), pcReturned);
688 /* Level 2 is not supported on win9x */
689 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
690 trace("Level %d not supported, skipping tests\n", level);
694 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
695 "(%d) returned %d with %d (expected '0' with " \
696 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
699 trace("no valid buffer size returned, skipping tests\n");
703 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
704 if (buffer == NULL) continue;
706 SetLastError(MAGIC_DEAD);
707 pcbNeeded = MAGIC_DEAD;
708 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
709 ok(res, "(%d) returned %d with %d (expected '!=0')\n",
710 level, res, GetLastError());
711 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n",
712 level, pcbNeeded, cbBuf);
713 /* We can validate the returned Data with the Registry here */
716 SetLastError(MAGIC_DEAD);
717 pcReturned = MAGIC_DEAD;
718 pcbNeeded = MAGIC_DEAD;
719 res = EnumMonitorsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
720 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level,
721 res, GetLastError());
722 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
725 SetLastError(MAGIC_DEAD);
726 pcbNeeded = MAGIC_DEAD;
727 res = EnumMonitorsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
728 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
729 "(%d) returned %d with %d (expected '0' with " \
730 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
732 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
736 Do not add the next test:
737 w2k+: RPC_X_NULL_REF_POINTER
738 NT3.5: ERROR_INVALID_USER_BUFFER
739 win9x: crash in winspool.drv
741 res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
744 SetLastError(MAGIC_DEAD);
745 pcbNeeded = MAGIC_DEAD;
746 pcReturned = MAGIC_DEAD;
747 res = EnumMonitorsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
748 ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
749 "(%d) returned %d with %d (expected '!=0' or '0' with "\
750 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
752 pcbNeeded = MAGIC_DEAD;
753 pcReturned = MAGIC_DEAD;
754 SetLastError(MAGIC_DEAD);
755 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
756 ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
757 "(%d) returned %d with %d (expected '!=0' or '0' with "\
758 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
760 HeapFree(GetProcessHeap(), 0, buffer);
761 } /* for(level ... */
764 /* ########################### */
766 static void test_EnumPorts(void)
775 /* valid levels are 1 and 2 */
776 for(level = 0; level < 4; level++) {
779 pcReturned = 0xdeadbeef;
780 SetLastError(0xdeadbeef);
781 res = EnumPortsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
782 RETURN_ON_DEACTIVATED_SPOOLER(res)
784 /* use only a short test, when we test with an invalid level */
785 if(!level || (level > 2)) {
786 /* NT: ERROR_INVALID_LEVEL, 9x: success */
787 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
788 (res && (pcReturned == 0)),
789 "(%d) returned %d with %d and 0x%08x (expected '0' with " \
790 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
791 level, res, GetLastError(), pcReturned);
796 /* Level 2 is not supported on NT 3.x */
797 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
798 trace("Level %d not supported, skipping tests\n", level);
802 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
803 "(%d) returned %d with %d (expected '0' with " \
804 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
806 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
807 if (buffer == NULL) continue;
809 pcbNeeded = 0xdeadbeef;
810 SetLastError(0xdeadbeef);
811 res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
812 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
813 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
814 /* ToDo: Compare the returned Data with the Registry / "win.ini",[Ports] here */
816 pcbNeeded = 0xdeadbeef;
817 pcReturned = 0xdeadbeef;
818 SetLastError(0xdeadbeef);
819 res = EnumPortsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
820 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
821 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
823 pcbNeeded = 0xdeadbeef;
824 SetLastError(0xdeadbeef);
825 res = EnumPortsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
826 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
827 "(%d) returned %d with %d (expected '0' with " \
828 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
829 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
832 Do not add this test:
833 res = EnumPortsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
834 w2k+: RPC_X_NULL_REF_POINTER
835 NT3.5: ERROR_INVALID_USER_BUFFER
836 win9x: crash in winspool.drv
839 SetLastError(0xdeadbeef);
840 res = EnumPorts(NULL, level, buffer, cbBuf, NULL, &pcReturned);
841 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
842 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
843 ( res && (GetLastError() == ERROR_SUCCESS) ),
844 "(%d) returned %d with %d (expected '0' with " \
845 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
846 level, res, GetLastError());
849 SetLastError(0xdeadbeef);
850 res = EnumPorts(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
851 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
852 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
853 ( res && (GetLastError() == ERROR_SUCCESS) ),
854 "(%d) returned %d with %d (expected '0' with " \
855 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
856 level, res, GetLastError());
858 HeapFree(GetProcessHeap(), 0, buffer);
862 /* ########################### */
864 static void test_GetDefaultPrinter(void)
867 DWORD exact = DEFAULT_PRINTER_SIZE;
869 char buffer[DEFAULT_PRINTER_SIZE];
871 if (!pGetDefaultPrinterA) return;
872 /* only supported on NT like OSes starting with win2k */
874 SetLastError(ERROR_SUCCESS);
875 retval = pGetDefaultPrinterA(buffer, &exact);
876 if (!retval || !exact || !strlen(buffer) ||
877 (ERROR_SUCCESS != GetLastError())) {
878 if ((ERROR_FILE_NOT_FOUND == GetLastError()) ||
879 (ERROR_INVALID_NAME == GetLastError()))
880 trace("this test requires a default printer to be set\n");
882 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
883 "function returned %s\n"
884 "last error 0x%08x\n"
885 "returned buffer size 0x%08x\n"
886 "returned buffer content %s\n",
887 retval ? "true" : "false", GetLastError(), exact, buffer);
891 SetLastError(ERROR_SUCCESS);
892 retval = pGetDefaultPrinterA(NULL, NULL);
893 ok( !retval, "function result wrong! False expected\n");
894 ok( ERROR_INVALID_PARAMETER == GetLastError(),
895 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
898 SetLastError(ERROR_SUCCESS);
899 retval = pGetDefaultPrinterA(buffer, NULL);
900 ok( !retval, "function result wrong! False expected\n");
901 ok( ERROR_INVALID_PARAMETER == GetLastError(),
902 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
905 SetLastError(ERROR_SUCCESS);
907 retval = pGetDefaultPrinterA(NULL, &size);
908 ok( !retval, "function result wrong! False expected\n");
909 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
910 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
912 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
915 SetLastError(ERROR_SUCCESS);
916 size = DEFAULT_PRINTER_SIZE;
917 retval = pGetDefaultPrinterA(NULL, &size);
918 ok( !retval, "function result wrong! False expected\n");
919 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
920 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
922 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
926 retval = pGetDefaultPrinterA(buffer, &size);
927 ok( !retval, "function result wrong! False expected\n");
928 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
929 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
931 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
935 retval = pGetDefaultPrinterA(buffer, &size);
936 ok( retval, "function result wrong! True expected\n");
937 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
941 static void test_GetPrinterDriverDirectory(void)
943 LPBYTE buffer = NULL;
944 DWORD cbBuf = 0, pcbNeeded = 0;
948 SetLastError(MAGIC_DEAD);
949 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
950 trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
951 res, GetLastError(), cbBuf);
953 RETURN_ON_DEACTIVATED_SPOOLER(res)
954 ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
955 "returned %d with lasterror=%d (expected '0' with " \
956 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
959 trace("no valid buffer size returned, skipping tests\n");
963 buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
964 if (buffer == NULL) return ;
966 res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
967 ok( res, "expected result != 0, got %d\n", res);
968 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
971 res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
972 ok( res, "expected result != 0, got %d\n", res);
973 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
976 SetLastError(MAGIC_DEAD);
977 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
978 ok( !res , "expected result == 0, got %d\n", res);
979 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
982 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
983 "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
987 Do not add the next test:
988 XPsp2: crash in this app, when the spooler is not running
989 NT3.5: ERROR_INVALID_USER_BUFFER
990 win9x: ERROR_INVALID_PARAMETER
992 pcbNeeded = MAGIC_DEAD;
993 SetLastError(MAGIC_DEAD);
994 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
997 SetLastError(MAGIC_DEAD);
998 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
999 ok( (!res && RPC_X_NULL_REF_POINTER == GetLastError()) || res,
1000 "expected either result == 0 and "
1001 "last error == RPC_X_NULL_REF_POINTER or result != 0 "
1002 "got result %d and last error == %d\n", res, GetLastError());
1004 SetLastError(MAGIC_DEAD);
1005 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
1006 ok(res || (GetLastError() == RPC_X_NULL_REF_POINTER),
1007 "returned %d with %d (expected '!=0' or '0' with " \
1008 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
1011 /* with a valid buffer, but level is too large */
1013 SetLastError(MAGIC_DEAD);
1014 res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
1016 /* Level not checked in win9x and wine:*/
1017 if((res != FALSE) && buffer[0])
1019 trace("Level '2' not checked '%s'\n", buffer);
1023 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1024 "returned %d with lasterror=%d (expected '0' with " \
1025 "ERROR_INVALID_LEVEL)\n", res, GetLastError());
1028 /* printing environments are case insensitive */
1029 /* "Windows 4.0" is valid for win9x and NT */
1031 SetLastError(MAGIC_DEAD);
1032 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1,
1033 buffer, cbBuf*2, &pcbNeeded);
1035 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
1037 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1038 if (buffer == NULL) return ;
1040 SetLastError(MAGIC_DEAD);
1041 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1,
1042 buffer, cbBuf*2, &pcbNeeded);
1045 ok(res && buffer[0], "returned %d with " \
1046 "lasterror=%d and len=%d (expected '1' with 'len > 0')\n",
1047 res, GetLastError(), lstrlenA((char *)buffer));
1050 SetLastError(MAGIC_DEAD);
1051 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1,
1052 buffer, cbBuf*2, &pcbNeeded);
1054 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
1056 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1057 if (buffer == NULL) return ;
1060 SetLastError(MAGIC_DEAD);
1061 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1,
1062 buffer, cbBuf*2, &pcbNeeded);
1065 /* "Windows NT x86" is invalid for win9x */
1066 ok( (res && buffer[0]) ||
1067 (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)),
1068 "returned %d with lasterror=%d and len=%d (expected '!= 0' with " \
1069 "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
1070 res, GetLastError(), lstrlenA((char *)buffer));
1072 /* A setup program (PDFCreator_0.8.0) use empty strings */
1073 SetLastError(MAGIC_DEAD);
1074 res = GetPrinterDriverDirectoryA(empty, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1075 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1077 SetLastError(MAGIC_DEAD);
1078 res = GetPrinterDriverDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1079 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1081 SetLastError(MAGIC_DEAD);
1082 res = GetPrinterDriverDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1083 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1085 HeapFree( GetProcessHeap(), 0, buffer);
1090 static void test_GetPrintProcessorDirectory(void)
1092 LPBYTE buffer = NULL;
1094 DWORD pcbNeeded = 0;
1098 SetLastError(0xdeadbeef);
1099 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf);
1100 /* The deactivated Spooler is caught here on NT3.51 */
1101 RETURN_ON_DEACTIVATED_SPOOLER(res)
1102 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1103 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1104 res, GetLastError());
1106 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2);
1107 if(buffer == NULL) return;
1110 SetLastError(0xdeadbeef);
1111 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
1112 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1114 SetLastError(0xdeadbeef);
1116 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1117 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1119 /* Buffer to small */
1121 SetLastError(0xdeadbeef);
1122 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
1123 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1124 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1125 res, GetLastError());
1128 /* XPsp2: the program will crash here, when the spooler is not running */
1129 /* GetPrinterDriverDirectory has the same bug */
1131 SetLastError(0xdeadbeef);
1132 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1136 SetLastError(0xdeadbeef);
1137 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
1138 /* NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1139 ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER),
1140 "returned %d with %d (expected '!= 0' or '0' with " \
1141 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
1145 SetLastError(0xdeadbeef);
1146 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
1147 /* NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1148 ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER),
1149 "returned %d with %d (expected '!= 0' or '0' with " \
1150 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
1153 /* with a valid buffer, but level is invalid */
1155 SetLastError(0xdeadbeef);
1156 res = GetPrintProcessorDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
1157 if (res && buffer[0])
1159 /* Level is ignored in win9x*/
1160 trace("invalid level (2) was ignored\n");
1164 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1165 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1166 res, GetLastError());
1169 /* Empty environment is the same as the default environment */
1171 SetLastError(0xdeadbeef);
1172 res = GetPrintProcessorDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1173 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1175 /* "Windows 4.0" is valid for win9x and NT */
1177 SetLastError(0xdeadbeef);
1178 res = GetPrintProcessorDirectoryA(NULL, env_win9x_case, 1, buffer, cbBuf*2, &pcbNeeded);
1179 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1182 /* "Windows NT x86" is invalid for win9x */
1184 SetLastError(0xdeadbeef);
1185 res = GetPrintProcessorDirectoryA(NULL, env_x86, 1, buffer, cbBuf*2, &pcbNeeded);
1186 ok( res || (GetLastError() == ERROR_INVALID_ENVIRONMENT),
1187 "returned %d with %d (expected '!= 0' or '0' with " \
1188 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
1190 /* invalid on all Systems */
1192 SetLastError(0xdeadbeef);
1193 res = GetPrintProcessorDirectoryA(NULL, invalid_env, 1, buffer, cbBuf*2, &pcbNeeded);
1194 ok( !res && (GetLastError() == ERROR_INVALID_ENVIRONMENT),
1195 "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
1196 res, GetLastError());
1198 /* Empty servername is the same as the local computer */
1200 SetLastError(0xdeadbeef);
1201 res = GetPrintProcessorDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1202 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1204 /* invalid on all Systems */
1206 SetLastError(0xdeadbeef);
1207 res = GetPrintProcessorDirectoryA(invalid_server, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1208 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
1209 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1210 res, GetLastError());
1212 HeapFree(GetProcessHeap(), 0, buffer);
1217 static void test_OpenPrinter(void)
1219 PRINTER_DEFAULTSA defaults;
1223 CHAR buffer[DEFAULT_PRINTER_SIZE];
1227 SetLastError(MAGIC_DEAD);
1228 res = OpenPrinter(NULL, NULL, NULL);
1229 /* The deactivated Spooler is caught here on NT3.51 */
1230 RETURN_ON_DEACTIVATED_SPOOLER(res)
1231 ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
1232 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1233 res, GetLastError());
1236 /* Get Handle for the local Printserver (NT only)*/
1237 hprinter = (HANDLE) MAGIC_DEAD;
1238 SetLastError(MAGIC_DEAD);
1239 res = OpenPrinter(NULL, &hprinter, NULL);
1240 /* The deactivated Spooler is caught here on XPsp2 */
1241 RETURN_ON_DEACTIVATED_SPOOLER(res)
1242 ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1243 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1244 res, GetLastError());
1246 ClosePrinter(hprinter);
1248 defaults.pDatatype=NULL;
1249 defaults.pDevMode=NULL;
1251 defaults.DesiredAccess=0;
1252 hprinter = (HANDLE) MAGIC_DEAD;
1253 SetLastError(MAGIC_DEAD);
1254 res = OpenPrinter(NULL, &hprinter, &defaults);
1255 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1256 if (res) ClosePrinter(hprinter);
1258 defaults.DesiredAccess=-1;
1259 hprinter = (HANDLE) MAGIC_DEAD;
1260 SetLastError(MAGIC_DEAD);
1261 res = OpenPrinter(NULL, &hprinter, &defaults);
1263 ok(!res && GetLastError() == ERROR_ACCESS_DENIED,
1264 "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n",
1265 res, GetLastError());
1267 if (res) ClosePrinter(hprinter);
1271 size = sizeof(buffer) - 3 ;
1277 if (GetComputerNameA(ptr, &size)) {
1279 hprinter = (HANDLE) MAGIC_DEAD;
1280 SetLastError(MAGIC_DEAD);
1281 res = OpenPrinter(buffer, &hprinter, NULL);
1283 ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1284 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1285 res, GetLastError());
1287 if(res) ClosePrinter(hprinter);
1290 /* Invalid Printername */
1291 hprinter = (HANDLE) MAGIC_DEAD;
1292 SetLastError(MAGIC_DEAD);
1293 res = OpenPrinter(illegal_name, &hprinter, NULL);
1294 ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) ||
1295 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1296 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or" \
1297 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1298 if(res) ClosePrinter(hprinter);
1300 hprinter = (HANDLE) MAGIC_DEAD;
1301 SetLastError(MAGIC_DEAD);
1302 res = OpenPrinter(empty, &hprinter, NULL);
1303 /* NT: ERROR_INVALID_PRINTER_NAME, 9x: ERROR_INVALID_PARAMETER */
1305 ((GetLastError() == ERROR_INVALID_PRINTER_NAME) ||
1306 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1307 "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME" \
1308 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1309 if(res) ClosePrinter(hprinter);
1312 /* Get Handle for the default Printer */
1313 if (default_printer)
1315 hprinter = (HANDLE) MAGIC_DEAD;
1316 SetLastError(MAGIC_DEAD);
1317 res = OpenPrinter(default_printer, &hprinter, NULL);
1318 if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
1320 trace("The Service 'Spooler' is required for '%s'\n", default_printer);
1323 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1324 if(res) ClosePrinter(hprinter);
1326 SetLastError(MAGIC_DEAD);
1327 res = OpenPrinter(default_printer, NULL, NULL);
1328 /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1329 ok(res || (GetLastError() == ERROR_INVALID_PARAMETER),
1330 "returned %d with %d (expected '!=0' or '0' with " \
1331 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1333 defaults.pDatatype=NULL;
1334 defaults.pDevMode=NULL;
1335 defaults.DesiredAccess=0;
1337 hprinter = (HANDLE) MAGIC_DEAD;
1338 SetLastError(MAGIC_DEAD);
1339 res = OpenPrinter(default_printer, &hprinter, &defaults);
1340 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1341 "returned %d with %d (expected '!=0' or '0' with " \
1342 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1343 if(res) ClosePrinter(hprinter);
1345 defaults.pDatatype = empty;
1347 hprinter = (HANDLE) MAGIC_DEAD;
1348 SetLastError(MAGIC_DEAD);
1349 res = OpenPrinter(default_printer, &hprinter, &defaults);
1350 /* stop here, when a remote Printserver has no RPC-Service running */
1351 RETURN_ON_DEACTIVATED_SPOOLER(res)
1352 ok(res || ((GetLastError() == ERROR_INVALID_DATATYPE) ||
1353 (GetLastError() == ERROR_ACCESS_DENIED)),
1354 "returned %d with %d (expected '!=0' or '0' with: " \
1355 "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1356 res, GetLastError());
1357 if(res) ClosePrinter(hprinter);
1360 defaults.pDatatype=NULL;
1361 defaults.DesiredAccess=PRINTER_ACCESS_USE;
1363 hprinter = (HANDLE) MAGIC_DEAD;
1364 SetLastError(MAGIC_DEAD);
1365 res = OpenPrinter(default_printer, &hprinter, &defaults);
1366 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1367 "returned %d with %d (expected '!=0' or '0' with " \
1368 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1369 if(res) ClosePrinter(hprinter);
1372 defaults.DesiredAccess=PRINTER_ALL_ACCESS;
1373 hprinter = (HANDLE) MAGIC_DEAD;
1374 SetLastError(MAGIC_DEAD);
1375 res = OpenPrinter(default_printer, &hprinter, &defaults);
1376 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1377 "returned %d with %d (expected '!=0' or '0' with " \
1378 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1379 if(res) ClosePrinter(hprinter);
1385 static void test_SetDefaultPrinter(void)
1388 DWORD size = DEFAULT_PRINTER_SIZE;
1389 CHAR buffer[DEFAULT_PRINTER_SIZE];
1390 CHAR org_value[DEFAULT_PRINTER_SIZE];
1393 if (!pSetDefaultPrinterA) return;
1394 /* only supported on win2k and above */
1396 /* backup the original value */
1397 org_value[0] = '\0';
1398 SetLastError(MAGIC_DEAD);
1399 res = GetProfileStringA("windows", "device", NULL, org_value, size);
1401 /* first part: with the default Printer */
1402 SetLastError(MAGIC_DEAD);
1403 res = pSetDefaultPrinterA("no_printer_with_this_name");
1405 RETURN_ON_DEACTIVATED_SPOOLER(res)
1406 /* spooler is running or we have no spooler here*/
1408 /* Not implemented in wine */
1409 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
1410 trace("SetDefaultPrinterA() not implemented yet.\n");
1414 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1415 "returned %d with %d (expected '0' with " \
1416 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1418 WriteProfileStringA("windows", "device", org_value);
1419 SetLastError(MAGIC_DEAD);
1420 res = pSetDefaultPrinterA("");
1421 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1422 "returned %d with %d (expected '!=0' or '0' with " \
1423 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1425 WriteProfileStringA("windows", "device", org_value);
1426 SetLastError(MAGIC_DEAD);
1427 res = pSetDefaultPrinterA(NULL);
1428 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1429 "returned %d with %d (expected '!=0' or '0' with " \
1430 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1432 WriteProfileStringA("windows", "device", org_value);
1433 SetLastError(MAGIC_DEAD);
1434 res = pSetDefaultPrinterA(default_printer);
1435 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1436 "returned %d with %d (expected '!=0' or '0' with " \
1437 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1440 /* second part: always without a default Printer */
1441 WriteProfileStringA("windows", "device", NULL);
1442 SetLastError(MAGIC_DEAD);
1443 res = pSetDefaultPrinterA("no_printer_with_this_name");
1445 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1446 "returned %d with %d (expected '0' with " \
1447 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1449 WriteProfileStringA("windows", "device", NULL);
1450 SetLastError(MAGIC_DEAD);
1451 res = pSetDefaultPrinterA("");
1452 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
1453 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1454 "returned %d with %d (expected '!=0' or '0' with " \
1455 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1457 WriteProfileStringA("windows", "device", NULL);
1458 SetLastError(MAGIC_DEAD);
1459 res = pSetDefaultPrinterA(NULL);
1460 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
1461 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1462 "returned %d with %d (expected '!=0' or '0' with " \
1463 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1465 WriteProfileStringA("windows", "device", NULL);
1466 SetLastError(MAGIC_DEAD);
1467 res = pSetDefaultPrinterA(default_printer);
1468 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1469 "returned %d with %d (expected '!=0' or '0' with " \
1470 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1472 /* restore the original value */
1473 res = pSetDefaultPrinterA(default_printer); /* the nice way */
1474 WriteProfileStringA("windows", "device", org_value); /* the old way */
1477 SetLastError(MAGIC_DEAD);
1478 res = GetProfileStringA("windows", "device", NULL, buffer, size);
1479 ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value);
1483 static void test_GetPrinterDriver(void)
1489 DWORD needed, filled;
1491 if (!default_printer)
1493 trace("There is no default printer installed, skiping the test\n");
1498 ret = OpenPrinter(default_printer, &hprn, NULL);
1501 trace("There is no printers installed, skiping the test\n");
1504 ok(hprn != 0, "wrong hprn %p\n", hprn);
1506 for (level = -1; level <= 7; level++)
1508 SetLastError(0xdeadbeef);
1510 ret = GetPrinterDriver(hprn, NULL, level, NULL, 0, &needed);
1511 ok(!ret, "level %d: GetPrinterDriver should fail\n", level);
1512 if (level >= 1 && level <= 6)
1514 /* Not all levels are supported on all Windows-Versions */
1515 if(GetLastError() == ERROR_INVALID_LEVEL) continue;
1516 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
1517 ok(needed > 0,"not expected needed buffer size %d\n", needed);
1521 /* ERROR_OUTOFMEMORY found on win9x */
1522 ok( ((GetLastError() == ERROR_INVALID_LEVEL) ||
1523 (GetLastError() == ERROR_OUTOFMEMORY)),
1524 "%d: returned %d with %d (expected '0' with: " \
1525 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
1526 level, ret, GetLastError());
1527 /* needed is modified in win9x. The modified Value depends on the
1528 default Printer. testing for "needed == (DWORD)-1" will fail */
1532 buf = HeapAlloc(GetProcessHeap(), 0, needed);
1534 SetLastError(0xdeadbeef);
1536 ret = GetPrinterDriver(hprn, NULL, level, buf, needed, &filled);
1537 ok(ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
1538 ok(needed == filled, "needed %d != filled %d\n", needed, filled);
1542 DRIVER_INFO_2 *di_2 = (DRIVER_INFO_2 *)buf;
1543 DWORD calculated = sizeof(*di_2);
1545 /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
1546 NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k and above(Usermode): 3 */
1547 ok((di_2->cVersion >= 0 && di_2->cVersion <= 3) ||
1548 (di_2->cVersion == 0x0400), "di_2->cVersion = %d\n", di_2->cVersion);
1549 ok(di_2->pName != NULL, "not expected NULL ptr\n");
1550 ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n");
1551 ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n");
1552 ok(di_2->pDataFile != NULL, "not expected NULL ptr\n");
1553 ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n");
1555 trace("cVersion %d\n", di_2->cVersion);
1556 trace("pName %s\n", di_2->pName);
1557 calculated += strlen(di_2->pName) + 1;
1558 trace("pEnvironment %s\n", di_2->pEnvironment);
1559 calculated += strlen(di_2->pEnvironment) + 1;
1560 trace("pDriverPath %s\n", di_2->pDriverPath);
1561 calculated += strlen(di_2->pDriverPath) + 1;
1562 trace("pDataFile %s\n", di_2->pDataFile);
1563 calculated += strlen(di_2->pDataFile) + 1;
1564 trace("pConfigFile %s\n", di_2->pConfigFile);
1565 calculated += strlen(di_2->pConfigFile) + 1;
1567 /* XP allocates memory for both ANSI and unicode names */
1568 ok(filled >= calculated,"calculated %d != filled %d\n", calculated, filled);
1571 HeapFree(GetProcessHeap(), 0, buf);
1574 SetLastError(0xdeadbeef);
1575 ret = ClosePrinter(hprn);
1576 ok(ret, "ClosePrinter error %d\n", GetLastError());
1579 static void test_DEVMODE(const DEVMODE *dm, LONG dmSize, LPCSTR exp_prn_name)
1581 /* On NT3.51, some fields in DEVMODE are empty/zero
1582 (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
1583 We skip the Tests on this Platform */
1584 if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) {
1585 /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
1586 ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1),
1587 "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName);
1588 ok(dm->dmSize + dm->dmDriverExtra == dmSize,
1589 "%u != %d\n", dm->dmSize + dm->dmDriverExtra, dmSize);
1591 trace("dmFields %08x\n", dm->dmFields);
1594 static void test_DocumentProperties(void)
1600 if (!default_printer)
1602 trace("There is no default printer installed, skiping the test\n");
1607 ret = OpenPrinter(default_printer, &hprn, NULL);
1610 trace("There is no printers installed, skiping the test\n");
1613 ok(hprn != 0, "wrong hprn %p\n", hprn);
1615 dm_size = DocumentProperties(0, hprn, NULL, NULL, NULL, 0);
1616 trace("DEVMODE required size %d\n", dm_size);
1617 ok(dm_size >= sizeof(DEVMODE), "unexpected DocumentProperties ret value %d\n", dm_size);
1619 dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
1621 ret = DocumentProperties(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
1622 ok(ret == IDOK, "DocumentProperties ret value %d != expected IDOK\n", ret);
1624 test_DEVMODE(dm, dm_size, default_printer);
1626 HeapFree(GetProcessHeap(), 0, dm);
1628 SetLastError(0xdeadbeef);
1629 ret = ClosePrinter(hprn);
1630 ok(ret, "ClosePrinter error %d\n", GetLastError());
1633 static void test_EnumPrinters(void)
1635 DWORD neededA, neededW, num;
1638 SetLastError(0xdeadbeef);
1640 ret = EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededA, &num);
1643 /* We have 1 or more printers */
1644 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "gle %d\n", GetLastError());
1645 ok(neededA > 0, "Expected neededA to show the number of needed bytes\n");
1649 /* We don't have any printers defined */
1650 ok(GetLastError() == S_OK, "gle %d\n", GetLastError());
1651 ok(neededA == 0, "Expected neededA to be zero\n");
1653 ok(num == 0, "num %d\n", num);
1655 SetLastError(0xdeadbeef);
1657 ret = EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededW, &num);
1660 /* We have 1 or more printers */
1661 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "gle %d\n", GetLastError());
1662 ok(neededW > 0, "Expected neededW to show the number of needed bytes\n");
1666 /* We don't have any printers defined */
1667 ok(GetLastError() == S_OK, "gle %d\n", GetLastError());
1668 ok(neededW == 0, "Expected neededW to be zero\n");
1670 ok(num == 0, "num %d\n", num);
1672 /* Outlook2003 relies on the buffer size returned by EnumPrintersA being big enough
1673 to hold the buffer returned by EnumPrintersW */
1674 ok(neededA == neededW, "neededA %d neededW %d\n", neededA, neededW);
1679 hwinspool = GetModuleHandleA("winspool.drv");
1680 pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
1681 pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
1683 find_default_printer();
1687 test_ConfigurePort();
1688 test_DeleteMonitor();
1690 test_DocumentProperties();
1691 test_EnumForms(NULL);
1692 if (default_printer) test_EnumForms(default_printer);
1693 test_EnumMonitors();
1695 test_GetDefaultPrinter();
1696 test_GetPrinterDriverDirectory();
1697 test_GetPrintProcessorDirectory();
1699 test_GetPrinterDriver();
1700 test_SetDefaultPrinter();
1702 test_EnumPrinters();