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