winspool/tests: Add tests for GetFormA().
[wine.git] / dlls / winspool.drv / tests / info.c
bloba9fbe7274534ad0fdc8340db179278b9aa399d1a
1 /*
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
21 #include <stdarg.h>
22 #include <assert.h>
24 #define NONAMELESSSTRUCT
25 #define NONAMELESSUNION
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "wingdi.h"
31 #include "winnls.h"
32 #include "winuser.h"
33 #include "winreg.h"
34 #include "winspool.h"
35 #include "commdlg.h"
36 #include "wine/test.h"
38 #define MAGIC_DEAD 0xdeadbeef
39 #define DEFAULT_PRINTER_SIZE 1000
41 static CHAR defaultspooldirectory[] = "DefaultSpoolDirectory";
42 static CHAR does_not_exist_dll[]= "does_not_exist.dll";
43 static CHAR does_not_exist[] = "does_not_exist";
44 static CHAR empty[] = "";
45 static CHAR env_x64[] = "Windows x64";
46 static CHAR env_x86[] = "Windows NT x86";
47 static CHAR env_win9x_case[] = "windowS 4.0";
48 static CHAR illegal_name[] = "illegal,name";
49 static CHAR invalid_env[] = "invalid_env";
50 static CHAR LocalPortA[] = "Local Port";
51 static CHAR portname_com1[] = "COM1:";
52 static CHAR portname_file[] = "FILE:";
53 static CHAR portname_lpt1[] = "LPT1:";
54 static CHAR server_does_not_exist[] = "\\\\does_not_exist";
55 static CHAR version_dll[] = "version.dll";
56 static CHAR winetest[] = "winetest";
57 static CHAR xcv_localport[] = ",XcvMonitor Local Port";
59 static HANDLE hwinspool;
60 static BOOL (WINAPI * pAddPortExA)(LPSTR, DWORD, LPBYTE, LPSTR);
61 static BOOL (WINAPI * pEnumPrinterDriversW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
62 static BOOL (WINAPI * pGetDefaultPrinterA)(LPSTR, LPDWORD);
63 static DWORD (WINAPI * pGetPrinterDataExA)(HANDLE, LPCSTR, LPCSTR, LPDWORD, LPBYTE, DWORD, LPDWORD);
64 static BOOL (WINAPI * pGetPrinterDriverW)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
65 static BOOL (WINAPI * pGetPrinterW)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
66 static BOOL (WINAPI * pSetDefaultPrinterA)(LPCSTR);
67 static DWORD (WINAPI * pXcvDataW)(HANDLE, LPCWSTR, PBYTE, DWORD, PBYTE, DWORD, PDWORD, PDWORD);
69 /* ################################ */
71 struct monitor_entry {
72 LPSTR env;
73 CHAR dllname[32];
76 static LPSTR default_printer = NULL;
77 static LPSTR local_server = NULL;
78 static LPSTR tempdirA = NULL;
79 static LPSTR tempfileA = NULL;
80 static LPWSTR tempdirW = NULL;
81 static LPWSTR tempfileW = NULL;
83 static BOOL is_spooler_deactivated(DWORD res, DWORD lasterror)
85 if (!res && lasterror == RPC_S_SERVER_UNAVAILABLE)
87 static int deactivated_spooler_reported = 0;
88 if (!deactivated_spooler_reported)
90 deactivated_spooler_reported = 1;
91 skip("The service 'Spooler' is required for many tests\n");
93 return TRUE;
95 return FALSE;
98 static BOOL is_access_denied(DWORD res, DWORD lasterror)
100 if (!res && lasterror == ERROR_ACCESS_DENIED)
102 static int access_denied_reported = 0;
103 if (!access_denied_reported)
105 access_denied_reported = 1;
106 skip("More access rights are required for many tests\n");
108 return TRUE;
110 return FALSE;
113 static void find_default_printer(VOID)
115 static char buffer[DEFAULT_PRINTER_SIZE];
116 DWORD needed;
117 DWORD res;
118 LPSTR ptr;
120 if ((default_printer == NULL) && (pGetDefaultPrinterA))
122 /* w2k and above */
123 needed = sizeof(buffer);
124 res = pGetDefaultPrinterA(buffer, &needed);
125 if(res) default_printer = buffer;
126 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
128 if (default_printer == NULL)
130 HKEY hwindows;
131 DWORD type;
132 /* NT 3.x and above */
133 if (RegOpenKeyExA(HKEY_CURRENT_USER,
134 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
135 0, KEY_QUERY_VALUE, &hwindows) == NO_ERROR) {
137 needed = sizeof(buffer);
138 if (RegQueryValueExA(hwindows, "device", NULL, &type, (LPBYTE)buffer, &needed) == NO_ERROR) {
139 ptr = strchr(buffer, ',');
140 if (ptr) {
141 ptr[0] = '\0';
142 default_printer = buffer;
145 RegCloseKey(hwindows);
147 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
149 if (default_printer == NULL)
151 /* win9x */
152 needed = sizeof(buffer);
153 res = GetProfileStringA("windows", "device", "*", buffer, needed);
154 if(res) {
155 ptr = strchr(buffer, ',');
156 if (ptr) {
157 ptr[0] = '\0';
158 default_printer = buffer;
161 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
166 static struct monitor_entry * find_installed_monitor(void)
168 MONITOR_INFO_2A mi2a;
169 static struct monitor_entry * entry = NULL;
170 DWORD num_tests;
171 DWORD i = 0;
173 static struct monitor_entry monitor_table[] = {
174 {env_win9x_case, "localspl.dll"},
175 {env_x86, "localspl.dll"},
176 {env_x64, "localspl.dll"},
177 {env_win9x_case, "localmon.dll"},
178 {env_x86, "localmon.dll"},
179 {env_win9x_case, "tcpmon.dll"},
180 {env_x86, "tcpmon.dll"},
181 {env_win9x_case, "usbmon.dll"},
182 {env_x86, "usbmon.dll"},
183 {env_win9x_case, "mspp32.dll"},
184 {env_x86, "win32spl.dll"},
185 {env_x86, "redmonnt.dll"},
186 {env_x86, "redmon35.dll"},
187 {env_win9x_case, "redmon95.dll"},
188 {env_x86, "pdfcmnnt.dll"},
189 {env_win9x_case, "pdfcmn95.dll"},
192 if (entry) return entry;
194 num_tests = ARRAY_SIZE(monitor_table);
196 /* cleanup */
197 DeleteMonitorA(NULL, env_x64, winetest);
198 DeleteMonitorA(NULL, env_x86, winetest);
199 DeleteMonitorA(NULL, env_win9x_case, winetest);
201 /* find a usable monitor from the table */
202 mi2a.pName = winetest;
203 while ((entry == NULL) && (i < num_tests)) {
204 entry = &monitor_table[i];
205 i++;
206 mi2a.pEnvironment = entry->env;
207 mi2a.pDLLName = entry->dllname;
209 if (AddMonitorA(NULL, 2, (LPBYTE) &mi2a)) {
210 /* we got one */
211 trace("using '%s', '%s'\n", entry->env, entry->dllname);
212 DeleteMonitorA(NULL, entry->env, winetest);
214 else
216 entry = NULL;
219 return entry;
223 /* ########################### */
225 static void find_local_server(VOID)
227 static char buffer[MAX_PATH];
228 DWORD res;
229 DWORD size;
231 size = sizeof(buffer) - 3 ;
232 buffer[0] = '\\';
233 buffer[1] = '\\';
234 buffer[2] = '\0';
236 SetLastError(0xdeadbeef);
237 res = GetComputerNameA(&buffer[2], &size);
238 trace("returned %d with %d and %d: '%s'\n", res, GetLastError(), size, buffer);
240 ok( res != 0, "returned %d with %d and %d: '%s' (expected '!= 0')\n",
241 res, GetLastError(), size, buffer);
243 if (res) local_server = buffer;
246 /* ########################### */
248 static void find_tempfile(VOID)
250 static CHAR buffer_dirA[MAX_PATH];
251 static CHAR buffer_fileA[MAX_PATH];
252 static WCHAR buffer_dirW[MAX_PATH];
253 static WCHAR buffer_fileW[MAX_PATH];
254 DWORD res;
255 int resint;
257 memset(buffer_dirA, 0, MAX_PATH - 1);
258 buffer_dirA[MAX_PATH - 1] = '\0';
259 SetLastError(0xdeadbeef);
260 res = GetTempPathA(MAX_PATH, buffer_dirA);
261 ok(res, "returned %u with %u and '%s' (expected '!= 0')\n", res, GetLastError(), buffer_dirA);
262 if (res == 0) return;
264 memset(buffer_fileA, 0, MAX_PATH - 1);
265 buffer_fileA[MAX_PATH - 1] = '\0';
266 SetLastError(0xdeadbeef);
267 res = GetTempFileNameA(buffer_dirA, winetest, 0, buffer_fileA);
268 ok(res, "returned %u with %u and '%s' (expected '!= 0')\n", res, GetLastError(), buffer_fileA);
269 if (res == 0) return;
271 SetLastError(0xdeadbeef);
272 resint = MultiByteToWideChar(CP_ACP, 0, buffer_dirA, -1, buffer_dirW, MAX_PATH);
273 ok(res, "returned %u with %u (expected '!= 0')\n", resint, GetLastError());
274 if (resint == 0) return;
276 SetLastError(0xdeadbeef);
277 resint = MultiByteToWideChar(CP_ACP, 0, buffer_fileA, -1, buffer_fileW, MAX_PATH);
278 ok(res, "returned %u with %u (expected '!= 0')\n", resint, GetLastError());
279 if (resint == 0) return;
281 tempdirA = buffer_dirA;
282 tempfileA = buffer_fileA;
283 tempdirW = buffer_dirW;
284 tempfileW = buffer_fileW;
285 trace("tempfile: '%s'\n", tempfileA);
288 /* ########################### */
290 static void test_AddMonitor(void)
292 MONITOR_INFO_2A mi2a;
293 struct monitor_entry * entry = NULL;
294 DWORD res;
296 entry = find_installed_monitor();
298 SetLastError(MAGIC_DEAD);
299 res = AddMonitorA(NULL, 1, NULL);
300 ok(!res && (GetLastError() == ERROR_INVALID_LEVEL),
301 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
302 res, GetLastError());
304 SetLastError(MAGIC_DEAD);
305 res = AddMonitorA(NULL, 3, NULL);
306 ok(!res && (GetLastError() == ERROR_INVALID_LEVEL),
307 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
308 res, GetLastError());
310 /* This test crashes win9x on vmware (works with win9x on qemu 0.8.1) */
311 SetLastError(MAGIC_DEAD);
312 res = AddMonitorA(NULL, 2, NULL);
313 /* NT: unchanged, 9x: ERROR_PRIVILEGE_NOT_HELD */
314 ok(!res &&
315 ((GetLastError() == MAGIC_DEAD) ||
316 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
317 "returned %d with %d (expected '0' with: MAGIC_DEAD or "
318 "ERROR_PRIVILEGE_NOT_HELD)\n", res, GetLastError());
320 ZeroMemory(&mi2a, sizeof(MONITOR_INFO_2A));
321 SetLastError(MAGIC_DEAD);
322 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
323 if (is_spooler_deactivated(res, GetLastError())) return;
324 if (is_access_denied(res, GetLastError())) return;
326 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_INVALID_ENVIRONMENT */
327 ok(!res && ((GetLastError() == ERROR_INVALID_PARAMETER) ||
328 (GetLastError() == ERROR_INVALID_ENVIRONMENT)),
329 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
330 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
332 if (!entry) {
333 skip("No usable Monitor found\n");
334 return;
337 if (0)
339 /* The test is deactivated, because when mi2a.pName is NULL, the subkey
340 HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM
341 or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì
342 is created on win9x and we do not want to hit this bug here. */
344 mi2a.pEnvironment = entry->env;
345 SetLastError(MAGIC_DEAD);
346 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
347 ok(res, "AddMonitor error %d\n", GetLastError());
348 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
351 mi2a.pEnvironment = entry->env;
352 mi2a.pName = empty;
353 SetLastError(MAGIC_DEAD);
354 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
355 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
356 ok( !res &&
357 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
358 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
359 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
360 "ERROR_PRIVILEGE_NOT_HELD)\n",
361 res, GetLastError());
363 mi2a.pName = winetest;
364 SetLastError(MAGIC_DEAD);
365 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
366 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
367 ok( !res &&
368 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
369 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)),
370 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
371 "ERROR_PRIVILEGE_NOT_HELD)\n",
372 res, GetLastError());
374 mi2a.pDLLName = empty;
375 SetLastError(MAGIC_DEAD);
376 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
377 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
378 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
379 res, GetLastError());
381 mi2a.pDLLName = does_not_exist_dll;
382 SetLastError(MAGIC_DEAD);
383 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
384 /* NT: ERROR_MOD_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
385 ok( !res &&
386 ((GetLastError() == ERROR_MOD_NOT_FOUND) ||
387 (GetLastError() == ERROR_INVALID_PARAMETER)),
388 "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or "
389 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
391 mi2a.pDLLName = version_dll;
392 SetLastError(MAGIC_DEAD);
393 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
394 /* NT: ERROR_PROC_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
395 ok( !res &&
396 ((GetLastError() == ERROR_PROC_NOT_FOUND) ||
397 (GetLastError() == ERROR_INVALID_PARAMETER)),
398 "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or "
399 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
400 if (res) DeleteMonitorA(NULL, entry->env, winetest);
402 /* Test AddMonitor with real options */
403 mi2a.pDLLName = entry->dllname;
404 SetLastError(MAGIC_DEAD);
405 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
406 /* Some apps depend on the result of GetLastError() also on success of AddMonitor */
407 ok(res && (GetLastError() == ERROR_SUCCESS),
408 "returned %d with %d (expected '!= 0' with ERROR_SUCCESS)\n", res, GetLastError());
410 /* add a monitor twice */
411 SetLastError(MAGIC_DEAD);
412 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
413 /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */
414 ok( !res &&
415 ((GetLastError() == ERROR_PRINT_MONITOR_ALREADY_INSTALLED) ||
416 (GetLastError() == ERROR_ALREADY_EXISTS)),
417 "returned %d with %d (expected '0' with: "
418 "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n",
419 res, GetLastError());
421 DeleteMonitorA(NULL, entry->env, winetest);
422 SetLastError(MAGIC_DEAD);
423 res = AddMonitorA(empty, 2, (LPBYTE) &mi2a);
424 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
426 /* cleanup */
427 DeleteMonitorA(NULL, entry->env, winetest);
431 /* ########################### */
433 static void test_AddPort(void)
435 DWORD res;
437 SetLastError(0xdeadbeef);
438 res = AddPortA(NULL, 0, NULL);
439 if (is_spooler_deactivated(res, GetLastError())) return;
440 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
441 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) ||
442 (GetLastError() == ERROR_INVALID_PARAMETER)),
443 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
444 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
447 SetLastError(0xdeadbeef);
448 res = AddPortA(NULL, 0, empty);
449 /* Allowed only for (Printer-)Administrators */
450 if (is_access_denied(res, GetLastError())) return;
452 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
453 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
454 (GetLastError() == ERROR_INVALID_PARAMETER)),
455 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
456 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
459 SetLastError(0xdeadbeef);
460 res = AddPortA(NULL, 0, does_not_exist);
461 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
462 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
463 (GetLastError() == ERROR_INVALID_PARAMETER)),
464 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
465 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
469 /* ########################### */
471 static void test_AddPortEx(void)
473 PORT_INFO_2A pi;
474 DWORD res;
477 if (!pAddPortExA) {
478 win_skip("AddPortEx not supported\n");
479 return;
482 /* start test with a clean system */
483 DeletePortA(NULL, 0, tempfileA);
485 pi.pPortName = tempfileA;
486 SetLastError(0xdeadbeef);
487 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
488 if (is_spooler_deactivated(res, GetLastError())) return;
490 /* Allowed only for (Printer-)Administrators.
491 W2K+XP: ERROR_INVALID_PARAMETER */
492 if (!res && (GetLastError() == ERROR_INVALID_PARAMETER)) {
493 skip("ACCESS_DENIED (ERROR_INVALID_PARAMETER)\n");
494 return;
496 ok( res, "got %u with %u (expected '!= 0')\n", res, GetLastError());
498 /* add a port that already exists */
499 SetLastError(0xdeadbeef);
500 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
501 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
502 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
503 res, GetLastError());
504 DeletePortA(NULL, 0, tempfileA);
507 /* the Monitorname must match */
508 SetLastError(0xdeadbeef);
509 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, NULL);
510 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
511 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
512 res, GetLastError());
513 if (res) DeletePortA(NULL, 0, tempfileA);
515 SetLastError(0xdeadbeef);
516 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, empty);
517 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
518 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
519 res, GetLastError());
520 if (res) DeletePortA(NULL, 0, tempfileA);
522 SetLastError(0xdeadbeef);
523 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, does_not_exist);
524 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
525 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
526 res, GetLastError());
527 if (res) DeletePortA(NULL, 0, tempfileA);
530 /* We need a Portname */
531 SetLastError(0xdeadbeef);
532 res = pAddPortExA(NULL, 1, NULL, LocalPortA);
533 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
534 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
535 res, GetLastError());
537 pi.pPortName = NULL;
538 SetLastError(0xdeadbeef);
539 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
540 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
541 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
542 res, GetLastError());
543 if (res) DeletePortA(NULL, 0, tempfileA);
546 /* level 2 is documented as supported for Printmonitors,
547 but that is not supported for "Local Port" (localspl.dll) and
548 AddPortEx fails with ERROR_INVALID_LEVEL */
550 pi.pPortName = tempfileA;
551 pi.pMonitorName = LocalPortA;
552 pi.pDescription = winetest;
553 pi.fPortType = PORT_TYPE_WRITE;
555 SetLastError(0xdeadbeef);
556 res = pAddPortExA(NULL, 2, (LPBYTE) &pi, LocalPortA);
557 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
558 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
559 res, GetLastError());
560 if (res) DeletePortA(NULL, 0, tempfileA);
563 /* invalid levels */
564 SetLastError(0xdeadbeef);
565 res = pAddPortExA(NULL, 0, (LPBYTE) &pi, LocalPortA);
566 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
567 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
568 res, GetLastError());
570 SetLastError(0xdeadbeef);
571 res = pAddPortExA(NULL, 3, (LPBYTE) &pi, LocalPortA);
572 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
573 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
574 res, GetLastError());
577 /* cleanup */
578 DeletePortA(NULL, 0, tempfileA);
582 /* ########################### */
584 static void test_ConfigurePort(void)
586 DWORD res;
589 SetLastError(0xdeadbeef);
590 res = ConfigurePortA(NULL, 0, NULL);
591 if (is_spooler_deactivated(res, GetLastError())) return;
592 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
593 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) ||
594 (GetLastError() == ERROR_INVALID_PARAMETER)),
595 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
596 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
598 SetLastError(0xdeadbeef);
599 res = ConfigurePortA(NULL, 0, empty);
600 /* Allowed only for (Printer-)Administrators */
601 if (is_access_denied(res, GetLastError())) return;
603 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
604 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
605 (GetLastError() == ERROR_INVALID_PARAMETER)),
606 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
607 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
610 SetLastError(0xdeadbeef);
611 res = ConfigurePortA(NULL, 0, does_not_exist);
612 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
613 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
614 (GetLastError() == ERROR_INVALID_PARAMETER)),
615 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
616 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
619 /* Testing-Results:
620 - Case of Portnames is ignored
621 - Portname without ":" => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
622 - Empty Servername (LPT1:) => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
624 - Port not present => 9x: ERROR_INVALID_PARAMETER, NT:ERROR_NOT_SUPPORTED
625 - "FILE:" => 9x:Success, NT:ERROR_CANCELED
626 - Cancel ("Local Port") => ERROR_CANCELED
627 - Cancel ("Redirected Port") => Success
629 if (winetest_interactive > 0) {
630 SetLastError(0xdeadbeef);
631 res = ConfigurePortA(NULL, 0, portname_com1);
632 trace("'%s' returned %d with %d\n", portname_com1, res, GetLastError());
634 SetLastError(0xdeadbeef);
635 res = ConfigurePortA(NULL, 0, portname_lpt1);
636 trace("'%s' returned %d with %d\n", portname_lpt1, res, GetLastError());
638 SetLastError(0xdeadbeef);
639 res = ConfigurePortA(NULL, 0, portname_file);
640 trace("'%s' returned %d with %d\n", portname_file, res, GetLastError());
644 /* ########################### */
646 static void test_ClosePrinter(void)
648 HANDLE printer = 0;
649 BOOL res;
651 /* NULL is handled */
652 SetLastError(0xdeadbeef);
653 res = ClosePrinter(NULL);
654 ok(!res && (GetLastError() == ERROR_INVALID_HANDLE),
655 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
656 res, GetLastError());
658 /* A random value as HANDLE is handled */
659 SetLastError(0xdeadbeef);
660 res = ClosePrinter( (void *) -1);
661 if (is_spooler_deactivated(res, GetLastError())) return;
662 ok(!res && (GetLastError() == ERROR_INVALID_HANDLE),
663 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
664 res, GetLastError());
667 /* Normal use (The Spooler service is needed) */
668 SetLastError(0xdeadbeef);
669 res = OpenPrinterA(default_printer, &printer, NULL);
670 if (is_spooler_deactivated(res, GetLastError())) return;
671 if (res)
673 SetLastError(0xdeadbeef);
674 res = ClosePrinter(printer);
675 ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError());
678 /* double free is handled */
679 SetLastError(0xdeadbeef);
680 res = ClosePrinter(printer);
681 ok(!res && (GetLastError() == ERROR_INVALID_HANDLE),
682 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
683 res, GetLastError());
688 /* ########################### */
690 static void test_DeleteMonitor(void)
692 MONITOR_INFO_2A mi2a;
693 struct monitor_entry * entry = NULL;
694 DWORD res;
697 entry = find_installed_monitor();
699 if (!entry) {
700 skip("No usable Monitor found\n");
701 return;
704 mi2a.pName = winetest;
705 mi2a.pEnvironment = entry->env;
706 mi2a.pDLLName = entry->dllname;
708 /* Testing DeleteMonitor with real options */
709 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
711 SetLastError(MAGIC_DEAD);
712 res = DeleteMonitorA(NULL, entry->env, winetest);
713 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
715 /* Delete the Monitor twice */
716 SetLastError(MAGIC_DEAD);
717 res = DeleteMonitorA(NULL, entry->env, winetest);
718 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
719 ok( !res &&
720 ((GetLastError() == ERROR_UNKNOWN_PRINT_MONITOR) ||
721 (GetLastError() == ERROR_INVALID_PARAMETER)),
722 "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR"
723 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
725 /* the environment */
726 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
727 SetLastError(MAGIC_DEAD);
728 res = DeleteMonitorA(NULL, NULL, winetest);
729 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
731 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
732 SetLastError(MAGIC_DEAD);
733 res = DeleteMonitorA(NULL, empty, winetest);
734 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
736 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
737 SetLastError(MAGIC_DEAD);
738 res = DeleteMonitorA(NULL, invalid_env, winetest);
739 ok( res || GetLastError() == ERROR_INVALID_ENVIRONMENT /* Vista/W2K8 */,
740 "returned %d with %d\n", res, GetLastError());
742 /* the monitor-name */
743 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
744 SetLastError(MAGIC_DEAD);
745 res = DeleteMonitorA(NULL, entry->env, NULL);
746 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
747 ok( !res &&
748 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
749 (GetLastError() == ERROR_INVALID_NAME)),
750 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
751 "ERROR_INVALID_NAME)\n", res, GetLastError());
753 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
754 SetLastError(MAGIC_DEAD);
755 res = DeleteMonitorA(NULL, entry->env, empty);
756 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
757 ok( !res &&
758 ((GetLastError() == ERROR_INVALID_PARAMETER) ||
759 (GetLastError() == ERROR_INVALID_NAME)),
760 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
761 "ERROR_INVALID_NAME)\n", res, GetLastError());
763 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
764 SetLastError(MAGIC_DEAD);
765 res = DeleteMonitorA(empty, entry->env, winetest);
766 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
768 /* cleanup */
769 DeleteMonitorA(NULL, entry->env, winetest);
772 /* ########################### */
774 static void test_DeletePort(void)
776 DWORD res;
778 SetLastError(0xdeadbeef);
779 res = DeletePortA(NULL, 0, NULL);
780 if (is_spooler_deactivated(res, GetLastError())) return;
782 SetLastError(0xdeadbeef);
783 res = DeletePortA(NULL, 0, empty);
784 /* Allowed only for (Printer-)Administrators */
785 if (is_access_denied(res, GetLastError())) return;
787 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
788 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
789 (GetLastError() == ERROR_INVALID_PARAMETER)),
790 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
791 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
794 SetLastError(0xdeadbeef);
795 res = DeletePortA(NULL, 0, does_not_exist);
796 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
797 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
798 (GetLastError() == ERROR_INVALID_PARAMETER)),
799 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
800 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
804 /* ########################### */
806 static void test_EnumForms(LPSTR pName)
808 DWORD res;
809 HANDLE hprinter = 0;
810 LPBYTE buffer;
811 DWORD cbBuf;
812 DWORD pcbNeeded;
813 DWORD pcReturned;
814 DWORD level;
815 UINT i;
816 const char *formtype;
817 static const char * const formtypes[] = { "FORM_USER", "FORM_BUILTIN", "FORM_PRINTER", "FORM_flag_unknown" };
818 #define FORMTYPE_MAX 2
819 PFORM_INFO_1A pFI_1a;
820 PFORM_INFO_2A pFI_2a;
822 res = OpenPrinterA(pName, &hprinter, NULL);
823 if (is_spooler_deactivated(res, GetLastError())) return;
824 if (!res || !hprinter)
826 /* opening the local Printserver is not supported on win9x */
827 if (pName) skip("Failed to open '%s' (not supported on win9x)\n", pName);
828 return;
831 /* valid levels are 1 and 2 */
832 for(level = 0; level < 4; level++) {
833 cbBuf = 0xdeadbeef;
834 pcReturned = 0xdeadbeef;
835 SetLastError(0xdeadbeef);
836 res = EnumFormsA(hprinter, level, NULL, 0, &cbBuf, &pcReturned);
838 /* EnumForms is not implemented on win9x */
839 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
841 /* EnumForms for the server is not implemented on all NT-versions */
842 if (!res && (GetLastError() == ERROR_INVALID_HANDLE) && !pName) continue;
844 /* Level 2 for EnumForms is not supported on all systems */
845 if (!res && (GetLastError() == ERROR_INVALID_LEVEL) && (level == 2)) continue;
847 /* use only a short test when testing an invalid level */
848 if(!level || (level > 2)) {
849 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
850 (res && (pcReturned == 0)),
851 "(%d) returned %d with %d and 0x%08x (expected '0' with "
852 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
853 level, res, GetLastError(), pcReturned);
854 continue;
857 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
858 "(%d) returned %d with %d (expected '0' with "
859 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
861 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
862 if (buffer == NULL) continue;
864 SetLastError(0xdeadbeef);
865 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
866 ok(res, "(%d) returned %d with %d (expected '!=0')\n",
867 level, res, GetLastError());
869 pFI_1a = (PFORM_INFO_1A)buffer;
870 pFI_2a = (PFORM_INFO_2A)buffer;
871 for (i = 0; i < pcReturned; i++)
873 /* first part is same in FORM_INFO_1 and FORM_INFO_2 */
874 formtype = (pFI_1a->Flags <= FORMTYPE_MAX) ? formtypes[pFI_1a->Flags] : formtypes[3];
875 if (winetest_debug > 1)
876 trace("%u (%s): %.03fmm x %.03fmm, %s\n", i, pFI_1a->pName,
877 (float)pFI_1a->Size.cx/1000, (float)pFI_1a->Size.cy/1000, formtype);
879 if (level == 1) pFI_1a++;
880 else
882 BYTE get_buffer[1000];
883 FORM_INFO_2A *get_form = (FORM_INFO_2A *)get_buffer;
884 DWORD get_needed;
886 /* output additional FORM_INFO_2 fields */
887 if (winetest_debug > 1)
888 trace("\tkeyword=%s strtype=%u muidll=%s resid=%u dispname=%s langid=%u\n",
889 pFI_2a->pKeyword, pFI_2a->StringType, pFI_2a->pMuiDll,
890 pFI_2a->dwResourceId, pFI_2a->pDisplayName, pFI_2a->wLangId);
892 if (pName && i == 0) /* GetForm() appears only to work on a printer handle */
894 res = GetFormA( hprinter, pFI_1a->pName, level, NULL, 0, &get_needed );
895 ok( !res && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d gle %d\n", res, GetLastError() );
896 if (get_needed <= sizeof(get_buffer))
898 res = GetFormA( hprinter, pFI_1a->pName, level, get_buffer, get_needed, &get_needed );
899 ok( res, "got %d\n", res );
900 ok( !strcmp( pFI_2a->pName, get_form->pName ), "name mismatch\n" );
901 res = GetFormA( hprinter, pFI_1a->pName, level, get_buffer, get_needed - 1, &get_needed );
902 ok( !res && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d gle %d\n", res, GetLastError() );
905 /* offset pointer pFI_1a by 1*sizeof(FORM_INFO_2A) Bytes */
906 pFI_2a++;
907 pFI_1a = (PFORM_INFO_1A)pFI_2a;
911 SetLastError(0xdeadbeef);
912 res = EnumFormsA(hprinter, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
913 ok( res, "(%d) returned %d with %d (expected '!=0')\n",
914 level, res, GetLastError());
916 SetLastError(0xdeadbeef);
917 res = EnumFormsA(hprinter, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
918 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
919 "(%d) returned %d with %d (expected '0' with "
920 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
923 SetLastError(0xdeadbeef);
924 res = EnumFormsA(hprinter, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
925 ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) ,
926 "(%d) returned %d with %d (expected '0' with "
927 "ERROR_INVALID_USER_BUFFER)\n", level, res, GetLastError());
930 SetLastError(0xdeadbeef);
931 res = EnumFormsA(hprinter, level, buffer, cbBuf, NULL, &pcReturned);
932 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
933 "(%d) returned %d with %d (expected '0' with "
934 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
936 SetLastError(0xdeadbeef);
937 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, NULL);
938 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) ,
939 "(%d) returned %d with %d (expected '0' with "
940 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
942 SetLastError(0xdeadbeef);
943 res = EnumFormsA(0, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
944 ok( !res && (GetLastError() == ERROR_INVALID_HANDLE) ,
945 "(%d) returned %d with %d (expected '0' with "
946 "ERROR_INVALID_HANDLE)\n", level, res, GetLastError());
948 HeapFree(GetProcessHeap(), 0, buffer);
949 } /* for(level ... */
951 ClosePrinter(hprinter);
954 /* ########################### */
956 static void test_EnumMonitors(void)
958 DWORD res;
959 LPBYTE buffer;
960 DWORD cbBuf;
961 DWORD pcbNeeded;
962 DWORD pcReturned;
963 DWORD level;
965 /* valid levels are 1 and 2 */
966 for(level = 0; level < 4; level++) {
967 cbBuf = MAGIC_DEAD;
968 pcReturned = MAGIC_DEAD;
969 SetLastError(MAGIC_DEAD);
970 res = EnumMonitorsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
971 if (is_spooler_deactivated(res, GetLastError())) return;
972 /* not implemented yet in wine */
973 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
976 /* use only a short test when testing an invalid level */
977 if(!level || (level > 2)) {
978 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
979 (res && (pcReturned == 0)),
980 "(%d) returned %d with %d and 0x%08x (expected '0' with "
981 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
982 level, res, GetLastError(), pcReturned);
983 continue;
986 /* Level 2 is not supported on win9x */
987 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
988 skip("Level %d not supported\n", level);
989 continue;
992 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
993 "(%d) returned %d with %d (expected '0' with "
994 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
996 if (!cbBuf) {
997 skip("no valid buffer size returned\n");
998 continue;
1001 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
1002 if (buffer == NULL) continue;
1004 SetLastError(MAGIC_DEAD);
1005 pcbNeeded = MAGIC_DEAD;
1006 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
1007 ok(res, "(%d) returned %d with %d (expected '!=0')\n",
1008 level, res, GetLastError());
1009 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n",
1010 level, pcbNeeded, cbBuf);
1011 /* We can validate the returned Data with the Registry here */
1014 SetLastError(MAGIC_DEAD);
1015 pcReturned = MAGIC_DEAD;
1016 pcbNeeded = MAGIC_DEAD;
1017 res = EnumMonitorsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1018 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level,
1019 res, GetLastError());
1020 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
1021 pcbNeeded, cbBuf);
1023 SetLastError(MAGIC_DEAD);
1024 pcbNeeded = MAGIC_DEAD;
1025 res = EnumMonitorsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1026 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1027 "(%d) returned %d with %d (expected '0' with "
1028 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1030 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
1031 pcbNeeded, cbBuf);
1034 Do not add the next test:
1035 w2k+: RPC_X_NULL_REF_POINTER
1036 NT3.5: ERROR_INVALID_USER_BUFFER
1037 win9x: crash in winspool.drv
1039 res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1042 SetLastError(MAGIC_DEAD);
1043 pcbNeeded = MAGIC_DEAD;
1044 pcReturned = MAGIC_DEAD;
1045 res = EnumMonitorsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
1046 ok( res || GetLastError() == RPC_X_NULL_REF_POINTER,
1047 "(%d) returned %d with %d (expected '!=0' or '0' with "
1048 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1050 pcbNeeded = MAGIC_DEAD;
1051 pcReturned = MAGIC_DEAD;
1052 SetLastError(MAGIC_DEAD);
1053 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
1054 ok( res || GetLastError() == RPC_X_NULL_REF_POINTER,
1055 "(%d) returned %d with %d (expected '!=0' or '0' with "
1056 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1058 HeapFree(GetProcessHeap(), 0, buffer);
1059 } /* for(level ... */
1062 /* ########################### */
1064 static void test_EnumPorts(void)
1066 DWORD res;
1067 DWORD level;
1068 LPBYTE buffer;
1069 DWORD cbBuf;
1070 DWORD pcbNeeded;
1071 DWORD pcReturned;
1073 /* valid levels are 1 and 2 */
1074 for(level = 0; level < 4; level++) {
1076 cbBuf = 0xdeadbeef;
1077 pcReturned = 0xdeadbeef;
1078 SetLastError(0xdeadbeef);
1079 res = EnumPortsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
1080 if (is_spooler_deactivated(res, GetLastError())) return;
1082 /* use only a short test when testing an invalid level */
1083 if(!level || (level > 2)) {
1084 /* NT: ERROR_INVALID_LEVEL, 9x: success */
1085 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1086 (res && (pcReturned == 0)),
1087 "(%d) returned %d with %d and 0x%08x (expected '0' with "
1088 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1089 level, res, GetLastError(), pcReturned);
1090 continue;
1094 /* Level 2 is not supported on NT 3.x */
1095 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
1096 skip("Level %d not supported\n", level);
1097 continue;
1100 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1101 "(%d) returned %d with %d (expected '0' with "
1102 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1104 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
1105 if (buffer == NULL) continue;
1107 pcbNeeded = 0xdeadbeef;
1108 SetLastError(0xdeadbeef);
1109 res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
1110 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
1111 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1112 /* ToDo: Compare the returned Data with the Registry / "win.ini",[Ports] here */
1114 pcbNeeded = 0xdeadbeef;
1115 pcReturned = 0xdeadbeef;
1116 SetLastError(0xdeadbeef);
1117 res = EnumPortsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1118 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
1119 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1121 pcbNeeded = 0xdeadbeef;
1122 SetLastError(0xdeadbeef);
1123 res = EnumPortsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1124 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1125 "(%d) returned %d with %d (expected '0' with "
1126 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1127 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1130 Do not add this test:
1131 res = EnumPortsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1132 w2k+: RPC_X_NULL_REF_POINTER
1133 NT3.5: ERROR_INVALID_USER_BUFFER
1134 win9x: crash in winspool.drv
1137 SetLastError(0xdeadbeef);
1138 res = EnumPortsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
1139 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
1140 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
1141 ( res && (GetLastError() == ERROR_SUCCESS) ),
1142 "(%d) returned %d with %d (expected '0' with "
1143 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1144 level, res, GetLastError());
1147 SetLastError(0xdeadbeef);
1148 res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
1149 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
1150 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
1151 ( res && (GetLastError() == ERROR_SUCCESS) ),
1152 "(%d) returned %d with %d (expected '0' with "
1153 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1154 level, res, GetLastError());
1156 HeapFree(GetProcessHeap(), 0, buffer);
1160 /* ########################### */
1162 static void test_EnumPrinterDrivers(void)
1164 static char env_all[] = "all";
1166 DWORD res;
1167 LPBYTE buffer;
1168 DWORD cbBuf;
1169 DWORD pcbNeeded;
1170 DWORD pcReturned;
1171 DWORD level;
1173 /* 1-3 for w95/w98/NT4; 1-3+6 for me; 1-6 for w2k/xp/2003; 1-6+8 for vista */
1174 for(level = 0; level < 10; level++) {
1175 cbBuf = 0xdeadbeef;
1176 pcReturned = 0xdeadbeef;
1177 SetLastError(0xdeadbeef);
1178 res = EnumPrinterDriversA(NULL, NULL, level, NULL, 0, &cbBuf, &pcReturned);
1179 if (is_spooler_deactivated(res, GetLastError())) return;
1181 /* use only a short test when testing an invalid level */
1182 if(!level || (level == 7) || (level > 8)) {
1184 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1185 (res && (pcReturned == 0)),
1186 "(%d) got %u with %u and 0x%x "
1187 "(expected '0' with ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1188 level, res, GetLastError(), pcReturned);
1189 continue;
1192 /* some levels are not supported on all windows versions */
1193 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
1194 skip("Level %d not supported\n", level);
1195 continue;
1198 ok( ((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) ||
1199 (res && (default_printer == NULL)),
1200 "(%u) got %u with %u for %s (expected '0' with "
1201 "ERROR_INSUFFICIENT_BUFFER or '!= 0' without a printer)\n",
1202 level, res, GetLastError(), default_printer);
1204 if (!cbBuf) {
1205 skip("no valid buffer size returned\n");
1206 continue;
1209 /* EnumPrinterDriversA returns the same number of bytes as EnumPrinterDriversW */
1210 if (pEnumPrinterDriversW)
1212 DWORD double_needed;
1213 DWORD double_returned;
1214 pEnumPrinterDriversW(NULL, NULL, level, NULL, 0, &double_needed, &double_returned);
1215 ok(double_needed == cbBuf, "level %d: EnumPrinterDriversA returned different size %d than EnumPrinterDriversW (%d)\n", level, cbBuf, double_needed);
1218 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4);
1219 if (buffer == NULL) continue;
1221 SetLastError(0xdeadbeef);
1222 pcbNeeded = 0xdeadbeef;
1223 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
1224 ok(res, "(%u) got %u with %u (expected '!=0')\n", level, res, GetLastError());
1225 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1227 /* validate the returned data here */
1228 if (level > 1) {
1229 LPDRIVER_INFO_2A di = (LPDRIVER_INFO_2A) buffer;
1231 ok( strrchr(di->pDriverPath, '\\') != NULL,
1232 "(%u) got %s for %s (expected a full path)\n",
1233 level, di->pDriverPath, di->pName);
1237 SetLastError(0xdeadbeef);
1238 pcReturned = 0xdeadbeef;
1239 pcbNeeded = 0xdeadbeef;
1240 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1241 ok(res, "(%u) got %u with %u (expected '!=0')\n", level, res, GetLastError());
1242 ok(pcbNeeded == cbBuf, "(%u) returned %u (expected %u)\n", level, pcbNeeded, cbBuf);
1244 SetLastError(0xdeadbeef);
1245 pcbNeeded = 0xdeadbeef;
1246 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1247 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1248 "(%u) got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1249 level, res, GetLastError());
1250 ok(pcbNeeded == cbBuf, "(%u) returned %u (expected %u)\n", level, pcbNeeded, cbBuf);
1253 Do not add the next test:
1254 NT: ERROR_INVALID_USER_BUFFER
1255 win9x: crash or 100% CPU
1257 res = EnumPrinterDriversA(NULL, NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1260 SetLastError(0xdeadbeef);
1261 pcbNeeded = 0xdeadbeef;
1262 pcReturned = 0xdeadbeef;
1263 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, NULL, &pcReturned);
1264 ok( res || GetLastError() == RPC_X_NULL_REF_POINTER,
1265 "(%u) got %u with %u (expected '!=0' or '0' with "
1266 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1268 pcbNeeded = 0xdeadbeef;
1269 pcReturned = 0xdeadbeef;
1270 SetLastError(0xdeadbeef);
1271 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
1272 ok( res || GetLastError() == RPC_X_NULL_REF_POINTER,
1273 "(%u) got %u with %u (expected '!=0' or '0' with "
1274 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1276 HeapFree(GetProcessHeap(), 0, buffer);
1277 } /* for(level ... */
1279 pcbNeeded = 0;
1280 pcReturned = 0;
1281 SetLastError(0xdeadbeef);
1282 res = EnumPrinterDriversA(NULL, env_all, 1, NULL, 0, &pcbNeeded, &pcReturned);
1283 if (res)
1285 skip("no printer drivers found\n");
1286 return;
1288 if (GetLastError() == ERROR_INVALID_ENVIRONMENT)
1290 win_skip("NT4 and below don't support the 'all' environment value\n");
1291 return;
1293 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "unexpected error %u\n", GetLastError());
1295 buffer = HeapAlloc(GetProcessHeap(), 0, pcbNeeded);
1296 res = EnumPrinterDriversA(NULL, env_all, 1, buffer, pcbNeeded, &pcbNeeded, &pcReturned);
1297 ok(res, "EnumPrinterDriversA failed %u\n", GetLastError());
1298 if (res && pcReturned > 0)
1300 DRIVER_INFO_1A *di_1 = (DRIVER_INFO_1A *)buffer;
1301 ok((LPBYTE) di_1->pName == NULL || (LPBYTE) di_1->pName < buffer ||
1302 (LPBYTE) di_1->pName >= (LPBYTE)(di_1 + pcReturned),
1303 "Driver Information not in sequence; pName %p, top of data %p\n",
1304 di_1->pName, di_1 + pcReturned);
1307 HeapFree(GetProcessHeap(), 0, buffer);
1310 /* ########################### */
1312 static void test_EnumPrintProcessors(void)
1314 DWORD res;
1315 LPBYTE buffer;
1316 DWORD cbBuf;
1317 DWORD pcbNeeded;
1318 DWORD pcReturned;
1321 cbBuf = 0xdeadbeef;
1322 pcReturned = 0xdeadbeef;
1323 SetLastError(0xdeadbeef);
1324 res = EnumPrintProcessorsA(NULL, NULL, 1, NULL, 0, &cbBuf, &pcReturned);
1325 if (is_spooler_deactivated(res, GetLastError())) return;
1327 if (res && !cbBuf) {
1328 skip("No Printprocessor installed\n");
1329 return;
1332 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1333 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1334 res, GetLastError());
1336 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4);
1337 if (buffer == NULL)
1338 return;
1340 SetLastError(0xdeadbeef);
1341 pcbNeeded = 0xdeadbeef;
1342 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1343 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1344 /* validate the returned data here. */
1347 SetLastError(0xdeadbeef);
1348 pcReturned = 0xdeadbeef;
1349 pcbNeeded = 0xdeadbeef;
1350 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1351 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1353 SetLastError(0xdeadbeef);
1354 pcbNeeded = 0xdeadbeef;
1355 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1356 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1357 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1358 res, GetLastError());
1360 /* only level 1 is valid */
1361 if (0) {
1362 /* both tests crash on win98se */
1363 SetLastError(0xdeadbeef);
1364 pcbNeeded = 0xdeadbeef;
1365 pcReturned = 0xdeadbeef;
1366 res = EnumPrintProcessorsA(NULL, NULL, 0, buffer, cbBuf, &pcbNeeded, &pcReturned);
1367 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1368 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1369 res, GetLastError());
1371 SetLastError(0xdeadbeef);
1372 pcbNeeded = 0xdeadbeef;
1373 res = EnumPrintProcessorsA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded, &pcReturned);
1374 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1375 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1376 res, GetLastError());
1379 /* an empty environment is ignored */
1380 SetLastError(0xdeadbeef);
1381 pcbNeeded = 0xdeadbeef;
1382 res = EnumPrintProcessorsA(NULL, empty, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1383 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1385 /* the environment is checked */
1386 SetLastError(0xdeadbeef);
1387 pcbNeeded = 0xdeadbeef;
1388 res = EnumPrintProcessorsA(NULL, invalid_env, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1389 /* NT5: ERROR_INVALID_ENVIRONMENT, NT4: res != 0, 9x: ERROR_INVALID_PARAMETER */
1390 ok( broken(res) || /* NT4 */
1391 (GetLastError() == ERROR_INVALID_ENVIRONMENT) ||
1392 (GetLastError() == ERROR_INVALID_PARAMETER),
1393 "got %u with %u (expected '0' with ERROR_INVALID_ENVIRONMENT or "
1394 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1397 /* failure-Codes for NULL */
1398 SetLastError(0xdeadbeef);
1399 pcbNeeded = 0xdeadbeef;
1400 pcReturned = 0xdeadbeef;
1401 res = EnumPrintProcessorsA(NULL, NULL, 1, NULL, cbBuf, &pcbNeeded, &pcReturned);
1402 todo_wine {
1403 ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) ,
1404 "got %u with %u (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1405 res, GetLastError());
1408 SetLastError(0xdeadbeef);
1409 pcbNeeded = 0xdeadbeef;
1410 pcReturned = 0xdeadbeef;
1411 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, NULL, &pcReturned);
1412 /* the NULL is ignored on win9x */
1413 ok( broken(res) || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)),
1414 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1415 res, GetLastError());
1417 pcbNeeded = 0xdeadbeef;
1418 pcReturned = 0xdeadbeef;
1419 SetLastError(0xdeadbeef);
1420 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded, NULL);
1421 /* the NULL is ignored on win9x */
1422 ok( broken(res) || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)),
1423 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1424 res, GetLastError());
1426 HeapFree(GetProcessHeap(), 0, buffer);
1430 /* ########################### */
1432 static void test_GetDefaultPrinter(void)
1434 BOOL retval;
1435 DWORD exact = DEFAULT_PRINTER_SIZE;
1436 DWORD size;
1437 char buffer[DEFAULT_PRINTER_SIZE];
1439 if (!pGetDefaultPrinterA) return;
1440 /* only supported on NT like OSes starting with win2k */
1442 SetLastError(ERROR_SUCCESS);
1443 retval = pGetDefaultPrinterA(buffer, &exact);
1444 if (!retval || !exact || !*buffer ||
1445 (ERROR_SUCCESS != GetLastError())) {
1446 if ((ERROR_FILE_NOT_FOUND == GetLastError()) ||
1447 (ERROR_INVALID_NAME == GetLastError()))
1448 trace("this test requires a default printer to be set\n");
1449 else {
1450 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
1451 "function returned %s\n"
1452 "last error 0x%08x\n"
1453 "returned buffer size 0x%08x\n"
1454 "returned buffer content %s\n",
1455 retval ? "true" : "false", GetLastError(), exact, buffer);
1457 return;
1459 SetLastError(ERROR_SUCCESS);
1460 retval = pGetDefaultPrinterA(NULL, NULL);
1461 ok( !retval, "function result wrong! False expected\n");
1462 ok( ERROR_INVALID_PARAMETER == GetLastError(),
1463 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1464 GetLastError());
1466 SetLastError(ERROR_SUCCESS);
1467 retval = pGetDefaultPrinterA(buffer, NULL);
1468 ok( !retval, "function result wrong! False expected\n");
1469 ok( ERROR_INVALID_PARAMETER == GetLastError(),
1470 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1471 GetLastError());
1473 SetLastError(ERROR_SUCCESS);
1474 size = 0;
1475 retval = pGetDefaultPrinterA(NULL, &size);
1476 ok( !retval, "function result wrong! False expected\n");
1477 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1478 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1479 GetLastError());
1480 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1481 exact, size);
1483 SetLastError(ERROR_SUCCESS);
1484 size = DEFAULT_PRINTER_SIZE;
1485 retval = pGetDefaultPrinterA(NULL, &size);
1486 ok( !retval, "function result wrong! False expected\n");
1487 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1488 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1489 GetLastError());
1490 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1491 exact, size);
1493 size = 0;
1494 retval = pGetDefaultPrinterA(buffer, &size);
1495 ok( !retval, "function result wrong! False expected\n");
1496 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1497 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1498 GetLastError());
1499 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1500 exact, size);
1502 size = exact;
1503 retval = pGetDefaultPrinterA(buffer, &size);
1504 ok( retval, "function result wrong! True expected\n");
1505 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1506 exact, size);
1509 static void test_GetPrinterDriverDirectory(void)
1511 LPBYTE buffer = NULL;
1512 DWORD cbBuf = 0, pcbNeeded = 0;
1513 BOOL res;
1516 SetLastError(MAGIC_DEAD);
1517 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
1518 if (is_spooler_deactivated(res, GetLastError())) return;
1520 trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
1521 res, GetLastError(), cbBuf);
1523 ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1524 "returned %d with lasterror=%d (expected '0' with "
1525 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
1527 if (!cbBuf) {
1528 skip("no valid buffer size returned\n");
1529 return;
1532 buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
1533 if (buffer == NULL) return ;
1535 res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
1536 ok( res, "expected result != 0, got %d\n", res);
1537 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1538 pcbNeeded, cbBuf);
1540 res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1541 ok( res, "expected result != 0, got %d\n", res);
1542 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1543 pcbNeeded, cbBuf);
1545 SetLastError(MAGIC_DEAD);
1546 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
1547 ok( !res , "expected result == 0, got %d\n", res);
1548 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1549 pcbNeeded, cbBuf);
1551 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1552 "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
1553 GetLastError());
1556 Do not add the next test:
1557 XPsp2: crash in this app, when the spooler is not running
1558 NT3.5: ERROR_INVALID_USER_BUFFER
1559 win9x: ERROR_INVALID_PARAMETER
1561 pcbNeeded = MAGIC_DEAD;
1562 SetLastError(MAGIC_DEAD);
1563 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1566 SetLastError(MAGIC_DEAD);
1567 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
1568 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1569 NT: RPC_X_NULL_REF_POINTER */
1570 ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER) ||
1571 (GetLastError() == ERROR_INVALID_PARAMETER),
1572 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1573 "or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1575 SetLastError(MAGIC_DEAD);
1576 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
1577 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1578 NT: RPC_X_NULL_REF_POINTER */
1579 ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER) ||
1580 (GetLastError() == ERROR_INVALID_PARAMETER),
1581 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1582 "or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1584 /* with a valid buffer, but level is too large */
1585 buffer[0] = '\0';
1586 SetLastError(MAGIC_DEAD);
1587 res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
1589 /* Level not checked in win9x and wine:*/
1590 if((res != FALSE) && buffer[0])
1592 trace("Level '2' not checked '%s'\n", buffer);
1594 else
1596 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1597 "returned %d with lasterror=%d (expected '0' with "
1598 "ERROR_INVALID_LEVEL)\n", res, GetLastError());
1601 /* printing environments are case insensitive */
1602 /* "Windows 4.0" is valid for win9x and NT */
1603 buffer[0] = '\0';
1604 SetLastError(MAGIC_DEAD);
1605 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1,
1606 buffer, cbBuf*2, &pcbNeeded);
1608 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
1609 cbBuf = pcbNeeded;
1610 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1611 if (buffer == NULL) return ;
1613 SetLastError(MAGIC_DEAD);
1614 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1,
1615 buffer, cbBuf*2, &pcbNeeded);
1618 ok(res && buffer[0], "returned %d with "
1619 "lasterror=%d and len=%d (expected '1' with 'len > 0')\n",
1620 res, GetLastError(), lstrlenA((char *)buffer));
1622 buffer[0] = '\0';
1623 SetLastError(MAGIC_DEAD);
1624 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1,
1625 buffer, cbBuf*2, &pcbNeeded);
1627 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
1628 cbBuf = pcbNeeded;
1629 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1630 if (buffer == NULL) return ;
1632 buffer[0] = '\0';
1633 SetLastError(MAGIC_DEAD);
1634 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1,
1635 buffer, cbBuf*2, &pcbNeeded);
1638 /* "Windows NT x86" is invalid for win9x */
1639 ok( (res && buffer[0]) ||
1640 (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)),
1641 "returned %d with lasterror=%d and len=%d (expected '!= 0' with "
1642 "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
1643 res, GetLastError(), lstrlenA((char *)buffer));
1645 /* A setup program (PDFCreator_0.8.0) use empty strings */
1646 SetLastError(MAGIC_DEAD);
1647 res = GetPrinterDriverDirectoryA(empty, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1648 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1650 SetLastError(MAGIC_DEAD);
1651 res = GetPrinterDriverDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1652 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1654 SetLastError(MAGIC_DEAD);
1655 res = GetPrinterDriverDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1656 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1658 HeapFree( GetProcessHeap(), 0, buffer);
1661 /* ##### */
1663 static void test_GetPrintProcessorDirectory(void)
1665 LPBYTE buffer = NULL;
1666 DWORD cbBuf = 0;
1667 DWORD pcbNeeded = 0;
1668 BOOL res;
1671 SetLastError(0xdeadbeef);
1672 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf);
1673 if (is_spooler_deactivated(res, GetLastError())) return;
1675 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1676 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1677 res, GetLastError());
1679 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2);
1680 if(buffer == NULL) return;
1682 buffer[0] = '\0';
1683 SetLastError(0xdeadbeef);
1684 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
1685 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1687 SetLastError(0xdeadbeef);
1688 buffer[0] = '\0';
1689 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1690 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1692 /* Buffer too small */
1693 buffer[0] = '\0';
1694 SetLastError(0xdeadbeef);
1695 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
1696 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1697 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1698 res, GetLastError());
1700 if (0)
1702 /* XPsp2: the program will crash here, when the spooler is not running */
1703 /* GetPrinterDriverDirectory has the same bug */
1704 pcbNeeded = 0;
1705 SetLastError(0xdeadbeef);
1706 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1707 /* NT: ERROR_INVALID_USER_BUFFER, 9x: res != 0 */
1708 ok( (!res && (GetLastError() == ERROR_INVALID_USER_BUFFER)) ||
1709 broken(res),
1710 "returned %d with %d (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1711 res, GetLastError());
1714 buffer[0] = '\0';
1715 SetLastError(0xdeadbeef);
1716 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
1717 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1718 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1719 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) ||
1720 (GetLastError() == ERROR_INVALID_PARAMETER)),
1721 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1722 "or with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1724 buffer[0] = '\0';
1725 SetLastError(0xdeadbeef);
1726 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
1727 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1728 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1729 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) ||
1730 (GetLastError() == ERROR_INVALID_PARAMETER)),
1731 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1732 "or with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1734 /* with a valid buffer, but level is invalid */
1735 buffer[0] = '\0';
1736 SetLastError(0xdeadbeef);
1737 res = GetPrintProcessorDirectoryA(NULL, NULL, 0, buffer, cbBuf, &pcbNeeded);
1738 /* Level is ignored in win9x*/
1739 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1740 broken(res && buffer[0]),
1741 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1742 res, GetLastError());
1744 buffer[0] = '\0';
1745 SetLastError(0xdeadbeef);
1746 res = GetPrintProcessorDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
1747 /* Level is ignored on win9x*/
1748 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1749 broken(res && buffer[0]),
1750 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1751 res, GetLastError());
1753 /* Empty environment is the same as the default environment */
1754 buffer[0] = '\0';
1755 SetLastError(0xdeadbeef);
1756 res = GetPrintProcessorDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded);
1757 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1759 /* "Windows 4.0" is valid for win9x and NT */
1760 buffer[0] = '\0';
1761 SetLastError(0xdeadbeef);
1762 res = GetPrintProcessorDirectoryA(NULL, env_win9x_case, 1, buffer, cbBuf*2, &pcbNeeded);
1763 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1766 /* "Windows NT x86" is invalid for win9x */
1767 buffer[0] = '\0';
1768 SetLastError(0xdeadbeef);
1769 res = GetPrintProcessorDirectoryA(NULL, env_x86, 1, buffer, cbBuf*2, &pcbNeeded);
1770 ok( res || (GetLastError() == ERROR_INVALID_ENVIRONMENT),
1771 "returned %d with %d (expected '!= 0' or '0' with "
1772 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
1774 /* invalid on all systems */
1775 buffer[0] = '\0';
1776 SetLastError(0xdeadbeef);
1777 res = GetPrintProcessorDirectoryA(NULL, invalid_env, 1, buffer, cbBuf*2, &pcbNeeded);
1778 ok( !res && (GetLastError() == ERROR_INVALID_ENVIRONMENT),
1779 "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
1780 res, GetLastError());
1782 /* Empty servername is the same as the local computer */
1783 buffer[0] = '\0';
1784 SetLastError(0xdeadbeef);
1785 res = GetPrintProcessorDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1786 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1788 /* invalid on all systems */
1789 buffer[0] = '\0';
1790 SetLastError(0xdeadbeef);
1791 res = GetPrintProcessorDirectoryA(server_does_not_exist, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
1792 ok( !res, "expected failure\n");
1793 ok( GetLastError() == RPC_S_SERVER_UNAVAILABLE || /* NT */
1794 GetLastError() == ERROR_INVALID_PARAMETER || /* 9x */
1795 GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista */
1796 "unexpected last error %d\n", GetLastError());
1798 HeapFree(GetProcessHeap(), 0, buffer);
1801 /* ##### */
1803 static void test_OpenPrinter(void)
1805 PRINTER_DEFAULTSA defaults;
1806 HANDLE hprinter;
1807 DWORD res;
1809 SetLastError(MAGIC_DEAD);
1810 res = OpenPrinterA(NULL, NULL, NULL);
1811 if (is_spooler_deactivated(res, GetLastError())) return;
1813 ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
1814 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1815 res, GetLastError());
1818 /* Get Handle for the local Printserver (NT only)*/
1819 hprinter = (HANDLE) MAGIC_DEAD;
1820 SetLastError(MAGIC_DEAD);
1821 res = OpenPrinterA(NULL, &hprinter, NULL);
1822 if (is_spooler_deactivated(res, GetLastError())) return;
1823 ok(res || GetLastError() == ERROR_INVALID_PARAMETER,
1824 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1825 res, GetLastError());
1826 if(res) {
1827 ClosePrinter(hprinter);
1829 defaults.pDatatype=NULL;
1830 defaults.pDevMode=NULL;
1832 defaults.DesiredAccess=0;
1833 hprinter = (HANDLE) MAGIC_DEAD;
1834 SetLastError(MAGIC_DEAD);
1835 res = OpenPrinterA(NULL, &hprinter, &defaults);
1836 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1837 if (res) ClosePrinter(hprinter);
1839 defaults.DesiredAccess=-1;
1840 hprinter = (HANDLE) MAGIC_DEAD;
1841 SetLastError(MAGIC_DEAD);
1842 res = OpenPrinterA(NULL, &hprinter, &defaults);
1843 todo_wine {
1844 ok(!res && GetLastError() == ERROR_ACCESS_DENIED,
1845 "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n",
1846 res, GetLastError());
1848 if (res) ClosePrinter(hprinter);
1853 if (local_server != NULL) {
1854 hprinter = (HANDLE) 0xdeadbeef;
1855 SetLastError(0xdeadbeef);
1856 res = OpenPrinterA(local_server, &hprinter, NULL);
1857 ok(res || GetLastError() == ERROR_INVALID_PARAMETER,
1858 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1859 res, GetLastError());
1860 if(res) ClosePrinter(hprinter);
1863 /* Invalid Printername */
1864 hprinter = (HANDLE) MAGIC_DEAD;
1865 SetLastError(MAGIC_DEAD);
1866 res = OpenPrinterA(illegal_name, &hprinter, NULL);
1867 ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) ||
1868 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1869 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or"
1870 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1871 if(res) ClosePrinter(hprinter);
1873 hprinter = (HANDLE) MAGIC_DEAD;
1874 SetLastError(MAGIC_DEAD);
1875 res = OpenPrinterA(empty, &hprinter, NULL);
1876 /* NT: ERROR_INVALID_PRINTER_NAME, 9x: ERROR_INVALID_PARAMETER */
1877 ok( !res &&
1878 ((GetLastError() == ERROR_INVALID_PRINTER_NAME) ||
1879 (GetLastError() == ERROR_INVALID_PARAMETER) ),
1880 "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME"
1881 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1882 if(res) ClosePrinter(hprinter);
1885 /* get handle for the default printer */
1886 if (default_printer)
1888 hprinter = (HANDLE) MAGIC_DEAD;
1889 SetLastError(MAGIC_DEAD);
1890 res = OpenPrinterA(default_printer, &hprinter, NULL);
1891 if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
1893 trace("The service 'Spooler' is required for '%s'\n", default_printer);
1894 return;
1896 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1897 if(res) ClosePrinter(hprinter);
1899 SetLastError(MAGIC_DEAD);
1900 res = OpenPrinterA(default_printer, NULL, NULL);
1901 /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1902 ok(res || (GetLastError() == ERROR_INVALID_PARAMETER),
1903 "returned %d with %d (expected '!=0' or '0' with "
1904 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1906 defaults.pDatatype=NULL;
1907 defaults.pDevMode=NULL;
1908 defaults.DesiredAccess=0;
1910 hprinter = (HANDLE) MAGIC_DEAD;
1911 SetLastError(MAGIC_DEAD);
1912 res = OpenPrinterA(default_printer, &hprinter, &defaults);
1913 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1914 "returned %d with %d (expected '!=0' or '0' with "
1915 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1916 if(res) ClosePrinter(hprinter);
1918 defaults.pDatatype = empty;
1920 hprinter = (HANDLE) MAGIC_DEAD;
1921 SetLastError(MAGIC_DEAD);
1922 res = OpenPrinterA(default_printer, &hprinter, &defaults);
1923 /* stop here, when a remote Printserver has no RPC-Service running */
1924 if (is_spooler_deactivated(res, GetLastError())) return;
1925 ok(res || ((GetLastError() == ERROR_INVALID_DATATYPE) ||
1926 (GetLastError() == ERROR_ACCESS_DENIED)),
1927 "returned %d with %d (expected '!=0' or '0' with: "
1928 "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1929 res, GetLastError());
1930 if(res) ClosePrinter(hprinter);
1933 defaults.pDatatype=NULL;
1934 defaults.DesiredAccess=PRINTER_ACCESS_USE;
1936 hprinter = (HANDLE) MAGIC_DEAD;
1937 SetLastError(MAGIC_DEAD);
1938 res = OpenPrinterA(default_printer, &hprinter, &defaults);
1939 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1940 "returned %d with %d (expected '!=0' or '0' with "
1941 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1942 if(res) ClosePrinter(hprinter);
1945 defaults.DesiredAccess=PRINTER_ALL_ACCESS;
1946 hprinter = (HANDLE) MAGIC_DEAD;
1947 SetLastError(MAGIC_DEAD);
1948 res = OpenPrinterA(default_printer, &hprinter, &defaults);
1949 ok(res || GetLastError() == ERROR_ACCESS_DENIED,
1950 "returned %d with %d (expected '!=0' or '0' with "
1951 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1952 if(res) ClosePrinter(hprinter);
1958 static void test_SetDefaultPrinter(void)
1960 DWORD res;
1961 DWORD size = DEFAULT_PRINTER_SIZE;
1962 CHAR buffer[DEFAULT_PRINTER_SIZE];
1963 CHAR org_value[DEFAULT_PRINTER_SIZE];
1965 if (!default_printer)
1967 skip("There is no default printer installed\n");
1968 return;
1971 if (!pSetDefaultPrinterA) return;
1972 /* only supported on win2k and above */
1974 /* backup the original value */
1975 org_value[0] = '\0';
1976 SetLastError(MAGIC_DEAD);
1977 res = GetProfileStringA("windows", "device", NULL, org_value, size);
1978 ok(res, "GetProfileString error %d\n", GetLastError());
1980 /* first part: with the default Printer */
1981 SetLastError(MAGIC_DEAD);
1982 res = pSetDefaultPrinterA("no_printer_with_this_name");
1983 if (is_spooler_deactivated(res, GetLastError())) return;
1985 /* Not implemented in wine */
1986 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
1987 trace("SetDefaultPrinterA() not implemented yet.\n");
1988 return;
1991 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
1992 "returned %d with %d (expected '0' with "
1993 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1995 WriteProfileStringA("windows", "device", org_value);
1996 SetLastError(MAGIC_DEAD);
1997 res = pSetDefaultPrinterA("");
1998 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME,
1999 "returned %d with %d (expected '!=0' or '0' with "
2000 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2002 WriteProfileStringA("windows", "device", org_value);
2003 SetLastError(MAGIC_DEAD);
2004 res = pSetDefaultPrinterA(NULL);
2005 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME,
2006 "returned %d with %d (expected '!=0' or '0' with "
2007 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2009 WriteProfileStringA("windows", "device", org_value);
2010 SetLastError(MAGIC_DEAD);
2011 res = pSetDefaultPrinterA(default_printer);
2012 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME,
2013 "returned %d with %d (expected '!=0' or '0' with "
2014 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2017 /* second part: always without a default Printer */
2018 WriteProfileStringA("windows", "device", NULL);
2019 SetLastError(MAGIC_DEAD);
2020 res = pSetDefaultPrinterA("no_printer_with_this_name");
2022 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
2023 "returned %d with %d (expected '0' with "
2024 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2026 WriteProfileStringA("windows", "device", NULL);
2027 SetLastError(MAGIC_DEAD);
2028 res = pSetDefaultPrinterA("");
2029 if (is_spooler_deactivated(res, GetLastError()))
2030 goto restore_old_printer;
2032 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2033 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME,
2034 "returned %d with %d (expected '!=0' or '0' with "
2035 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2037 WriteProfileStringA("windows", "device", NULL);
2038 SetLastError(MAGIC_DEAD);
2039 res = pSetDefaultPrinterA(NULL);
2040 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2041 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME,
2042 "returned %d with %d (expected '!=0' or '0' with "
2043 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2045 WriteProfileStringA("windows", "device", NULL);
2046 SetLastError(MAGIC_DEAD);
2047 res = pSetDefaultPrinterA(default_printer);
2048 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME,
2049 "returned %d with %d (expected '!=0' or '0' with "
2050 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2052 /* restore the original value */
2053 restore_old_printer:
2054 res = pSetDefaultPrinterA(default_printer); /* the nice way */
2055 ok(res, "SetDefaultPrinter error %d\n", GetLastError());
2056 WriteProfileStringA("windows", "device", org_value); /* the old way */
2058 buffer[0] = '\0';
2059 SetLastError(MAGIC_DEAD);
2060 res = GetProfileStringA("windows", "device", NULL, buffer, size);
2061 ok(res, "GetProfileString error %d\n", GetLastError());
2062 ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value);
2066 /* ########################### */
2068 static void test_XcvDataW_MonitorUI(void)
2070 DWORD res;
2071 HANDLE hXcv;
2072 BYTE buffer[MAX_PATH + 4];
2073 DWORD needed;
2074 DWORD status;
2075 DWORD len;
2076 PRINTER_DEFAULTSA pd;
2078 /* api is not present before w2k */
2079 if (pXcvDataW == NULL) return;
2081 pd.pDatatype = NULL;
2082 pd.pDevMode = NULL;
2083 pd.DesiredAccess = SERVER_ACCESS_ADMINISTER;
2085 hXcv = NULL;
2086 SetLastError(0xdeadbeef);
2087 res = OpenPrinterA(xcv_localport, &hXcv, &pd);
2088 if (is_spooler_deactivated(res, GetLastError())) return;
2089 if (is_access_denied(res, GetLastError())) return;
2091 ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv);
2092 if (!res) return;
2094 /* ask for needed size */
2095 needed = (DWORD) 0xdeadbeef;
2096 status = (DWORD) 0xdeadbeef;
2097 SetLastError(0xdeadbeef);
2098 res = pXcvDataW(hXcv, L"MonitorUI", NULL, 0, NULL, 0, &needed, &status);
2099 ok( res && (status == ERROR_INSUFFICIENT_BUFFER) && (needed <= MAX_PATH),
2100 "returned %d with %u and %u for status %u (expected '!= 0' and "
2101 "'<= MAX_PATH' for status ERROR_INSUFFICIENT_BUFFER)\n",
2102 res, GetLastError(), needed, status);
2104 if (needed > MAX_PATH) {
2105 ClosePrinter(hXcv);
2106 skip("buffer overflow (%u)\n", needed);
2107 return;
2109 len = needed; /* Size is in bytes */
2111 /* the command is required */
2112 needed = (DWORD) 0xdeadbeef;
2113 status = (DWORD) 0xdeadbeef;
2114 SetLastError(0xdeadbeef);
2115 res = pXcvDataW(hXcv, L"", NULL, 0, NULL, 0, &needed, &status);
2116 ok( res && (status == ERROR_INVALID_PARAMETER),
2117 "returned %d with %u and %u for status %u (expected '!= 0' with "
2118 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), needed, status);
2120 needed = (DWORD) 0xdeadbeef;
2121 status = (DWORD) 0xdeadbeef;
2122 SetLastError(0xdeadbeef);
2123 res = pXcvDataW(hXcv, NULL, NULL, 0, buffer, MAX_PATH, &needed, &status);
2124 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER),
2125 "returned %d with %u and %u for status %u (expected '0' with "
2126 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2128 /* "PDWORD needed" is checked before RPC-Errors */
2129 needed = (DWORD) 0xdeadbeef;
2130 status = (DWORD) 0xdeadbeef;
2131 SetLastError(0xdeadbeef);
2132 res = pXcvDataW(hXcv, L"MonitorUI", NULL, 0, buffer, len, NULL, &status);
2133 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
2134 "returned %d with %u and %u for status %u (expected '0' with "
2135 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), needed, status);
2137 needed = (DWORD) 0xdeadbeef;
2138 status = (DWORD) 0xdeadbeef;
2139 SetLastError(0xdeadbeef);
2140 res = pXcvDataW(hXcv, L"MonitorUI", NULL, 0, NULL, len, &needed, &status);
2141 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER),
2142 "returned %d with %u and %u for status %u (expected '0' with "
2143 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2145 needed = (DWORD) 0xdeadbeef;
2146 status = (DWORD) 0xdeadbeef;
2147 SetLastError(0xdeadbeef);
2148 res = pXcvDataW(hXcv, L"MonitorUI", NULL, 0, buffer, len, &needed, NULL);
2149 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER),
2150 "returned %d with %u and %u for status %u (expected '0' with "
2151 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2153 /* off by one: larger */
2154 needed = (DWORD) 0xdeadbeef;
2155 status = (DWORD) 0xdeadbeef;
2156 SetLastError(0xdeadbeef);
2157 res = pXcvDataW(hXcv, L"MonitorUI", NULL, 0, buffer, len+1, &needed, &status);
2158 ok( res && (status == ERROR_SUCCESS),
2159 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2160 "ERROR_SUCCESS)\n", res, GetLastError(), needed, status);
2162 /* off by one: smaller */
2163 /* the buffer is not modified for NT4, w2k, XP */
2164 needed = (DWORD) 0xdeadbeef;
2165 status = (DWORD) 0xdeadbeef;
2166 SetLastError(0xdeadbeef);
2167 res = pXcvDataW(hXcv, L"MonitorUI", NULL, 0, buffer, len-1, &needed, &status);
2168 ok( res && (status == ERROR_INSUFFICIENT_BUFFER),
2169 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2170 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError(), needed, status);
2173 /* Normal use. The DLL-Name without a Path is returned */
2174 memset(buffer, 0, len);
2175 needed = (DWORD) 0xdeadbeef;
2176 status = (DWORD) 0xdeadbeef;
2177 SetLastError(0xdeadbeef);
2178 res = pXcvDataW(hXcv, L"MonitorUI", NULL, 0, buffer, len, &needed, &status);
2179 ok( res && (status == ERROR_SUCCESS),
2180 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2181 "ERROR_SUCCESS)\n", res, GetLastError(), needed, status);
2183 ClosePrinter(hXcv);
2186 /* ########################### */
2188 static void test_XcvDataW_PortIsValid(void)
2190 DWORD res;
2191 HANDLE hXcv;
2192 DWORD needed;
2193 DWORD status;
2194 PRINTER_DEFAULTSA pd;
2196 /* api is not present before w2k */
2197 if (pXcvDataW == NULL) return;
2199 pd.pDatatype = NULL;
2200 pd.pDevMode = NULL;
2201 pd.DesiredAccess = SERVER_ACCESS_ADMINISTER;
2203 hXcv = NULL;
2204 SetLastError(0xdeadbeef);
2205 res = OpenPrinterA(xcv_localport, &hXcv, &pd);
2206 if (is_spooler_deactivated(res, GetLastError())) return;
2207 if (is_access_denied(res, GetLastError())) return;
2209 ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv);
2210 if (!res) return;
2213 /* "PDWORD needed" is always required */
2214 needed = (DWORD) 0xdeadbeef;
2215 status = (DWORD) 0xdeadbeef;
2216 SetLastError(0xdeadbeef);
2217 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) L"LPT1:", sizeof(L"LPT1:"), NULL, 0, NULL, &status);
2218 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER),
2219 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_INVALID_PARAMETER)\n",
2220 res, GetLastError(), needed, status);
2222 /* an empty name is not allowed */
2223 needed = (DWORD) 0xdeadbeef;
2224 status = (DWORD) 0xdeadbeef;
2225 SetLastError(0xdeadbeef);
2226 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) L"", sizeof(L""), NULL, 0, &needed, &status);
2227 ok( res && ((status == ERROR_FILE_NOT_FOUND) || (status == ERROR_PATH_NOT_FOUND)),
2228 "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2229 "ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND)\n",
2230 res, GetLastError(), needed, status);
2232 /* a directory is not allowed */
2233 needed = (DWORD) 0xdeadbeef;
2234 status = (DWORD) 0xdeadbeef;
2235 SetLastError(0xdeadbeef);
2236 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) tempdirW, (lstrlenW(tempdirW) + 1) * sizeof(WCHAR),
2237 NULL, 0, &needed, &status);
2238 /* XP: ERROR_PATH_NOT_FOUND, w2k ERROR_ACCESS_DENIED */
2239 ok( res && ((status == ERROR_PATH_NOT_FOUND) || (status == ERROR_ACCESS_DENIED)),
2240 "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2241 "ERROR_PATH_NOT_FOUND or ERROR_ACCESS_DENIED)\n",
2242 res, GetLastError(), needed, status);
2244 /* more valid well known ports */
2245 needed = (DWORD) 0xdeadbeef;
2246 status = (DWORD) 0xdeadbeef;
2247 SetLastError(0xdeadbeef);
2248 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) L"LPT1:", sizeof(L"LPT1:"), NULL, 0, &needed, &status);
2249 ok( res && (status == ERROR_SUCCESS),
2250 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2251 res, GetLastError(), needed, status);
2253 needed = (DWORD) 0xdeadbeef;
2254 status = (DWORD) 0xdeadbeef;
2255 SetLastError(0xdeadbeef);
2256 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) L"LPT2:", sizeof(L"LPT2:"), NULL, 0, &needed, &status);
2257 ok( res && (status == ERROR_SUCCESS),
2258 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2259 res, GetLastError(), needed, status);
2261 needed = (DWORD) 0xdeadbeef;
2262 status = (DWORD) 0xdeadbeef;
2263 SetLastError(0xdeadbeef);
2264 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) L"COM1:", sizeof(L"COM1:"), NULL, 0, &needed, &status);
2265 ok( res && (status == ERROR_SUCCESS),
2266 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2267 res, GetLastError(), needed, status);
2269 needed = (DWORD) 0xdeadbeef;
2270 status = (DWORD) 0xdeadbeef;
2271 SetLastError(0xdeadbeef);
2272 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) L"COM2:", sizeof(L"COM2:"), NULL, 0, &needed, &status);
2273 ok( res && (status == ERROR_SUCCESS),
2274 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2275 res, GetLastError(), needed, status);
2277 needed = (DWORD) 0xdeadbeef;
2278 status = (DWORD) 0xdeadbeef;
2279 SetLastError(0xdeadbeef);
2280 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) L"FILE:", sizeof(L"FILE:"), NULL, 0, &needed, &status);
2281 ok( res && (status == ERROR_SUCCESS),
2282 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2283 res, GetLastError(), needed, status);
2286 /* a normal, writable file is allowed */
2287 needed = (DWORD) 0xdeadbeef;
2288 status = (DWORD) 0xdeadbeef;
2289 SetLastError(0xdeadbeef);
2290 res = pXcvDataW(hXcv, L"PortIsValid", (BYTE *) tempfileW, (lstrlenW(tempfileW) + 1) * sizeof(WCHAR),
2291 NULL, 0, &needed, &status);
2292 ok( res && (status == ERROR_SUCCESS),
2293 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2294 res, GetLastError(), needed, status);
2296 ClosePrinter(hXcv);
2299 /* ########################### */
2301 static void test_GetPrinter(void)
2303 HANDLE hprn;
2304 BOOL ret;
2305 BYTE *buf;
2306 INT level;
2307 DWORD needed, filled;
2309 if (!default_printer)
2311 skip("There is no default printer installed\n");
2312 return;
2315 hprn = 0;
2316 ret = OpenPrinterA(default_printer, &hprn, NULL);
2317 if (!ret)
2319 skip("Unable to open the default printer (%s)\n", default_printer);
2320 return;
2322 ok(hprn != 0, "wrong hprn %p\n", hprn);
2324 for (level = 1; level <= 9; level++)
2326 SetLastError(0xdeadbeef);
2327 needed = (DWORD)-1;
2328 ret = GetPrinterA(hprn, level, NULL, 0, &needed);
2329 if (ret)
2331 win_skip("Level %d is not supported on Win9x/WinMe\n", level);
2332 ok(GetLastError() == ERROR_SUCCESS, "wrong error %d\n", GetLastError());
2333 ok(needed == 0,"Expected 0, got %d\n", needed);
2334 continue;
2336 ok(!ret, "level %d: GetPrinter should fail\n", level);
2337 /* Not all levels are supported on all Windows-Versions */
2338 if (GetLastError() == ERROR_INVALID_LEVEL ||
2339 GetLastError() == ERROR_NOT_SUPPORTED /* Win9x/WinMe */)
2341 skip("Level %d not supported\n", level);
2342 continue;
2344 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
2345 ok(needed > 0,"not expected needed buffer size %d\n", needed);
2347 /* GetPrinterA returns the same number of bytes as GetPrinterW */
2348 if (!ret && pGetPrinterW && level != 6 && level != 7)
2350 DWORD double_needed;
2351 ret = pGetPrinterW(hprn, level, NULL, 0, &double_needed);
2352 ok(!ret, "level %d: GetPrinter error %d\n", level, GetLastError());
2353 ok(double_needed == needed, "level %d: GetPrinterA returned different size %d than GetPrinterW (%d)\n", level, needed, double_needed);
2356 buf = HeapAlloc(GetProcessHeap(), 0, needed);
2358 SetLastError(0xdeadbeef);
2359 filled = -1;
2360 ret = GetPrinterA(hprn, level, buf, needed, &filled);
2361 ok(ret, "level %d: GetPrinter error %d\n", level, GetLastError());
2362 ok(needed == filled, "needed %d != filled %d\n", needed, filled);
2364 if (level == 2)
2366 PRINTER_INFO_2A *pi_2 = (PRINTER_INFO_2A *)buf;
2368 ok(pi_2->pPrinterName!= NULL, "not expected NULL ptr\n");
2369 ok(pi_2->pDriverName!= NULL, "not expected NULL ptr\n");
2371 trace("pPrinterName %s\n", pi_2->pPrinterName);
2372 trace("pDriverName %s\n", pi_2->pDriverName);
2375 HeapFree(GetProcessHeap(), 0, buf);
2378 SetLastError(0xdeadbeef);
2379 ret = ClosePrinter(hprn);
2380 ok(ret, "ClosePrinter error %d\n", GetLastError());
2383 /* ########################### */
2385 static void test_GetPrinterData(void)
2387 HANDLE hprn = 0;
2388 DWORD res;
2389 DWORD type;
2390 CHAR buffer[MAX_PATH + 1];
2391 DWORD needed;
2392 DWORD len;
2394 /* ToDo: test parameter validation, test with the default printer */
2396 SetLastError(0xdeadbeef);
2397 res = OpenPrinterA(NULL, &hprn, NULL);
2398 if (!res)
2400 return;
2403 memset(buffer, '#', sizeof(buffer));
2404 buffer[MAX_PATH] = 0;
2405 type = 0xdeadbeef;
2406 needed = 0xdeadbeef;
2407 SetLastError(0xdeadbeef);
2408 res = GetPrinterDataA(hprn, defaultspooldirectory, &type, (LPBYTE) buffer, sizeof(buffer), &needed);
2410 len = lstrlenA(buffer) + sizeof(CHAR);
2411 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2412 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2413 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2414 res, type, needed, buffer, len);
2416 needed = 0xdeadbeef;
2417 SetLastError(0xdeadbeef);
2418 res = GetPrinterDataA(hprn, defaultspooldirectory, NULL, NULL, 0, &needed);
2419 ok( (res == ERROR_MORE_DATA) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2420 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2422 /* ToDo: test SPLREG_* */
2424 SetLastError(0xdeadbeef);
2425 res = ClosePrinter(hprn);
2426 ok(res, "ClosePrinter error %d\n", GetLastError());
2429 /* ########################### */
2431 static void test_GetPrinterDataEx(void)
2433 HANDLE hprn = 0;
2434 DWORD res;
2435 DWORD type;
2436 CHAR buffer[MAX_PATH + 1];
2437 DWORD needed;
2438 DWORD len;
2440 /* not present before w2k */
2441 if (!pGetPrinterDataExA) {
2442 win_skip("GetPrinterDataEx not found\n");
2443 return;
2446 /* ToDo: test parameter validation, test with the default printer */
2448 SetLastError(0xdeadbeef);
2449 res = OpenPrinterA(NULL, &hprn, NULL);
2450 if (!res)
2452 win_skip("Unable to open the printserver: %d\n", GetLastError());
2453 return;
2456 /* keyname is ignored, when hprn is a HANDLE for a printserver */
2457 memset(buffer, '#', sizeof(buffer));
2458 buffer[MAX_PATH] = 0;
2459 type = 0xdeadbeef;
2460 needed = 0xdeadbeef;
2461 SetLastError(0xdeadbeef);
2462 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, &type,
2463 (LPBYTE) buffer, sizeof(buffer), &needed);
2465 len = lstrlenA(buffer) + sizeof(CHAR);
2466 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2467 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2468 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2469 res, type, needed, buffer, len);
2471 memset(buffer, '#', sizeof(buffer));
2472 buffer[MAX_PATH] = 0;
2473 type = 0xdeadbeef;
2474 needed = 0xdeadbeef;
2475 SetLastError(0xdeadbeef);
2476 res = pGetPrinterDataExA(hprn, "", defaultspooldirectory, &type,
2477 (LPBYTE) buffer, sizeof(buffer), &needed);
2478 len = lstrlenA(buffer) + sizeof(CHAR);
2479 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2480 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2481 res, type, needed, buffer, len);
2483 memset(buffer, '#', sizeof(buffer));
2484 buffer[MAX_PATH] = 0;
2485 type = 0xdeadbeef;
2486 needed = 0xdeadbeef;
2487 SetLastError(0xdeadbeef);
2488 /* Wine uses GetPrinterDataEx with "PrinterDriverData" to implement GetPrinterData */
2489 res = pGetPrinterDataExA(hprn, "PrinterDriverData", defaultspooldirectory,
2490 &type, (LPBYTE) buffer, sizeof(buffer), &needed);
2491 len = lstrlenA(buffer) + sizeof(CHAR);
2492 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2493 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2494 res, type, needed, buffer, len);
2497 memset(buffer, '#', sizeof(buffer));
2498 buffer[MAX_PATH] = 0;
2499 type = 0xdeadbeef;
2500 needed = 0xdeadbeef;
2501 SetLastError(0xdeadbeef);
2502 res = pGetPrinterDataExA(hprn, does_not_exist, defaultspooldirectory, &type,
2503 (LPBYTE) buffer, sizeof(buffer), &needed);
2504 len = lstrlenA(buffer) + sizeof(CHAR);
2505 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2506 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2507 res, type, needed, buffer, len);
2509 needed = 0xdeadbeef;
2510 SetLastError(0xdeadbeef);
2511 /* vista and w2k8 have a bug in GetPrinterDataEx:
2512 the current LastError value is returned as result */
2513 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, NULL, NULL, 0, &needed);
2514 ok( ((res == ERROR_MORE_DATA) || broken(res == 0xdeadbeef)) &&
2515 ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2516 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2518 needed = 0xdeadbeef;
2519 SetLastError(0xdeaddead);
2520 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, NULL, NULL, 0, &needed);
2521 ok( ((res == ERROR_MORE_DATA) || broken(res == 0xdeaddead)) &&
2522 ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2523 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2525 SetLastError(0xdeadbeef);
2526 res = ClosePrinter(hprn);
2527 ok(res, "ClosePrinter error %d\n", GetLastError());
2530 /* ########################### */
2532 static void test_GetPrinterDriver(void)
2534 HANDLE hprn;
2535 BOOL ret;
2536 BYTE *buf;
2537 INT level;
2538 DWORD needed, filled;
2540 if (!default_printer)
2542 skip("There is no default printer installed\n");
2543 return;
2546 hprn = 0;
2547 ret = OpenPrinterA(default_printer, &hprn, NULL);
2548 if (!ret)
2550 skip("Unable to open the default printer (%s)\n", default_printer);
2551 return;
2553 ok(hprn != 0, "wrong hprn %p\n", hprn);
2555 for (level = -1; level <= 7; level++)
2557 SetLastError(0xdeadbeef);
2558 needed = (DWORD)-1;
2559 ret = GetPrinterDriverA(hprn, NULL, level, NULL, 0, &needed);
2560 ok(!ret, "level %d: GetPrinterDriver should fail\n", level);
2561 if (level >= 1 && level <= 6)
2563 /* Not all levels are supported on all Windows-Versions */
2564 if(GetLastError() == ERROR_INVALID_LEVEL) continue;
2565 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
2566 ok(needed > 0,"not expected needed buffer size %d\n", needed);
2568 else
2570 /* ERROR_OUTOFMEMORY found on win9x */
2571 ok( ((GetLastError() == ERROR_INVALID_LEVEL) ||
2572 (GetLastError() == ERROR_OUTOFMEMORY)),
2573 "%d: returned %d with %d (expected '0' with: "
2574 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
2575 level, ret, GetLastError());
2576 /* needed is modified in win9x. The modified Value depends on the
2577 default Printer. testing for "needed == (DWORD)-1" will fail */
2578 continue;
2581 /* GetPrinterDriverA returns the same number of bytes as GetPrinterDriverW */
2582 if (!ret && pGetPrinterDriverW)
2584 DWORD double_needed;
2585 ret = pGetPrinterDriverW(hprn, NULL, level, NULL, 0, &double_needed);
2586 ok(!ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
2587 ok(double_needed == needed, "GetPrinterDriverA returned different size %d than GetPrinterDriverW (%d)\n", needed, double_needed);
2590 buf = HeapAlloc(GetProcessHeap(), 0, needed);
2592 SetLastError(0xdeadbeef);
2593 filled = -1;
2594 ret = GetPrinterDriverA(hprn, NULL, level, buf, needed, &filled);
2595 ok(ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
2596 ok(needed == filled, "needed %d != filled %d\n", needed, filled);
2598 if (level == 2)
2600 DRIVER_INFO_2A *di_2 = (DRIVER_INFO_2A *)buf;
2601 DWORD calculated = sizeof(*di_2);
2602 HANDLE hf;
2604 /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
2605 NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k-win7(Usermode): 3, win8 and above(Usermode): 4 */
2606 ok( (di_2->cVersion <= 4) ||
2607 (di_2->cVersion == 0x0400), "di_2->cVersion = %d\n", di_2->cVersion);
2608 ok(di_2->pName != NULL, "not expected NULL ptr\n");
2609 ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n");
2610 ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n");
2611 ok(di_2->pDataFile != NULL, "not expected NULL ptr\n");
2612 ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n");
2614 trace("cVersion %d\n", di_2->cVersion);
2615 trace("pName %s\n", di_2->pName);
2616 calculated += strlen(di_2->pName) + 1;
2617 trace("pEnvironment %s\n", di_2->pEnvironment);
2618 calculated += strlen(di_2->pEnvironment) + 1;
2619 trace("pDriverPath %s\n", di_2->pDriverPath);
2620 calculated += strlen(di_2->pDriverPath) + 1;
2621 trace("pDataFile %s\n", di_2->pDataFile);
2622 calculated += strlen(di_2->pDataFile) + 1;
2623 trace("pConfigFile %s\n", di_2->pConfigFile);
2624 calculated += strlen(di_2->pConfigFile) + 1;
2626 hf = CreateFileA(di_2->pDriverPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2627 if(hf != INVALID_HANDLE_VALUE)
2628 CloseHandle(hf);
2629 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pDriverPath);
2631 hf = CreateFileA(di_2->pDataFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2632 if(hf != INVALID_HANDLE_VALUE)
2633 CloseHandle(hf);
2634 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pDataFile);
2636 hf = CreateFileA(di_2->pConfigFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2637 if(hf != INVALID_HANDLE_VALUE)
2638 CloseHandle(hf);
2639 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pConfigFile);
2641 /* XP allocates memory for both ANSI and unicode names */
2642 ok(filled >= calculated,"calculated %d != filled %d\n", calculated, filled);
2644 /* Obscure test - demonstrate that Windows zero fills the buffer, even on failure */
2645 ret = GetPrinterDriverA(hprn, NULL, level, buf, needed - 2, &filled);
2646 ok(!ret, "level %d: GetPrinterDriver succeeded with less buffer than it should\n", level);
2647 ok(di_2->pDataFile == NULL ||
2648 broken(di_2->pDataFile != NULL), /* Win9x/WinMe */
2649 "Even on failure, GetPrinterDriver clears the buffer to zeros\n");
2652 HeapFree(GetProcessHeap(), 0, buf);
2655 SetLastError(0xdeadbeef);
2656 ret = ClosePrinter(hprn);
2657 ok(ret, "ClosePrinter error %d\n", GetLastError());
2660 static void test_DEVMODEA(const DEVMODEA *dm, LONG dmSize, LPCSTR exp_prn_name)
2662 /* On NT3.51, some fields in DEVMODEA are empty/zero
2663 (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
2664 We skip the Tests on this Platform */
2665 if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) {
2666 /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
2667 ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1) ||
2668 !strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -2), /* XP+ */
2669 "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName);
2670 ok(dm->dmSize + dm->dmDriverExtra == dmSize,
2671 "%u != %d\n", dm->dmSize + dm->dmDriverExtra, dmSize);
2673 trace("dmFields %08x\n", dm->dmFields);
2676 static void test_DocumentProperties(void)
2678 HANDLE hprn;
2679 LONG dm_size, ret;
2680 DEVMODEA *dm;
2681 char empty_str[] = "";
2683 if (!default_printer)
2685 skip("There is no default printer installed\n");
2686 return;
2689 hprn = 0;
2690 ret = OpenPrinterA(default_printer, &hprn, NULL);
2691 if (!ret)
2693 skip("Unable to open the default printer (%s)\n", default_printer);
2694 return;
2696 ok(hprn != 0, "wrong hprn %p\n", hprn);
2698 dm_size = DocumentPropertiesA(0, hprn, NULL, NULL, NULL, 0);
2699 trace("DEVMODEA required size %d\n", dm_size);
2700 ok(dm_size >= sizeof(DEVMODEA), "unexpected DocumentPropertiesA ret value %d\n", dm_size);
2702 dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
2704 ret = DocumentPropertiesA(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
2705 ok(ret == IDOK, "DocumentPropertiesA ret value %d != expected IDOK\n", ret);
2707 ret = DocumentPropertiesA(0, hprn, empty_str, dm, dm, DM_OUT_BUFFER);
2708 ok(ret == IDOK, "DocumentPropertiesA ret value %d != expected IDOK\n", ret);
2710 test_DEVMODEA(dm, dm_size, default_printer);
2712 HeapFree(GetProcessHeap(), 0, dm);
2714 SetLastError(0xdeadbeef);
2715 ret = ClosePrinter(hprn);
2716 ok(ret, "ClosePrinter error %d\n", GetLastError());
2719 static void test_EnumPrinters(void)
2721 DWORD neededA, neededW, num;
2722 DWORD ret;
2724 SetLastError(0xdeadbeef);
2725 neededA = -1;
2726 ret = EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededA, &num);
2727 if (is_spooler_deactivated(ret, GetLastError())) return;
2728 if (!ret)
2730 /* We have 1 or more printers */
2731 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "gle %d\n", GetLastError());
2732 ok(neededA > 0, "Expected neededA to show the number of needed bytes\n");
2734 else
2736 /* We don't have any printers defined */
2737 ok(GetLastError() == S_OK, "gle %d\n", GetLastError());
2738 ok(neededA == 0, "Expected neededA to be zero\n");
2740 ok(num == 0, "num %d\n", num);
2742 SetLastError(0xdeadbeef);
2743 neededW = -1;
2744 ret = EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededW, &num);
2745 /* EnumPrintersW is not supported on all platforms */
2746 if (!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2748 win_skip("EnumPrintersW is not implemented\n");
2749 return;
2752 if (!ret)
2754 /* We have 1 or more printers */
2755 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "gle %d\n", GetLastError());
2756 ok(neededW > 0, "Expected neededW to show the number of needed bytes\n");
2758 else
2760 /* We don't have any printers defined */
2761 ok(GetLastError() == S_OK, "gle %d\n", GetLastError());
2762 ok(neededW == 0, "Expected neededW to be zero\n");
2764 ok(num == 0, "num %d\n", num);
2766 /* Outlook2003 relies on the buffer size returned by EnumPrintersA being big enough
2767 to hold the buffer returned by EnumPrintersW */
2768 ok(neededA == neededW, "neededA %d neededW %d\n", neededA, neededW);
2771 static void test_DeviceCapabilities(void)
2773 HANDLE hComdlg32;
2774 BOOL (WINAPI *pPrintDlgA)(PRINTDLGA *);
2775 PRINTDLGA prn_dlg;
2776 DEVMODEA *dm;
2777 DEVNAMES *dn;
2778 const char *driver, *device, *port;
2779 WORD *papers;
2780 POINT *paper_size;
2781 POINTS ext;
2782 struct
2784 char name[64];
2785 } *paper_name;
2786 INT n_papers, n_paper_size, n_paper_names, n_copies, ret;
2787 DWORD fields;
2789 hComdlg32 = LoadLibraryA("comdlg32.dll");
2790 assert(hComdlg32);
2791 pPrintDlgA = (void *)GetProcAddress(hComdlg32, "PrintDlgA");
2792 assert(pPrintDlgA);
2794 memset(&prn_dlg, 0, sizeof(prn_dlg));
2795 prn_dlg.lStructSize = sizeof(prn_dlg);
2796 prn_dlg.Flags = PD_RETURNDEFAULT;
2797 ret = pPrintDlgA(&prn_dlg);
2798 FreeLibrary(hComdlg32);
2799 if (!ret)
2801 skip("PrintDlg returned no default printer\n");
2802 return;
2804 ok(prn_dlg.hDevMode != 0, "PrintDlg returned hDevMode == NULL\n");
2805 ok(prn_dlg.hDevNames != 0, "PrintDlg returned hDevNames == NULL\n");
2807 dm = GlobalLock(prn_dlg.hDevMode);
2808 ok(dm != NULL, "GlobalLock(prn_dlg.hDevMode) failed\n");
2809 trace("dmDeviceName \"%s\"\n", dm->dmDeviceName);
2811 dn = GlobalLock(prn_dlg.hDevNames);
2812 ok(dn != NULL, "GlobalLock(prn_dlg.hDevNames) failed\n");
2813 ok(dn->wDriverOffset, "expected not 0 wDriverOffset\n");
2814 ok(dn->wDeviceOffset, "expected not 0 wDeviceOffset\n");
2815 ok(dn->wOutputOffset, "expected not 0 wOutputOffset\n");
2816 ok(dn->wDefault == DN_DEFAULTPRN, "expected DN_DEFAULTPRN got %x\n", dn->wDefault);
2817 driver = (const char *)dn + dn->wDriverOffset;
2818 device = (const char *)dn + dn->wDeviceOffset;
2819 port = (const char *)dn + dn->wOutputOffset;
2820 trace("driver \"%s\" device \"%s\" port \"%s\"\n", driver, device, port);
2822 test_DEVMODEA(dm, dm->dmSize + dm->dmDriverExtra, device);
2824 n_papers = DeviceCapabilitiesA(device, port, DC_PAPERS, NULL, NULL);
2825 ok(n_papers > 0, "DeviceCapabilitiesA DC_PAPERS failed\n");
2826 papers = HeapAlloc(GetProcessHeap(), 0, sizeof(*papers) * n_papers);
2827 ret = DeviceCapabilitiesA(device, port, DC_PAPERS, (LPSTR)papers, NULL);
2828 ok(ret == n_papers, "expected %d, got %d\n", n_papers, ret);
2829 #ifdef VERBOSE
2830 for (ret = 0; ret < n_papers; ret++)
2831 trace("papers[%d] = %d\n", ret, papers[ret]);
2832 #endif
2833 HeapFree(GetProcessHeap(), 0, papers);
2835 n_paper_size = DeviceCapabilitiesA(device, port, DC_PAPERSIZE, NULL, NULL);
2836 ok(n_paper_size > 0, "DeviceCapabilitiesA DC_PAPERSIZE failed\n");
2837 ok(n_paper_size == n_papers, "n_paper_size %d != n_papers %d\n", n_paper_size, n_papers);
2838 paper_size = HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_size) * n_paper_size);
2839 ret = DeviceCapabilitiesA(device, port, DC_PAPERSIZE, (LPSTR)paper_size, NULL);
2840 ok(ret == n_paper_size, "expected %d, got %d\n", n_paper_size, ret);
2841 #ifdef VERBOSE
2842 for (ret = 0; ret < n_paper_size; ret++)
2843 trace("paper_size[%d] = %d x %d\n", ret, paper_size[ret].x, paper_size[ret].y);
2844 #endif
2845 HeapFree(GetProcessHeap(), 0, paper_size);
2847 n_paper_names = DeviceCapabilitiesA(device, port, DC_PAPERNAMES, NULL, NULL);
2848 ok(n_paper_names > 0, "DeviceCapabilitiesA DC_PAPERNAMES failed\n");
2849 ok(n_paper_names == n_papers, "n_paper_names %d != n_papers %d\n", n_paper_names, n_papers);
2850 paper_name = HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_name) * n_paper_names);
2851 ret = DeviceCapabilitiesA(device, port, DC_PAPERNAMES, (LPSTR)paper_name, NULL);
2852 ok(ret == n_paper_names, "expected %d, got %d\n", n_paper_names, ret);
2853 #ifdef VERBOSE
2854 for (ret = 0; ret < n_paper_names; ret++)
2855 trace("paper_name[%u] = %s\n", ret, paper_name[ret].name);
2856 #endif
2857 HeapFree(GetProcessHeap(), 0, paper_name);
2859 n_copies = DeviceCapabilitiesA(device, port, DC_COPIES, NULL, dm);
2860 ok(n_copies > 0, "DeviceCapabilitiesA DC_COPIES failed\n");
2861 trace("n_copies = %d\n", n_copies);
2863 /* these capabilities are not available on all printer drivers */
2864 if (0)
2866 ret = DeviceCapabilitiesA(device, port, DC_MAXEXTENT, NULL, NULL);
2867 ok(ret != -1, "DeviceCapabilitiesA DC_MAXEXTENT failed\n");
2868 ext = MAKEPOINTS(ret);
2869 trace("max ext = %d x %d\n", ext.x, ext.y);
2871 ret = DeviceCapabilitiesA(device, port, DC_MINEXTENT, NULL, NULL);
2872 ok(ret != -1, "DeviceCapabilitiesA DC_MINEXTENT failed\n");
2873 ext = MAKEPOINTS(ret);
2874 trace("min ext = %d x %d\n", ext.x, ext.y);
2877 fields = DeviceCapabilitiesA(device, port, DC_FIELDS, NULL, NULL);
2878 ok(fields != (DWORD)-1, "DeviceCapabilitiesA DC_FIELDS failed\n");
2879 ok(fields == (dm->dmFields | DM_FORMNAME) ||
2880 fields == ((dm->dmFields | DM_FORMNAME | DM_PAPERSIZE) & ~(DM_PAPERLENGTH|DM_PAPERWIDTH)) ||
2881 broken(fields == dm->dmFields), /* Win9x/WinMe */
2882 "fields %x, dm->dmFields %x\n", fields, dm->dmFields);
2884 GlobalUnlock(prn_dlg.hDevMode);
2885 GlobalFree(prn_dlg.hDevMode);
2886 GlobalUnlock(prn_dlg.hDevNames);
2887 GlobalFree(prn_dlg.hDevNames);
2890 static void test_OpenPrinter_defaults(void)
2892 HANDLE printer;
2893 BOOL ret;
2894 DWORD needed;
2895 short default_size;
2896 ADDJOB_INFO_1A *add_job;
2897 JOB_INFO_2A *job_info;
2898 DEVMODEA my_dm;
2899 PRINTER_DEFAULTSA prn_def;
2900 PRINTER_INFO_2A *pi;
2902 if (!default_printer)
2904 skip("There is no default printer installed\n");
2905 return;
2908 /* Printer opened with NULL defaults. Retrieve default paper size
2909 and confirm that jobs have this size. */
2911 ret = OpenPrinterA( default_printer, &printer, NULL );
2912 if (!ret)
2914 skip("Unable to open the default printer (%s)\n", default_printer);
2915 return;
2918 ret = GetPrinterA( printer, 2, NULL, 0, &needed );
2919 ok( !ret, "got %d\n", ret );
2920 pi = HeapAlloc( GetProcessHeap(), 0, needed );
2921 ret = GetPrinterA( printer, 2, (BYTE *)pi, needed, &needed );
2922 ok( ret, "GetPrinterA() failed le=%d\n", GetLastError() );
2923 default_size = pi->pDevMode->u1.s1.dmPaperSize;
2924 HeapFree( GetProcessHeap(), 0, pi );
2926 needed = 0;
2927 SetLastError( 0xdeadbeef );
2928 ret = AddJobA( printer, 1, NULL, 0, &needed );
2929 ok( !ret, "got %d\n", ret );
2930 if (GetLastError() == ERROR_NOT_SUPPORTED) /* win8 */
2932 win_skip( "AddJob is not supported on this platform\n" );
2933 ClosePrinter( printer );
2934 return;
2936 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError() );
2937 ok( needed > sizeof(ADDJOB_INFO_1A), "AddJob needs %u bytes\n", needed);
2938 add_job = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, needed );
2939 ret = AddJobA( printer, 1, (BYTE *)add_job, needed, &needed );
2940 ok( ret, "AddJobA() failed le=%d\n", GetLastError() );
2942 ret = GetJobA( printer, add_job->JobId, 2, NULL, 0, &needed );
2943 ok( !ret, "got %d\n", ret );
2944 job_info = HeapAlloc( GetProcessHeap(), 0, needed );
2945 ret = GetJobA( printer, add_job->JobId, 2, (BYTE *)job_info, needed, &needed );
2946 ok( ret, "GetJobA() failed le=%d\n", GetLastError() );
2948 todo_wine
2949 ok( job_info->pDevMode != NULL, "got NULL DEVMODEA\n");
2950 if (job_info->pDevMode)
2951 ok( job_info->pDevMode->u1.s1.dmPaperSize == default_size, "got %d default %d\n",
2952 job_info->pDevMode->u1.s1.dmPaperSize, default_size );
2954 HeapFree( GetProcessHeap(), 0, job_info );
2955 ScheduleJob( printer, add_job->JobId ); /* remove the empty job */
2956 HeapFree( GetProcessHeap(), 0, add_job );
2957 ClosePrinter( printer );
2959 /* Printer opened with something other than the default paper size. */
2961 memset( &my_dm, 0, sizeof(my_dm) );
2962 my_dm.dmSize = sizeof(my_dm);
2963 my_dm.dmFields = DM_PAPERSIZE;
2964 my_dm.u1.s1.dmPaperSize = (default_size == DMPAPER_A4) ? DMPAPER_LETTER : DMPAPER_A4;
2966 prn_def.pDatatype = NULL;
2967 prn_def.pDevMode = &my_dm;
2968 prn_def.DesiredAccess = PRINTER_ACCESS_USE;
2970 ret = OpenPrinterA( default_printer, &printer, &prn_def );
2971 ok( ret, "OpenPrinterA() failed le=%d\n", GetLastError() );
2973 /* GetPrinter stills returns default size */
2974 ret = GetPrinterA( printer, 2, NULL, 0, &needed );
2975 ok( !ret, "got %d\n", ret );
2976 pi = HeapAlloc( GetProcessHeap(), 0, needed );
2977 ret = GetPrinterA( printer, 2, (BYTE *)pi, needed, &needed );
2978 ok( ret, "GetPrinterA() failed le=%d\n", GetLastError() );
2979 ok( pi->pDevMode->u1.s1.dmPaperSize == default_size, "got %d default %d\n",
2980 pi->pDevMode->u1.s1.dmPaperSize, default_size );
2982 HeapFree( GetProcessHeap(), 0, pi );
2984 /* However the GetJobA has the new size */
2985 ret = AddJobA( printer, 1, NULL, 0, &needed );
2986 ok( !ret, "got %d\n", ret );
2987 add_job = HeapAlloc( GetProcessHeap(), 0, needed );
2988 ret = AddJobA( printer, 1, (BYTE *)add_job, needed, &needed );
2989 ok( ret, "AddJobA() failed le=%d\n", GetLastError() );
2991 ret = GetJobA( printer, add_job->JobId, 2, NULL, 0, &needed );
2992 ok( !ret, "got %d\n", ret );
2993 job_info = HeapAlloc( GetProcessHeap(), 0, needed );
2994 ret = GetJobA( printer, add_job->JobId, 2, (BYTE *)job_info, needed, &needed );
2995 ok( ret, "GetJobA() failed le=%d\n", GetLastError() );
2997 ok( job_info->pDevMode->dmFields == DM_PAPERSIZE, "got %08x\n",
2998 job_info->pDevMode->dmFields );
2999 ok( job_info->pDevMode->u1.s1.dmPaperSize == my_dm.u1.s1.dmPaperSize,
3000 "got %d new size %d\n",
3001 job_info->pDevMode->u1.s1.dmPaperSize, my_dm.u1.s1.dmPaperSize );
3003 HeapFree( GetProcessHeap(), 0, job_info );
3004 ScheduleJob( printer, add_job->JobId ); /* remove the empty job */
3005 HeapFree( GetProcessHeap(), 0, add_job );
3006 ClosePrinter( printer );
3009 static void test_IsValidDevmodeW(void)
3011 static const struct
3013 DWORD dmFields;
3014 WORD dmSize;
3015 BOOL ret;
3016 } test[] =
3018 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 0, FALSE },
3019 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 1, FALSE },
3020 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 2, FALSE },
3021 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 3, FALSE },
3022 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 4, TRUE },
3024 { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 0, FALSE },
3025 { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 1, FALSE },
3026 { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 2, TRUE },
3028 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 0, FALSE },
3029 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 1, FALSE },
3030 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 2, FALSE },
3031 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 3, FALSE },
3032 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 4, TRUE },
3035 DEVMODEW dm;
3036 int i;
3037 BOOL ret;
3039 ret = IsValidDevmodeW(NULL, 0);
3040 ok(!ret, "got %d\n", ret);
3042 ret = IsValidDevmodeW(NULL, sizeof(DEVMODEW));
3043 ok(!ret, "got %d\n", ret);
3045 memset(&dm, 0, sizeof(dm));
3047 for (i = 0; i < ARRAY_SIZE(test); i++)
3049 dm.dmSize = test[i].dmSize;
3050 dm.dmFields = test[i].dmFields;
3051 ret = IsValidDevmodeW(&dm, dm.dmSize);
3052 ok(ret == test[i].ret, "%d: got %d\n", i, ret);
3056 START_TEST(info)
3058 hwinspool = LoadLibraryA("winspool.drv");
3059 pAddPortExA = (void *) GetProcAddress(hwinspool, "AddPortExA");
3060 pEnumPrinterDriversW = (void *) GetProcAddress(hwinspool, "EnumPrinterDriversW");
3061 pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
3062 pGetPrinterDataExA = (void *) GetProcAddress(hwinspool, "GetPrinterDataExA");
3063 pGetPrinterDriverW = (void *) GetProcAddress(hwinspool, "GetPrinterDriverW");
3064 pGetPrinterW = (void *) GetProcAddress(hwinspool, "GetPrinterW");
3065 pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
3066 pXcvDataW = (void *) GetProcAddress(hwinspool, "XcvDataW");
3068 find_default_printer();
3069 find_local_server();
3070 find_tempfile();
3072 test_AddMonitor();
3073 test_AddPort();
3074 test_AddPortEx();
3075 test_ConfigurePort();
3076 test_ClosePrinter();
3077 test_DeleteMonitor();
3078 test_DeletePort();
3079 test_DeviceCapabilities();
3080 test_DocumentProperties();
3081 test_EnumForms(NULL);
3082 if (default_printer) test_EnumForms(default_printer);
3083 test_EnumMonitors();
3084 test_EnumPorts();
3085 test_EnumPrinterDrivers();
3086 test_EnumPrinters();
3087 test_EnumPrintProcessors();
3088 test_GetDefaultPrinter();
3089 test_GetPrinterDriverDirectory();
3090 test_GetPrintProcessorDirectory();
3091 test_IsValidDevmodeW();
3092 test_OpenPrinter();
3093 test_OpenPrinter_defaults();
3094 test_GetPrinter();
3095 test_GetPrinterData();
3096 test_GetPrinterDataEx();
3097 test_GetPrinterDriver();
3098 test_SetDefaultPrinter();
3099 test_XcvDataW_MonitorUI();
3100 test_XcvDataW_PortIsValid();
3102 /* Cleanup our temporary file */
3103 DeleteFileA(tempfileA);