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 empty[] = "";
37 static CHAR env_x86[] = "Windows NT x86";
38 static CHAR env_win9x_case[] = "windowS 4.0";
39 static CHAR illegal_name[] = "illegal,name";
40 static CHAR invalid_env[] = "invalid_env";
41 static CHAR invalid_server[] = "\\invalid_server";
42 static CHAR version_dll[] = "version.dll";
43 static CHAR winetest_monitor[] = "winetest";
45 static HANDLE hwinspool;
46 static FARPROC pGetDefaultPrinterA;
47 static FARPROC pSetDefaultPrinterA;
49 struct monitor_entry {
54 /* report common behavior only once */
55 static DWORD report_deactivated_spooler = 1;
56 #define RETURN_ON_DEACTIVATED_SPOOLER(res) \
57 if((res == 0) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE)) \
59 if(report_deactivated_spooler > 0) { \
60 report_deactivated_spooler--; \
61 trace("The Service 'Spooler' is required for many test\n"); \
67 static LPSTR find_default_printer(VOID)
69 static LPSTR default_printer = NULL;
70 static char buffer[DEFAULT_PRINTER_SIZE];
75 if ((default_printer == NULL) && (pGetDefaultPrinterA))
78 needed = sizeof(buffer);
79 res = pGetDefaultPrinterA(buffer, &needed);
80 if(res) default_printer = buffer;
81 trace("default_printer: '%s'\n", default_printer);
83 if (default_printer == NULL)
87 /* NT 3.x and above */
88 if (RegOpenKeyEx(HKEY_CURRENT_USER,
89 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
90 0, KEY_QUERY_VALUE, &hwindows) == NO_ERROR) {
92 needed = sizeof(buffer);
93 if (RegQueryValueEx(hwindows, "device", NULL,
94 &type, (LPBYTE)buffer, &needed) == NO_ERROR) {
96 ptr = strchr(buffer, ',');
99 default_printer = buffer;
102 RegCloseKey(hwindows);
104 trace("default_printer: '%s'\n", default_printer);
106 if (default_printer == NULL)
109 needed = sizeof(buffer);
110 res = GetProfileStringA("windows", "device", "*", buffer, needed);
112 ptr = strchr(buffer, ',');
115 default_printer = buffer;
118 trace("default_printer: '%s'\n", default_printer);
120 return default_printer;
124 static struct monitor_entry * find_installed_monitor(void)
126 MONITOR_INFO_2A mi2a;
127 static struct monitor_entry * entry = NULL;
131 static struct monitor_entry monitor_table[] = {
132 {env_win9x_case, "localspl.dll"},
133 {env_x86, "localspl.dll"},
134 {env_win9x_case, "localmon.dll"},
135 {env_x86, "localmon.dll"},
136 {env_win9x_case, "tcpmon.dll"},
137 {env_x86, "tcpmon.dll"},
138 {env_win9x_case, "usbmon.dll"},
139 {env_x86, "usbmon.dll"},
140 {env_win9x_case, "mspp32.dll"},
141 {env_x86, "win32spl.dll"},
142 {env_x86, "redmonnt.dll"},
143 {env_x86, "redmon35.dll"},
144 {env_win9x_case, "redmon95.dll"},
145 {env_x86, "pdfcmnnt.dll"},
146 {env_win9x_case, "pdfcmn95.dll"},
149 if (entry) return entry;
151 num_tests = (sizeof(monitor_table)/sizeof(struct monitor_entry));
154 DeleteMonitorA(NULL, env_x86, winetest_monitor);
155 DeleteMonitorA(NULL, env_win9x_case, winetest_monitor);
157 /* find a usable monitor from the table */
158 mi2a.pName = winetest_monitor;
159 while ((entry == NULL) && (i < num_tests)) {
160 entry = &monitor_table[i];
162 mi2a.pEnvironment = entry->env;
163 mi2a.pDLLName = entry->dllname;
165 if (AddMonitorA(NULL, 2, (LPBYTE) &mi2a)) {
167 trace("using '%s', '%s'\n", entry->env, entry->dllname);
168 DeleteMonitorA(NULL, entry->env, winetest_monitor);
178 /* ########################### */
181 static void test_AddMonitor(void)
183 MONITOR_INFO_2A mi2a;
184 struct monitor_entry * entry = NULL;
187 entry = find_installed_monitor();
189 SetLastError(MAGIC_DEAD);
190 res = AddMonitorA(NULL, 1, NULL);
191 ok(!res && (GetLastError() == ERROR_INVALID_LEVEL),
192 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
193 res, GetLastError());
195 SetLastError(MAGIC_DEAD);
196 res = AddMonitorA(NULL, 3, NULL);
197 ok(!res && (GetLastError() == ERROR_INVALID_LEVEL),
198 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
199 res, GetLastError());
202 /* This test crash with win9x on vmware (works with win9x on qemu 0.8.1) */
203 SetLastError(MAGIC_DEAD);
204 res = AddMonitorA(NULL, 2, NULL);
205 /* NT: unchanged, 9x: ERROR_PRIVILEGE_NOT_HELD */
207 ((GetLastError() == MAGIC_DEAD) ||
208 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
209 "returned %d with %d (expected '0' with: MAGIC_DEAD or " \
210 "ERROR_PRIVILEGE_NOT_HELD)\n", res, GetLastError());
213 ZeroMemory(&mi2a, sizeof(MONITOR_INFO_2A));
214 SetLastError(MAGIC_DEAD);
215 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
216 RETURN_ON_DEACTIVATED_SPOOLER(res)
218 if (!res && (GetLastError() == ERROR_ACCESS_DENIED)) {
219 trace("skip tests (ACCESS_DENIED)\n");
223 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_INVALID_ENVIRONMENT */
224 ok(!res && ((GetLastError() == ERROR_INVALID_PARAMETER) ||
225 (GetLastError() == ERROR_INVALID_ENVIRONMENT)),
226 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
227 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
230 trace("No usable Monitor found: Skip tests\n");
235 /* The Test is deactivated, because when mi2a.pName is NULL, the subkey
236 HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM
237 or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì
238 is created on win9x and we do not want to hit this bug here. */
240 mi2a.pEnvironment = entry->env;
241 SetLastError(MAGIC_DEAD);
242 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
243 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
246 mi2a.pEnvironment = entry->env;
248 SetLastError(MAGIC_DEAD);
249 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
250 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
252 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
253 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
254 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
255 "ERROR_PRIVILEGE_NOT_HELD)\n",
256 res, GetLastError());
258 mi2a.pName = winetest_monitor;
259 SetLastError(MAGIC_DEAD);
260 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
261 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
263 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
264 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
265 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
266 "ERROR_PRIVILEGE_NOT_HELD)\n",
267 res, GetLastError());
269 mi2a.pDLLName = empty;
270 SetLastError(MAGIC_DEAD);
271 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
272 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
273 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
274 res, GetLastError());
276 mi2a.pDLLName = does_not_exist_dll;
277 SetLastError(MAGIC_DEAD);
278 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
279 /* NT: ERROR_MOD_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
281 ((GetLastError() == ERROR_MOD_NOT_FOUND) ||
282 (GetLastError() == ERROR_INVALID_PARAMETER)),
283 "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or " \
284 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
286 mi2a.pDLLName = version_dll;
287 SetLastError(MAGIC_DEAD);
288 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
289 /* NT: ERROR_PROC_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
291 ((GetLastError() == ERROR_PROC_NOT_FOUND) ||
292 (GetLastError() == ERROR_INVALID_PARAMETER)),
293 "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or " \
294 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
295 if (res) DeleteMonitorA(NULL, entry->env, winetest_monitor);
297 /* Test AddMonitor with real options */
298 mi2a.pDLLName = entry->dllname;
299 SetLastError(MAGIC_DEAD);
300 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
301 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
303 /* add a monitor twice */
304 SetLastError(MAGIC_DEAD);
305 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
306 /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */
308 ((GetLastError() == ERROR_PRINT_MONITOR_ALREADY_INSTALLED) ||
309 (GetLastError() == ERROR_ALREADY_EXISTS)),
310 "returned %d with %d (expected '0' with: " \
311 "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n",
312 res, GetLastError());
314 DeleteMonitorA(NULL, entry->env, winetest_monitor);
315 SetLastError(MAGIC_DEAD);
316 res = AddMonitorA(empty, 2, (LPBYTE) &mi2a);
317 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
320 DeleteMonitorA(NULL, entry->env, winetest_monitor);
324 /* ########################### */
326 static void test_DeleteMonitor(void)
328 MONITOR_INFO_2A mi2a;
329 struct monitor_entry * entry = NULL;
333 entry = find_installed_monitor();
336 trace("No usable Monitor found: Skip tests\n");
340 mi2a.pName = winetest_monitor;
341 mi2a.pEnvironment = entry->env;
342 mi2a.pDLLName = entry->dllname;
344 /* Testing DeleteMonitor with real options */
345 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
347 SetLastError(MAGIC_DEAD);
348 res = DeleteMonitorA(NULL, entry->env, winetest_monitor);
349 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
351 /* Delete the Monitor twice */
352 SetLastError(MAGIC_DEAD);
353 res = DeleteMonitorA(NULL, entry->env, winetest_monitor);
354 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
356 ((GetLastError() == ERROR_UNKNOWN_PRINT_MONITOR) ||
357 (GetLastError() == ERROR_INVALID_PARAMETER)),
358 "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR" \
359 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
361 /* the environment */
362 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
363 SetLastError(MAGIC_DEAD);
364 res = DeleteMonitorA(NULL, NULL, winetest_monitor);
365 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
367 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
368 SetLastError(MAGIC_DEAD);
369 res = DeleteMonitorA(NULL, empty, winetest_monitor);
370 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
372 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
373 SetLastError(MAGIC_DEAD);
374 res = DeleteMonitorA(NULL, invalid_env, winetest_monitor);
375 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
377 /* the monitor-name */
378 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
379 SetLastError(MAGIC_DEAD);
380 res = DeleteMonitorA(NULL, entry->env, NULL);
381 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
383 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
384 (GetLastError() == ERROR_INVALID_NAME)),
385 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
386 "ERROR_INVALID_NAME)\n", res, GetLastError());
388 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
389 SetLastError(MAGIC_DEAD);
390 res = DeleteMonitorA(NULL, entry->env, empty);
391 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
393 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
394 (GetLastError() == ERROR_INVALID_NAME)),
395 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " \
396 "ERROR_INVALID_NAME)\n", res, GetLastError());
398 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
399 SetLastError(MAGIC_DEAD);
400 res = DeleteMonitorA(empty, entry->env, winetest_monitor);
401 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
404 DeleteMonitorA(NULL, entry->env, winetest_monitor);
409 static void test_EnumForms(LPSTR pName)
420 res = OpenPrinter(pName, &hprinter, NULL);
421 RETURN_ON_DEACTIVATED_SPOOLER(res)
422 if (!res || !hprinter)
424 /* Open the local Prinserver is not supported on win9x */
425 if (pName) trace("Failed to open '%s', skiping the test\n", pName);
429 /* valid levels are 1 and 2 */
430 for(level = 0; level < 4; level++) {
432 pcReturned = 0xdeadbeef;
433 SetLastError(0xdeadbeef);
434 res = EnumFormsA(hprinter, level, NULL, 0, &cbBuf, &pcReturned);
436 /* EnumForms is not implemented in win9x */
437 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
439 /* EnumForms for the Server not implemented on all NT-Versions */
440 if (!res && (GetLastError() == ERROR_INVALID_HANDLE) && !pName) continue;
442 /* Level 2 for EnumForms is not supported on all systems */
443 if (!res && (GetLastError() == ERROR_INVALID_LEVEL) && (level == 2)) continue;
445 /* use only a short test, when we test with an invalid level */
446 if(!level || (level > 2)) {
447 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
448 (res && (pcReturned == 0)),
449 "(%d) returned %d with %d and 0x%08x (expected '0' with " \
450 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
451 level, res, GetLastError(), pcReturned);
455 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
456 "(%d) returned %d with %d (expected '0' with " \
457 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
459 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
460 if (buffer == NULL) continue;
462 SetLastError(0xdeadbeef);
463 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
464 ok(res, "(%d) returned %d with %d (expected '!=0')\n",
465 level, res, GetLastError());
466 /* We can dump the returned Data here */
469 SetLastError(0xdeadbeef);
470 res = EnumFormsA(hprinter, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
471 ok( res, "(%d) returned %d with %d (expected '!=0')\n",
472 level, res, GetLastError());
474 SetLastError(0xdeadbeef);
475 res = EnumFormsA(hprinter, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
476 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
477 "(%d) returned %d with %d (expected '0' with " \
478 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
481 SetLastError(0xdeadbeef);
482 res = EnumFormsA(hprinter, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
483 ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) ,
484 "(%d) returned %d with %d (expected '0' with "\
485 "ERROR_INVALID_USER_BUFFER)\n", level, res, GetLastError());
488 SetLastError(0xdeadbeef);
489 res = EnumFormsA(hprinter, level, buffer, cbBuf, NULL, &pcReturned);
490 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
491 "(%d) returned %d with %d (expected '0' with "\
492 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
494 SetLastError(0xdeadbeef);
495 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, NULL);
496 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
497 "(%d) returned %d with %d (expected '0' with "\
498 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
500 SetLastError(0xdeadbeef);
501 res = EnumFormsA(0, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
502 ok( !res && (GetLastError() == ERROR_INVALID_HANDLE) ,
503 "(%d) returned %d with %d (expected '0' with "\
504 "ERROR_INVALID_HANDLE)\n", level, res, GetLastError());
506 HeapFree(GetProcessHeap(), 0, buffer);
507 } /* for(level ... */
509 ClosePrinter(hprinter);
512 /* ########################### */
514 static void test_EnumMonitors(void)
523 /* valid levels are 1 and 2 */
524 for(level = 0; level < 4; level++) {
526 pcReturned = MAGIC_DEAD;
527 SetLastError(MAGIC_DEAD);
528 res = EnumMonitorsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
530 RETURN_ON_DEACTIVATED_SPOOLER(res)
532 /* not implemented yet in wine */
533 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
536 /* use only a short test, when we test with an invalid level */
537 if(!level || (level > 2)) {
538 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
539 (res && (pcReturned == 0)),
540 "(%d) returned %d with %d and 0x%08x (expected '0' with " \
541 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
542 level, res, GetLastError(), pcReturned);
546 /* Level 2 is not supported on win9x */
547 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
548 trace("Level %d not supported, skipping tests\n", level);
552 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
553 "(%d) returned %d with %d (expected '0' with " \
554 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
557 trace("no valid buffer size returned, skipping tests\n");
561 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
562 if (buffer == NULL) continue;
564 SetLastError(MAGIC_DEAD);
565 pcbNeeded = MAGIC_DEAD;
566 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
567 ok(res, "(%d) returned %d with %d (expected '!=0')\n",
568 level, res, GetLastError());
569 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n",
570 level, pcbNeeded, cbBuf);
571 /* We can validate the returned Data with the Registry here */
574 SetLastError(MAGIC_DEAD);
575 pcReturned = MAGIC_DEAD;
576 pcbNeeded = MAGIC_DEAD;
577 res = EnumMonitorsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
578 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level,
579 res, GetLastError());
580 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
583 SetLastError(MAGIC_DEAD);
584 pcbNeeded = MAGIC_DEAD;
585 res = EnumMonitorsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
586 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
587 "(%d) returned %d with %d (expected '0' with " \
588 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
590 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
594 Do not add the next test:
595 w2k+: RPC_X_NULL_REF_POINTER
596 NT3.5: ERROR_INVALID_USER_BUFFER
597 win9x: crash in winspool.drv
599 res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
602 SetLastError(MAGIC_DEAD);
603 pcbNeeded = MAGIC_DEAD;
604 pcReturned = MAGIC_DEAD;
605 res = EnumMonitorsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
606 ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
607 "(%d) returned %d with %d (expected '!=0' or '0' with "\
608 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
610 pcbNeeded = MAGIC_DEAD;
611 pcReturned = MAGIC_DEAD;
612 SetLastError(MAGIC_DEAD);
613 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
614 ok( res || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)) ,
615 "(%d) returned %d with %d (expected '!=0' or '0' with "\
616 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
618 HeapFree(GetProcessHeap(), 0, buffer);
619 } /* for(level ... */
622 /* ########################### */
624 static void test_EnumPorts(void)
633 /* valid levels are 1 and 2 */
634 for(level = 0; level < 4; level++) {
637 pcReturned = 0xdeadbeef;
638 SetLastError(0xdeadbeef);
639 res = EnumPortsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
640 RETURN_ON_DEACTIVATED_SPOOLER(res)
642 /* use only a short test, when we test with an invalid level */
643 if(!level || (level > 2)) {
644 /* NT: ERROR_INVALID_LEVEL, 9x: success */
645 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
646 (res && (pcReturned == 0)),
647 "(%d) returned %d with %d and 0x%08x (expected '0' with " \
648 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
649 level, res, GetLastError(), pcReturned);
654 /* Level 2 is not supported on NT 3.x */
655 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
656 trace("Level %d not supported, skipping tests\n", level);
660 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
661 "(%d) returned %d with %d (expected '0' with " \
662 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
664 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
665 if (buffer == NULL) continue;
667 pcbNeeded = 0xdeadbeef;
668 SetLastError(0xdeadbeef);
669 res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
670 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
671 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
672 /* ToDo: Compare the returned Data with the Registry / "win.ini",[Ports] here */
674 pcbNeeded = 0xdeadbeef;
675 pcReturned = 0xdeadbeef;
676 SetLastError(0xdeadbeef);
677 res = EnumPortsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
678 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
679 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
681 pcbNeeded = 0xdeadbeef;
682 SetLastError(0xdeadbeef);
683 res = EnumPortsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
684 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
685 "(%d) returned %d with %d (expected '0' with " \
686 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
687 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
690 Do not add this test:
691 res = EnumPortsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
692 w2k+: RPC_X_NULL_REF_POINTER
693 NT3.5: ERROR_INVALID_USER_BUFFER
694 win9x: crash in winspool.drv
697 SetLastError(0xdeadbeef);
698 res = EnumPorts(NULL, level, buffer, cbBuf, NULL, &pcReturned);
699 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
700 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
701 ( res && (GetLastError() == ERROR_SUCCESS) ),
702 "(%d) returned %d with %d (expected '0' with " \
703 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
704 level, res, GetLastError());
707 SetLastError(0xdeadbeef);
708 res = EnumPorts(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
709 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
710 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
711 ( res && (GetLastError() == ERROR_SUCCESS) ),
712 "(%d) returned %d with %d (expected '0' with " \
713 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
714 level, res, GetLastError());
716 HeapFree(GetProcessHeap(), 0, buffer);
720 /* ########################### */
722 static void test_GetDefaultPrinter(void)
725 DWORD exact = DEFAULT_PRINTER_SIZE;
727 char buffer[DEFAULT_PRINTER_SIZE];
729 if (!pGetDefaultPrinterA) return;
730 /* only supported on NT like OSes starting with win2k */
732 SetLastError(ERROR_SUCCESS);
733 retval = pGetDefaultPrinterA(buffer, &exact);
734 if (!retval || !exact || !strlen(buffer) ||
735 (ERROR_SUCCESS != GetLastError())) {
736 if ((ERROR_FILE_NOT_FOUND == GetLastError()) ||
737 (ERROR_INVALID_NAME == GetLastError()))
738 trace("this test requires a default printer to be set\n");
740 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
741 "function returned %s\n"
742 "last error 0x%08x\n"
743 "returned buffer size 0x%08x\n"
744 "returned buffer content %s\n",
745 retval ? "true" : "false", GetLastError(), exact, buffer);
749 SetLastError(ERROR_SUCCESS);
750 retval = pGetDefaultPrinterA(NULL, NULL);
751 ok( !retval, "function result wrong! False expected\n");
752 ok( ERROR_INVALID_PARAMETER == GetLastError(),
753 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
756 SetLastError(ERROR_SUCCESS);
757 retval = pGetDefaultPrinterA(buffer, NULL);
758 ok( !retval, "function result wrong! False expected\n");
759 ok( ERROR_INVALID_PARAMETER == GetLastError(),
760 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
763 SetLastError(ERROR_SUCCESS);
765 retval = pGetDefaultPrinterA(NULL, &size);
766 ok( !retval, "function result wrong! False expected\n");
767 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
768 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
770 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
773 SetLastError(ERROR_SUCCESS);
774 size = DEFAULT_PRINTER_SIZE;
775 retval = pGetDefaultPrinterA(NULL, &size);
776 ok( !retval, "function result wrong! False expected\n");
777 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
778 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
780 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
784 retval = pGetDefaultPrinterA(buffer, &size);
785 ok( !retval, "function result wrong! False expected\n");
786 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
787 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
789 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
793 retval = pGetDefaultPrinterA(buffer, &size);
794 ok( retval, "function result wrong! True expected\n");
795 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
799 static void test_GetPrinterDriverDirectory(void)
801 LPBYTE buffer = NULL;
802 DWORD cbBuf = 0, pcbNeeded = 0;
806 SetLastError(MAGIC_DEAD);
807 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
808 trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
809 res, GetLastError(), cbBuf);
811 RETURN_ON_DEACTIVATED_SPOOLER(res)
812 ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
813 "returned %d with lasterror=%d (expected '0' with " \
814 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
817 trace("no valid buffer size returned, skipping tests\n");
821 buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
822 if (buffer == NULL) return ;
824 res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
825 ok( res, "expected result != 0, got %d\n", res);
826 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
829 res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
830 ok( res, "expected result != 0, got %d\n", res);
831 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
834 SetLastError(MAGIC_DEAD);
835 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
836 ok( !res , "expected result == 0, got %d\n", res);
837 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
840 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
841 "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
845 Do not add the next test:
846 XPsp2: crash in this app, when the spooler is not running
847 NT3.5: ERROR_INVALID_USER_BUFFER
848 win9x: ERROR_INVALID_PARAMETER
850 pcbNeeded = MAGIC_DEAD;
851 SetLastError(MAGIC_DEAD);
852 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
855 SetLastError(MAGIC_DEAD);
856 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
857 ok( (!res && RPC_X_NULL_REF_POINTER == GetLastError()) || res,
858 "expected either result == 0 and "
859 "last error == RPC_X_NULL_REF_POINTER or result != 0 "
860 "got result %d and last error == %d\n", res, GetLastError());
862 SetLastError(MAGIC_DEAD);
863 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
864 ok(res || (GetLastError() == RPC_X_NULL_REF_POINTER),
865 "returned %d with %d (expected '!=0' or '0' with " \
866 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
869 /* with a valid buffer, but level is too large */
871 SetLastError(MAGIC_DEAD);
872 res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
874 /* Level not checked in win9x and wine:*/
875 if((res != FALSE) && buffer[0])
877 trace("Level '2' not checked '%s'\n", buffer);
881 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
882 "returned %d with lasterror=%d (expected '0' with " \
883 "ERROR_INVALID_LEVEL)\n", res, GetLastError());
886 /* printing environments are case insensitive */
887 /* "Windows 4.0" is valid for win9x and NT */
889 SetLastError(MAGIC_DEAD);
890 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1,
891 buffer, cbBuf*2, &pcbNeeded);
893 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
895 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
896 if (buffer == NULL) return ;
898 SetLastError(MAGIC_DEAD);
899 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1,
900 buffer, cbBuf*2, &pcbNeeded);
903 ok(res && buffer[0], "returned %d with " \
904 "lasterror=%d and len=%d (expected '1' with 'len > 0')\n",
905 res, GetLastError(), lstrlenA((char *)buffer));
908 SetLastError(MAGIC_DEAD);
909 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1,
910 buffer, cbBuf*2, &pcbNeeded);
912 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
914 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
915 if (buffer == NULL) return ;
918 SetLastError(MAGIC_DEAD);
919 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1,
920 buffer, cbBuf*2, &pcbNeeded);
923 /* "Windows NT x86" is invalid for win9x */
924 ok( (res && buffer[0]) ||
925 (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)),
926 "returned %d with lasterror=%d and len=%d (expected '!= 0' with " \
927 "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
928 res, GetLastError(), lstrlenA((char *)buffer));
930 /* A Setup-Programm (PDFCreator_0.8.0) use empty strings */
931 SetLastError(MAGIC_DEAD);
932 res = GetPrinterDriverDirectoryA(empty, empty, 1, buffer, cbBuf*2, &pcbNeeded);
933 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
935 SetLastError(MAGIC_DEAD);
936 res = GetPrinterDriverDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
937 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
939 SetLastError(MAGIC_DEAD);
940 res = GetPrinterDriverDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
941 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
943 HeapFree( GetProcessHeap(), 0, buffer);
948 static void test_GetPrintProcessorDirectory(void)
950 LPBYTE buffer = NULL;
956 SetLastError(0xdeadbeef);
957 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf);
958 /* The deactivated Spooler is catched here on NT3.51 */
959 RETURN_ON_DEACTIVATED_SPOOLER(res)
960 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
961 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
962 res, GetLastError());
964 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2);
965 if(buffer == NULL) return;
968 SetLastError(0xdeadbeef);
969 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
970 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
972 SetLastError(0xdeadbeef);
974 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
975 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
977 /* Buffer to small */
979 SetLastError(0xdeadbeef);
980 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
981 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
982 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
983 res, GetLastError());
986 /* XPsp2: the programm will crash here, when the spooler is not running */
987 /* GetPrinterDriverDirectory has the same bug */
989 SetLastError(0xdeadbeef);
990 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
994 SetLastError(0xdeadbeef);
995 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
996 /* NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
997 ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER),
998 "returned %d with %d (expected '!= 0' or '0' with " \
999 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError());
1003 SetLastError(0xdeadbeef);
1004 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
1005 /* NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
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 invalid */
1013 SetLastError(0xdeadbeef);
1014 res = GetPrintProcessorDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
1015 if (res && buffer[0])
1017 /* Level is ignored in win9x*/
1018 trace("invalid level (2) was ignored\n");
1022 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1023 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1024 res, GetLastError());
1027 /* Empty environment is the same as the default environment */
1029 SetLastError(0xdeadbeef);
1030 res = GetPrintProcessorDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1031 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1033 /* "Windows 4.0" is valid for win9x and NT */
1035 SetLastError(0xdeadbeef);
1036 res = GetPrintProcessorDirectoryA(NULL, env_win9x_case, 1, buffer, cbBuf*2, &pcbNeeded);
1037 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1040 /* "Windows NT x86" is invalid for win9x */
1042 SetLastError(0xdeadbeef);
1043 res = GetPrintProcessorDirectoryA(NULL, env_x86, 1, buffer, cbBuf*2, &pcbNeeded);
1044 ok( res || (GetLastError() == ERROR_INVALID_ENVIRONMENT),
1045 "returned %d with %d (expected '!= 0' or '0' with " \
1046 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
1048 /* invalid on all Systems */
1050 SetLastError(0xdeadbeef);
1051 res = GetPrintProcessorDirectoryA(NULL, invalid_env, 1, buffer, cbBuf*2, &pcbNeeded);
1052 ok( !res && (GetLastError() == ERROR_INVALID_ENVIRONMENT),
1053 "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
1054 res, GetLastError());
1056 /* Empty servername is the same as the local computer */
1058 SetLastError(0xdeadbeef);
1059 res = GetPrintProcessorDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1060 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1062 /* invalid on all Systems */
1064 SetLastError(0xdeadbeef);
1065 res = GetPrintProcessorDirectoryA(invalid_server, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1066 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
1067 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1068 res, GetLastError());
1070 HeapFree(GetProcessHeap(), 0, buffer);
1075 static void test_OpenPrinter(void)
1077 PRINTER_DEFAULTSA defaults;
1079 LPSTR default_printer;
1082 CHAR buffer[DEFAULT_PRINTER_SIZE];
1086 SetLastError(MAGIC_DEAD);
1087 res = OpenPrinter(NULL, NULL, NULL);
1088 /* The deactivated Spooler is catched here on NT3.51 */
1089 RETURN_ON_DEACTIVATED_SPOOLER(res)
1090 ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
1091 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1092 res, GetLastError());
1095 /* Get Handle for the local Printserver (NT only)*/
1096 hprinter = (HANDLE) MAGIC_DEAD;
1097 SetLastError(MAGIC_DEAD);
1098 res = OpenPrinter(NULL, &hprinter, NULL);
1099 /* The deactivated Spooler is catched here on XPsp2 */
1100 RETURN_ON_DEACTIVATED_SPOOLER(res)
1101 ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1102 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1103 res, GetLastError());
1105 ClosePrinter(hprinter);
1107 defaults.pDatatype=NULL;
1108 defaults.pDevMode=NULL;
1110 defaults.DesiredAccess=0;
1111 hprinter = (HANDLE) MAGIC_DEAD;
1112 SetLastError(MAGIC_DEAD);
1113 res = OpenPrinter(NULL, &hprinter, &defaults);
1114 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1115 if (res) ClosePrinter(hprinter);
1117 defaults.DesiredAccess=-1;
1118 hprinter = (HANDLE) MAGIC_DEAD;
1119 SetLastError(MAGIC_DEAD);
1120 res = OpenPrinter(NULL, &hprinter, &defaults);
1122 ok(!res && GetLastError() == ERROR_ACCESS_DENIED,
1123 "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n",
1124 res, GetLastError());
1126 if (res) ClosePrinter(hprinter);
1130 size = sizeof(buffer) - 3 ;
1136 if (GetComputerNameA(ptr, &size)) {
1138 hprinter = (HANDLE) MAGIC_DEAD;
1139 SetLastError(MAGIC_DEAD);
1140 res = OpenPrinter(buffer, &hprinter, NULL);
1142 ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
1143 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1144 res, GetLastError());
1146 if(res) ClosePrinter(hprinter);
1149 /* Invalid Printername */
1150 hprinter = (HANDLE) MAGIC_DEAD;
1151 SetLastError(MAGIC_DEAD);
1152 res = OpenPrinter(illegal_name, &hprinter, NULL);
1153 ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) ||
1154 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1155 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or" \
1156 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1157 if(res) ClosePrinter(hprinter);
1159 hprinter = (HANDLE) MAGIC_DEAD;
1160 SetLastError(MAGIC_DEAD);
1161 res = OpenPrinter(empty, &hprinter, NULL);
1162 /* NT: ERROR_INVALID_PRINTER_NAME, 9x: ERROR_INVALID_PARAMETER */
1164 ((GetLastError() == ERROR_INVALID_PRINTER_NAME) ||
1165 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1166 "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME" \
1167 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1168 if(res) ClosePrinter(hprinter);
1171 /* Get Handle for the default Printer */
1172 if ((default_printer = find_default_printer()))
1174 hprinter = (HANDLE) MAGIC_DEAD;
1175 SetLastError(MAGIC_DEAD);
1176 res = OpenPrinter(default_printer, &hprinter, NULL);
1177 if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
1179 trace("The Service 'Spooler' is required for '%s'\n", default_printer);
1182 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1183 if(res) ClosePrinter(hprinter);
1185 SetLastError(MAGIC_DEAD);
1186 res = OpenPrinter(default_printer, NULL, NULL);
1187 /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1188 ok(res || (GetLastError() == ERROR_INVALID_PARAMETER),
1189 "returned %d with %d (expected '!=0' or '0' with " \
1190 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1192 defaults.pDatatype=NULL;
1193 defaults.pDevMode=NULL;
1194 defaults.DesiredAccess=0;
1196 hprinter = (HANDLE) MAGIC_DEAD;
1197 SetLastError(MAGIC_DEAD);
1198 res = OpenPrinter(default_printer, &hprinter, &defaults);
1199 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1200 "returned %d with %d (expected '!=0' or '0' with " \
1201 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1202 if(res) ClosePrinter(hprinter);
1204 defaults.pDatatype = empty;
1206 hprinter = (HANDLE) MAGIC_DEAD;
1207 SetLastError(MAGIC_DEAD);
1208 res = OpenPrinter(default_printer, &hprinter, &defaults);
1209 /* stop here, when a remote Printserver has no RPC-Service running */
1210 RETURN_ON_DEACTIVATED_SPOOLER(res)
1211 ok(res || ((GetLastError() == ERROR_INVALID_DATATYPE) ||
1212 (GetLastError() == ERROR_ACCESS_DENIED)),
1213 "returned %d with %d (expected '!=0' or '0' with: " \
1214 "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1215 res, GetLastError());
1216 if(res) ClosePrinter(hprinter);
1219 defaults.pDatatype=NULL;
1220 defaults.DesiredAccess=PRINTER_ACCESS_USE;
1222 hprinter = (HANDLE) MAGIC_DEAD;
1223 SetLastError(MAGIC_DEAD);
1224 res = OpenPrinter(default_printer, &hprinter, &defaults);
1225 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1226 "returned %d with %d (expected '!=0' or '0' with " \
1227 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1228 if(res) ClosePrinter(hprinter);
1231 defaults.DesiredAccess=PRINTER_ALL_ACCESS;
1232 hprinter = (HANDLE) MAGIC_DEAD;
1233 SetLastError(MAGIC_DEAD);
1234 res = OpenPrinter(default_printer, &hprinter, &defaults);
1235 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1236 "returned %d with %d (expected '!=0' or '0' with " \
1237 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1238 if(res) ClosePrinter(hprinter);
1244 static void test_SetDefaultPrinter(void)
1247 LPSTR default_printer;
1248 DWORD size = DEFAULT_PRINTER_SIZE;
1249 CHAR buffer[DEFAULT_PRINTER_SIZE];
1250 CHAR org_value[DEFAULT_PRINTER_SIZE];
1253 if (!pSetDefaultPrinterA) return;
1254 /* only supported on win2k and above */
1256 default_printer = find_default_printer();
1258 /* backup the original value */
1259 org_value[0] = '\0';
1260 SetLastError(MAGIC_DEAD);
1261 res = GetProfileStringA("windows", "device", NULL, org_value, size);
1263 /* first part: with the default Printer */
1264 SetLastError(MAGIC_DEAD);
1265 res = pSetDefaultPrinterA("no_printer_with_this_name");
1267 RETURN_ON_DEACTIVATED_SPOOLER(res)
1268 /* spooler is running or we have no spooler here*/
1270 /* Not implemented in wine */
1271 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
1272 trace("SetDefaultPrinterA() not implemented yet.\n");
1276 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1277 "returned %d with %d (expected '0' with " \
1278 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1280 WriteProfileStringA("windows", "device", org_value);
1281 SetLastError(MAGIC_DEAD);
1282 res = pSetDefaultPrinterA("");
1283 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1284 "returned %d with %d (expected '!=0' or '0' with " \
1285 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1287 WriteProfileStringA("windows", "device", org_value);
1288 SetLastError(MAGIC_DEAD);
1289 res = pSetDefaultPrinterA(NULL);
1290 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1291 "returned %d with %d (expected '!=0' or '0' with " \
1292 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1294 WriteProfileStringA("windows", "device", org_value);
1295 SetLastError(MAGIC_DEAD);
1296 res = pSetDefaultPrinterA(default_printer);
1297 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1298 "returned %d with %d (expected '!=0' or '0' with " \
1299 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1302 /* second part: always without a default Printer */
1303 WriteProfileStringA("windows", "device", NULL);
1304 SetLastError(MAGIC_DEAD);
1305 res = pSetDefaultPrinterA("no_printer_with_this_name");
1307 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1308 "returned %d with %d (expected '0' with " \
1309 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1311 WriteProfileStringA("windows", "device", NULL);
1312 SetLastError(MAGIC_DEAD);
1313 res = pSetDefaultPrinterA("");
1314 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
1315 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1316 "returned %d with %d (expected '!=0' or '0' with " \
1317 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1319 WriteProfileStringA("windows", "device", NULL);
1320 SetLastError(MAGIC_DEAD);
1321 res = pSetDefaultPrinterA(NULL);
1322 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
1323 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1324 "returned %d with %d (expected '!=0' or '0' with " \
1325 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1327 WriteProfileStringA("windows", "device", NULL);
1328 SetLastError(MAGIC_DEAD);
1329 res = pSetDefaultPrinterA(default_printer);
1330 ok(res || (!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME)),
1331 "returned %d with %d (expected '!=0' or '0' with " \
1332 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1334 /* restore the original value */
1335 res = pSetDefaultPrinterA(default_printer); /* the nice way */
1336 WriteProfileStringA("windows", "device", org_value); /* the old way */
1339 SetLastError(MAGIC_DEAD);
1340 res = GetProfileStringA("windows", "device", NULL, buffer, size);
1341 ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value);
1345 static void test_GetPrinterDriver(void)
1347 LPSTR default_printer;
1352 DWORD needed, filled;
1354 default_printer = find_default_printer();
1355 if (!default_printer)
1357 trace("There is no default printer installed, skiping the test\n");
1362 ret = OpenPrinter(default_printer, &hprn, NULL);
1365 trace("There is no printers installed, skiping the test\n");
1368 ok(hprn != 0, "wrong hprn %p\n", hprn);
1370 for (level = -1; level <= 7; level++)
1372 SetLastError(0xdeadbeef);
1374 ret = GetPrinterDriver(hprn, NULL, level, NULL, 0, &needed);
1375 ok(!ret, "level %d: GetPrinterDriver should fail\n", level);
1376 if (level >= 1 && level <= 6)
1378 /* Not all levels are supported on all Windows-Versions */
1379 if(GetLastError() == ERROR_INVALID_LEVEL) continue;
1380 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
1381 ok(needed > 0,"not expected needed buffer size %d\n", needed);
1385 /* ERROR_OUTOFMEMORY found on win9x */
1386 ok( ((GetLastError() == ERROR_INVALID_LEVEL) ||
1387 (GetLastError() == ERROR_OUTOFMEMORY)),
1388 "%d: returned %d with %d (expected '0' with: " \
1389 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
1390 level, ret, GetLastError());
1391 /* needed is modified in win9x. The modified Value depends on the
1392 default Printer. testing for "needed == (DWORD)-1" will fail */
1396 buf = HeapAlloc(GetProcessHeap(), 0, needed);
1398 SetLastError(0xdeadbeef);
1400 ret = GetPrinterDriver(hprn, NULL, level, buf, needed, &filled);
1401 ok(ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
1402 ok(needed == filled, "needed %d != filled %d\n", needed, filled);
1406 DRIVER_INFO_2 *di_2 = (DRIVER_INFO_2 *)buf;
1407 DWORD calculated = sizeof(*di_2);
1409 /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
1410 NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k and above(Usermode): 3 */
1411 ok((di_2->cVersion >= 0 && di_2->cVersion <= 3) ||
1412 (di_2->cVersion == 0x0400), "di_2->cVersion = %d\n", di_2->cVersion);
1413 ok(di_2->pName != NULL, "not expected NULL ptr\n");
1414 ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n");
1415 ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n");
1416 ok(di_2->pDataFile != NULL, "not expected NULL ptr\n");
1417 ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n");
1419 trace("cVersion %d\n", di_2->cVersion);
1420 trace("pName %s\n", di_2->pName);
1421 calculated += strlen(di_2->pName) + 1;
1422 trace("pEnvironment %s\n", di_2->pEnvironment);
1423 calculated += strlen(di_2->pEnvironment) + 1;
1424 trace("pDriverPath %s\n", di_2->pDriverPath);
1425 calculated += strlen(di_2->pDriverPath) + 1;
1426 trace("pDataFile %s\n", di_2->pDataFile);
1427 calculated += strlen(di_2->pDataFile) + 1;
1428 trace("pConfigFile %s\n", di_2->pConfigFile);
1429 calculated += strlen(di_2->pConfigFile) + 1;
1431 /* XP allocates memory for both ANSI and unicode names */
1432 ok(filled >= calculated,"calculated %d != filled %d\n", calculated, filled);
1435 HeapFree(GetProcessHeap(), 0, buf);
1438 SetLastError(0xdeadbeef);
1439 ret = ClosePrinter(hprn);
1440 ok(ret, "ClosePrinter error %d\n", GetLastError());
1443 static void test_DEVMODE(const DEVMODE *dm, LONG dmSize, LPCSTR exp_prn_name)
1445 /* On NT3.51, some fields in DEVMODE are empty/zero
1446 (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
1447 We skip the Tests on this Platform */
1448 if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) {
1449 /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
1450 ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1),
1451 "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName);
1452 ok(dm->dmSize + dm->dmDriverExtra == dmSize,
1453 "%u != %d\n", dm->dmSize + dm->dmDriverExtra, dmSize);
1455 trace("dmFields %08x\n", dm->dmFields);
1458 static void test_DocumentProperties(void)
1460 LPSTR default_printer;
1465 default_printer = find_default_printer();
1466 if (!default_printer)
1468 trace("There is no default printer installed, skiping the test\n");
1473 ret = OpenPrinter(default_printer, &hprn, NULL);
1476 trace("There is no printers installed, skiping the test\n");
1479 ok(hprn != 0, "wrong hprn %p\n", hprn);
1481 dm_size = DocumentProperties(0, hprn, NULL, NULL, NULL, 0);
1482 trace("DEVMODE required size %d\n", dm_size);
1483 ok(dm_size >= sizeof(DEVMODE), "unexpected DocumentProperties ret value %d\n", dm_size);
1485 dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
1487 ret = DocumentProperties(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
1488 ok(ret == IDOK, "DocumentProperties ret value %d != expected IDOK\n", ret);
1490 test_DEVMODE(dm, dm_size, default_printer);
1492 HeapFree(GetProcessHeap(), 0, dm);
1494 SetLastError(0xdeadbeef);
1495 ret = ClosePrinter(hprn);
1496 ok(ret, "ClosePrinter error %d\n", GetLastError());
1501 LPSTR default_printer;
1503 hwinspool = GetModuleHandleA("winspool.drv");
1504 pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
1505 pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
1507 default_printer = find_default_printer();
1510 test_DeleteMonitor();
1511 test_DocumentProperties();
1512 test_EnumForms(NULL);
1513 if (default_printer) test_EnumForms(default_printer);
1514 test_EnumMonitors();
1516 test_GetDefaultPrinter();
1517 test_GetPrinterDriverDirectory();
1518 test_GetPrintProcessorDirectory();
1520 test_GetPrinterDriver();
1521 test_SetDefaultPrinter();