2526cd738338925eb4546ece137175124049c18b
[reactos.git] / modules / rostests / winetests / winspool / info.c
1 /*
2 * Copyright (C) 2003, 2004 Stefan Leichter
3 * Copyright (C) 2005, 2006 Detlef Riekenberg
4 * Copyright (C) 2006 Dmitry Timoshkov
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <stdarg.h>
22 #include <assert.h>
23
24 #define NONAMELESSSTRUCT
25 #define NONAMELESSUNION
26
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"
37
38 #define MAGIC_DEAD 0xdeadbeef
39 #define DEFAULT_PRINTER_SIZE 1000
40
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";
58
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};
62
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};
68
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);
79
80
81 /* ################################ */
82
83 struct monitor_entry {
84 LPSTR env;
85 CHAR dllname[32];
86 };
87
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;
94
95 static BOOL is_spooler_deactivated(DWORD res, DWORD lasterror)
96 {
97 if (!res && lasterror == RPC_S_SERVER_UNAVAILABLE)
98 {
99 static int deactivated_spooler_reported = 0;
100 if (!deactivated_spooler_reported)
101 {
102 deactivated_spooler_reported = 1;
103 skip("The service 'Spooler' is required for many tests\n");
104 }
105 return TRUE;
106 }
107 return FALSE;
108 }
109
110 static BOOL is_access_denied(DWORD res, DWORD lasterror)
111 {
112 if (!res && lasterror == ERROR_ACCESS_DENIED)
113 {
114 static int access_denied_reported = 0;
115 if (!access_denied_reported)
116 {
117 access_denied_reported = 1;
118 skip("More access rights are required for many tests\n");
119 }
120 return TRUE;
121 }
122 return FALSE;
123 }
124
125 static BOOL on_win9x = FALSE;
126
127 static BOOL check_win9x(void)
128 {
129 if (pGetPrinterW)
130 {
131 SetLastError(0xdeadbeef);
132 pGetPrinterW(NULL, 0, NULL, 0, NULL);
133 return (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED);
134 }
135 else
136 {
137 return TRUE;
138 }
139 }
140
141 static void find_default_printer(VOID)
142 {
143 static char buffer[DEFAULT_PRINTER_SIZE];
144 DWORD needed;
145 DWORD res;
146 LPSTR ptr;
147
148 if ((default_printer == NULL) && (pGetDefaultPrinterA))
149 {
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)");
155 }
156 if (default_printer == NULL)
157 {
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) {
164
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;
171 }
172 }
173 RegCloseKey(hwindows);
174 }
175 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
176 }
177 if (default_printer == NULL)
178 {
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;
187 }
188 }
189 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
190 }
191 }
192
193
194 static struct monitor_entry * find_installed_monitor(void)
195 {
196 MONITOR_INFO_2A mi2a;
197 static struct monitor_entry * entry = NULL;
198 DWORD num_tests;
199 DWORD i = 0;
200
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"},
218 };
219
220 if (entry) return entry;
221
222 num_tests = (sizeof(monitor_table)/sizeof(struct monitor_entry));
223
224 /* cleanup */
225 DeleteMonitorA(NULL, env_x64, winetest);
226 DeleteMonitorA(NULL, env_x86, winetest);
227 DeleteMonitorA(NULL, env_win9x_case, winetest);
228
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;
236
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);
241 }
242 else
243 {
244 entry = NULL;
245 }
246 }
247 return entry;
248 }
249
250
251 /* ########################### */
252
253 static void find_local_server(VOID)
254 {
255 static char buffer[MAX_PATH];
256 DWORD res;
257 DWORD size;
258
259 size = sizeof(buffer) - 3 ;
260 buffer[0] = '\\';
261 buffer[1] = '\\';
262 buffer[2] = '\0';
263
264 SetLastError(0xdeadbeef);
265 res = GetComputerNameA(&buffer[2], &size);
266 trace("returned %d with %d and %d: '%s'\n", res, GetLastError(), size, buffer);
267
268 ok( res != 0, "returned %d with %d and %d: '%s' (expected '!= 0')\n",
269 res, GetLastError(), size, buffer);
270
271 if (res) local_server = buffer;
272 }
273
274 /* ########################### */
275
276 static void find_tempfile(VOID)
277 {
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;
284
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;
291
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;
298
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;
303
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;
308
309 tempdirA = buffer_dirA;
310 tempfileA = buffer_fileA;
311 tempdirW = buffer_dirW;
312 tempfileW = buffer_fileW;
313 trace("tempfile: '%s'\n", tempfileA);
314 }
315
316 /* ########################### */
317
318 static void test_AddMonitor(void)
319 {
320 MONITOR_INFO_2A mi2a;
321 struct monitor_entry * entry = NULL;
322 DWORD res;
323
324 entry = find_installed_monitor();
325
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());
331
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());
337
338 if (0)
339 {
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());
349 }
350
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;
356
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());
362
363 if (!entry) {
364 skip("No usable Monitor found\n");
365 return;
366 }
367
368 if (0)
369 {
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. */
374
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 */
380 }
381
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());
393
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());
404
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());
411
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());
421
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);
432
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());
440
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());
451
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());
456
457 /* cleanup */
458 DeleteMonitorA(NULL, entry->env, winetest);
459
460 }
461
462 /* ########################### */
463
464 static void test_AddPort(void)
465 {
466 DWORD res;
467
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());
476
477
478 SetLastError(0xdeadbeef);
479 res = AddPortA(NULL, 0, empty);
480 /* Allowed only for (Printer-)Administrators */
481 if (is_access_denied(res, GetLastError())) return;
482
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());
488
489
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());
497
498 }
499
500 /* ########################### */
501
502 static void test_AddPortEx(void)
503 {
504 PORT_INFO_2A pi;
505 DWORD res;
506
507
508 if (!pAddPortExA) {
509 win_skip("AddPortEx not supported\n");
510 return;
511 }
512
513 /* start test with a clean system */
514 DeletePortA(NULL, 0, tempfileA);
515
516 pi.pPortName = tempfileA;
517 SetLastError(0xdeadbeef);
518 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
519 if (is_spooler_deactivated(res, GetLastError())) return;
520
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;
526 }
527 ok( res, "got %u with %u (expected '!= 0')\n", res, GetLastError());
528
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);
536
537
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);
545
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);
552
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);
559
560
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());
567
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);
575
576
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 */
580
581 pi.pPortName = tempfileA;
582 pi.pMonitorName = LocalPortA;
583 pi.pDescription = winetest;
584 pi.fPortType = PORT_TYPE_WRITE;
585
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);
592
593
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());
600
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());
606
607
608 /* cleanup */
609 DeletePortA(NULL, 0, tempfileA);
610
611 }
612
613 /* ########################### */
614
615 static void test_ConfigurePort(void)
616 {
617 DWORD res;
618
619
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());
628
629 SetLastError(0xdeadbeef);
630 res = ConfigurePortA(NULL, 0, empty);
631 /* Allowed only for (Printer-)Administrators */
632 if (is_access_denied(res, GetLastError())) return;
633
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());
639
640
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());
648
649
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
654
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
659 */
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());
664
665 SetLastError(0xdeadbeef);
666 res = ConfigurePortA(NULL, 0, portname_lpt1);
667 trace("'%s' returned %d with %d\n", portname_lpt1, res, GetLastError());
668
669 SetLastError(0xdeadbeef);
670 res = ConfigurePortA(NULL, 0, portname_file);
671 trace("'%s' returned %d with %d\n", portname_file, res, GetLastError());
672 }
673 }
674
675 /* ########################### */
676
677 static void test_ClosePrinter(void)
678 {
679 HANDLE printer = 0;
680 BOOL res;
681
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());
688
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());
696
697
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)
703 {
704 SetLastError(0xdeadbeef);
705 res = ClosePrinter(printer);
706 ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError());
707
708
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());
715
716 }
717 }
718
719 /* ########################### */
720
721 static void test_DeleteMonitor(void)
722 {
723 MONITOR_INFO_2A mi2a;
724 struct monitor_entry * entry = NULL;
725 DWORD res;
726
727
728 entry = find_installed_monitor();
729
730 if (!entry) {
731 skip("No usable Monitor found\n");
732 return;
733 }
734
735 mi2a.pName = winetest;
736 mi2a.pEnvironment = entry->env;
737 mi2a.pDLLName = entry->dllname;
738
739 /* Testing DeleteMonitor with real options */
740 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
741
742 SetLastError(MAGIC_DEAD);
743 res = DeleteMonitorA(NULL, entry->env, winetest);
744 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
745
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());
755
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());
761
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());
766
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());
772
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());
783
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());
793
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());
798
799 /* cleanup */
800 DeleteMonitorA(NULL, entry->env, winetest);
801 }
802
803 /* ########################### */
804
805 static void test_DeletePort(void)
806 {
807 DWORD res;
808
809 SetLastError(0xdeadbeef);
810 res = DeletePortA(NULL, 0, NULL);
811 if (is_spooler_deactivated(res, GetLastError())) return;
812
813 SetLastError(0xdeadbeef);
814 res = DeletePortA(NULL, 0, empty);
815 /* Allowed only for (Printer-)Administrators */
816 if (is_access_denied(res, GetLastError())) return;
817
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());
823
824
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());
832
833 }
834
835 /* ########################### */
836
837 static void test_EnumForms(LPSTR pName)
838 {
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;
852
853 res = OpenPrinterA(pName, &hprinter, NULL);
854 if (is_spooler_deactivated(res, GetLastError())) return;
855 if (!res || !hprinter)
856 {
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;
860 }
861
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);
868
869 /* EnumForms is not implemented on win9x */
870 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
871
872 /* EnumForms for the server is not implemented on all NT-versions */
873 if (!res && (GetLastError() == ERROR_INVALID_HANDLE) && !pName) continue;
874
875 /* Level 2 for EnumForms is not supported on all systems */
876 if (!res && (GetLastError() == ERROR_INVALID_LEVEL) && (level == 2)) continue;
877
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;
886 }
887
888 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
889 "(%d) returned %d with %d (expected '0' with "
890 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
891
892 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
893 if (buffer == NULL) continue;
894
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());
899
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++)
905 {
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);
910
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);
917
918 /* offset pointer pFI_1a by 1*sizeof(FORM_INFO_2A) Bytes */
919 pFI_2a ++;
920 pFI_1a = (PFORM_INFO_1A)pFI_2a;
921 }
922 }
923 }
924
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());
929
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());
935
936
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());
942
943
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());
949
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());
955
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());
961
962 HeapFree(GetProcessHeap(), 0, buffer);
963 } /* for(level ... */
964
965 ClosePrinter(hprinter);
966 }
967
968 /* ########################### */
969
970 static void test_EnumMonitors(void)
971 {
972 DWORD res;
973 LPBYTE buffer;
974 DWORD cbBuf;
975 DWORD pcbNeeded;
976 DWORD pcReturned;
977 DWORD level;
978
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;
988
989
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;
998 }
999
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;
1004 }
1005
1006 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1007 "(%d) returned %d with %d (expected '0' with "
1008 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1009
1010 if (!cbBuf) {
1011 skip("no valid buffer size returned\n");
1012 continue;
1013 }
1014
1015 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
1016 if (buffer == NULL) continue;
1017
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 */
1026
1027
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);
1036
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());
1043
1044 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
1045 pcbNeeded, cbBuf);
1046
1047 /*
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
1052
1053 res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1054 */
1055
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());
1063
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());
1071
1072 HeapFree(GetProcessHeap(), 0, buffer);
1073 } /* for(level ... */
1074 }
1075
1076 /* ########################### */
1077
1078 static void test_EnumPorts(void)
1079 {
1080 DWORD res;
1081 DWORD level;
1082 LPBYTE buffer;
1083 DWORD cbBuf;
1084 DWORD pcbNeeded;
1085 DWORD pcReturned;
1086
1087 /* valid levels are 1 and 2 */
1088 for(level = 0; level < 4; level++) {
1089
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;
1095
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;
1105 }
1106
1107
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;
1112 }
1113
1114 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1115 "(%d) returned %d with %d (expected '0' with "
1116 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1117
1118 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
1119 if (buffer == NULL) continue;
1120
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 */
1127
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);
1134
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);
1142
1143 /*
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
1149 */
1150
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());
1159
1160
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());
1169
1170 HeapFree(GetProcessHeap(), 0, buffer);
1171 }
1172 }
1173
1174 /* ########################### */
1175
1176 static void test_EnumPrinterDrivers(void)
1177 {
1178 static char env_all[] = "all";
1179
1180 DWORD res;
1181 LPBYTE buffer;
1182 DWORD cbBuf;
1183 DWORD pcbNeeded;
1184 DWORD pcReturned;
1185 DWORD level;
1186
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;
1194
1195 /* use only a short test when testing an invalid level */
1196 if(!level || (level == 7) || (level > 8)) {
1197
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;
1204 }
1205
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;
1210 }
1211
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);
1217
1218 if (!cbBuf) {
1219 skip("no valid buffer size returned\n");
1220 continue;
1221 }
1222
1223 /* EnumPrinterDriversA returns the same number of bytes as EnumPrinterDriversW */
1224 if (!on_win9x && pEnumPrinterDriversW)
1225 {
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);
1230 }
1231
1232 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4);
1233 if (buffer == NULL) continue;
1234
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);
1240
1241 /* validate the returned data here */
1242 if (level > 1) {
1243 LPDRIVER_INFO_2A di = (LPDRIVER_INFO_2A) buffer;
1244
1245 ok( strrchr(di->pDriverPath, '\\') != NULL,
1246 "(%u) got %s for %s (expected a full path)\n",
1247 level, di->pDriverPath, di->pName);
1248
1249 }
1250
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);
1257
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);
1265
1266 /*
1267 Do not add the next test:
1268 NT: ERROR_INVALID_USER_BUFFER
1269 win9x: crash or 100% CPU
1270
1271 res = EnumPrinterDriversA(NULL, NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1272 */
1273
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());
1281
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());
1289
1290 HeapFree(GetProcessHeap(), 0, buffer);
1291 } /* for(level ... */
1292
1293 pcbNeeded = 0;
1294 pcReturned = 0;
1295 SetLastError(0xdeadbeef);
1296 res = EnumPrinterDriversA(NULL, env_all, 1, NULL, 0, &pcbNeeded, &pcReturned);
1297 if (res)
1298 {
1299 skip("no printer drivers found\n");
1300 return;
1301 }
1302 if (GetLastError() == ERROR_INVALID_ENVIRONMENT)
1303 {
1304 win_skip("NT4 and below don't support the 'all' environment value\n");
1305 return;
1306 }
1307 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "unexpected error %u\n", GetLastError());
1308
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)
1313 {
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);
1319 }
1320
1321 HeapFree(GetProcessHeap(), 0, buffer);
1322 }
1323
1324 /* ########################### */
1325
1326 static void test_EnumPrintProcessors(void)
1327 {
1328 DWORD res;
1329 LPBYTE buffer;
1330 DWORD cbBuf;
1331 DWORD pcbNeeded;
1332 DWORD pcReturned;
1333
1334
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;
1340
1341 if (res && !cbBuf) {
1342 skip("No Printprocessor installed\n");
1343 return;
1344 }
1345
1346 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1347 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1348 res, GetLastError());
1349
1350 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4);
1351 if (buffer == NULL)
1352 return;
1353
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. */
1359
1360
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());
1366
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());
1373
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());
1384
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());
1391 }
1392
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());
1398
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());
1409
1410
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());
1421 }
1422
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());
1431
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());
1440
1441 HeapFree(GetProcessHeap(), 0, buffer);
1442
1443 }
1444
1445 /* ########################### */
1446
1447 static void test_GetDefaultPrinter(void)
1448 {
1449 BOOL retval;
1450 DWORD exact = DEFAULT_PRINTER_SIZE;
1451 DWORD size;
1452 char buffer[DEFAULT_PRINTER_SIZE];
1453
1454 if (!pGetDefaultPrinterA) return;
1455 /* only supported on NT like OSes starting with win2k */
1456
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);
1471 }
1472 return;
1473 }
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());
1480
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());
1487
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);
1497
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);
1507
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);
1516
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);
1522 }
1523
1524 static void test_GetPrinterDriverDirectory(void)
1525 {
1526 LPBYTE buffer = NULL;
1527 DWORD cbBuf = 0, pcbNeeded = 0;
1528 BOOL res;
1529
1530
1531 SetLastError(MAGIC_DEAD);
1532 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
1533 if (is_spooler_deactivated(res, GetLastError())) return;
1534
1535 trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
1536 res, GetLastError(), cbBuf);
1537
1538 ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1539 "returned %d with lasterror=%d (expected '0' with "
1540 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
1541
1542 if (!cbBuf) {
1543 skip("no valid buffer size returned\n");
1544 return;
1545 }
1546
1547 buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
1548 if (buffer == NULL) return ;
1549
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);
1554
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);
1559
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);
1565
1566 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
1567 "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
1568 GetLastError());
1569
1570 /*
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
1575
1576 pcbNeeded = MAGIC_DEAD;
1577 SetLastError(MAGIC_DEAD);
1578 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1579 */
1580
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());
1589
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());
1598
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);
1603
1604 /* Level not checked in win9x and wine:*/
1605 if((res != FALSE) && buffer[0])
1606 {
1607 trace("Level '2' not checked '%s'\n", buffer);
1608 }
1609 else
1610 {
1611 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
1612 "returned %d with lasterror=%d (expected '0' with "
1613 "ERROR_INVALID_LEVEL)\n", res, GetLastError());
1614 }
1615
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);
1622
1623 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
1624 cbBuf = pcbNeeded;
1625 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1626 if (buffer == NULL) return ;
1627
1628 SetLastError(MAGIC_DEAD);
1629 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1,
1630 buffer, cbBuf*2, &pcbNeeded);
1631 }
1632
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));
1636
1637 buffer[0] = '\0';
1638 SetLastError(MAGIC_DEAD);
1639 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1,
1640 buffer, cbBuf*2, &pcbNeeded);
1641
1642 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
1643 cbBuf = pcbNeeded;
1644 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1645 if (buffer == NULL) return ;
1646
1647 buffer[0] = '\0';
1648 SetLastError(MAGIC_DEAD);
1649 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1,
1650 buffer, cbBuf*2, &pcbNeeded);
1651 }
1652
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));
1659
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() );
1664
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() );
1668
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() );
1672
1673 HeapFree( GetProcessHeap(), 0, buffer);
1674 }
1675
1676 /* ##### */
1677
1678 static void test_GetPrintProcessorDirectory(void)
1679 {
1680 LPBYTE buffer = NULL;
1681 DWORD cbBuf = 0;
1682 DWORD pcbNeeded = 0;
1683 BOOL res;
1684
1685
1686 SetLastError(0xdeadbeef);
1687 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf);
1688 if (is_spooler_deactivated(res, GetLastError())) return;
1689
1690 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1691 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1692 res, GetLastError());
1693
1694 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2);
1695 if(buffer == NULL) return;
1696
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());
1701
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());
1706
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());
1714
1715 if (0)
1716 {
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());
1727 }
1728
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());
1738
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());
1748
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());
1758
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());
1767
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());
1773
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());
1779
1780
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());
1788
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());
1796
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());
1802
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());
1812
1813 HeapFree(GetProcessHeap(), 0, buffer);
1814 }
1815
1816 /* ##### */
1817
1818 static void test_OpenPrinter(void)
1819 {
1820 PRINTER_DEFAULTSA defaults;
1821 HANDLE hprinter;
1822 DWORD res;
1823
1824 SetLastError(MAGIC_DEAD);
1825 res = OpenPrinterA(NULL, NULL, NULL);
1826 if (is_spooler_deactivated(res, GetLastError())) return;
1827
1828 ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
1829 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1830 res, GetLastError());
1831
1832
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);
1843
1844 defaults.pDatatype=NULL;
1845 defaults.pDevMode=NULL;
1846
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);
1853
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());
1862 }
1863 if (res) ClosePrinter(hprinter);
1864
1865 }
1866
1867
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);
1876 }
1877
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);
1887
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);
1898
1899
1900 /* get handle for the default printer */
1901 if (default_printer)
1902 {
1903 hprinter = (HANDLE) MAGIC_DEAD;
1904 SetLastError(MAGIC_DEAD);
1905 res = OpenPrinterA(default_printer, &hprinter, NULL);
1906 if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
1907 {
1908 trace("The service 'Spooler' is required for '%s'\n", default_printer);
1909 return;
1910 }
1911 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1912 if(res) ClosePrinter(hprinter);
1913
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());
1920
1921 defaults.pDatatype=NULL;
1922 defaults.pDevMode=NULL;
1923 defaults.DesiredAccess=0;
1924
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);
1932
1933 defaults.pDatatype = empty;
1934
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);
1946
1947
1948 defaults.pDatatype=NULL;
1949 defaults.DesiredAccess=PRINTER_ACCESS_USE;
1950
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);
1958
1959
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);
1968 }
1969
1970 }
1971
1972
1973 static void test_SetDefaultPrinter(void)
1974 {
1975 DWORD res;
1976 DWORD size = DEFAULT_PRINTER_SIZE;
1977 CHAR buffer[DEFAULT_PRINTER_SIZE];
1978 CHAR org_value[DEFAULT_PRINTER_SIZE];
1979
1980 if (!default_printer)
1981 {
1982 skip("There is no default printer installed\n");
1983 return;
1984 }
1985
1986 if (!pSetDefaultPrinterA) return;
1987 /* only supported on win2k and above */
1988
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());
1994
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;
1999
2000 /* Not implemented in wine */
2001 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
2002 trace("SetDefaultPrinterA() not implemented yet.\n");
2003 return;
2004 }
2005
2006 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
2007 "returned %d with %d (expected '0' with "
2008 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2009
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());
2016
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());
2023
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());
2030
2031
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");
2036
2037 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME),
2038 "returned %d with %d (expected '0' with "
2039 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2040
2041 WriteProfileStringA("windows", "device", NULL);
2042 SetLastError(MAGIC_DEAD);
2043 res = pSetDefaultPrinterA("");
2044 if (is_spooler_deactivated(res, GetLastError()))
2045 goto restore_old_printer;
2046
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());
2051
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());
2059
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());
2066
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 */
2072
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);
2078
2079 }
2080
2081 /* ########################### */
2082
2083 static void test_XcvDataW_MonitorUI(void)
2084 {
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;
2092
2093 /* api is not present before w2k */
2094 if (pXcvDataW == NULL) return;
2095
2096 pd.pDatatype = NULL;
2097 pd.pDevMode = NULL;
2098 pd.DesiredAccess = SERVER_ACCESS_ADMINISTER;
2099
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;
2105
2106 ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv);
2107 if (!res) return;
2108
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);
2118
2119 if (needed > MAX_PATH) {
2120 ClosePrinter(hXcv);
2121 skip("buffer overflow (%u)\n", needed);
2122 return;
2123 }
2124 len = needed; /* Size is in bytes */
2125
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);
2134
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);
2142
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);
2151
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);
2159
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);
2167
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);
2176
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);
2186
2187
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);
2197
2198 ClosePrinter(hXcv);
2199 }
2200
2201 /* ########################### */
2202
2203 static void test_XcvDataW_PortIsValid(void)
2204 {
2205 DWORD res;
2206 HANDLE hXcv;
2207 DWORD needed;
2208 DWORD status;
2209 PRINTER_DEFAULTSA pd;
2210
2211 /* api is not present before w2k */
2212 if (pXcvDataW == NULL) return;
2213
2214 pd.pDatatype = NULL;
2215 pd.pDevMode = NULL;
2216 pd.DesiredAccess = SERVER_ACCESS_ADMINISTER;
2217
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;
2223
2224 ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv);
2225 if (!res) return;
2226
2227
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);
2236
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);
2246
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);
2257
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);
2266
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);
2274
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);
2282
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);
2290
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);
2298
2299
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);
2308
2309 ClosePrinter(hXcv);
2310 }
2311
2312 /* ########################### */
2313
2314 static void test_GetPrinter(void)
2315 {
2316 HANDLE hprn;
2317 BOOL ret;
2318 BYTE *buf;
2319 INT level;
2320 DWORD needed, filled;
2321
2322 if (!default_printer)
2323 {
2324 skip("There is no default printer installed\n");
2325 return;
2326 }
2327
2328 hprn = 0;
2329 ret = OpenPrinterA(default_printer, &hprn, NULL);
2330 if (!ret)
2331 {
2332 skip("Unable to open the default printer (%s)\n", default_printer);
2333 return;
2334 }
2335 ok(hprn != 0, "wrong hprn %p\n", hprn);
2336
2337 for (level = 1; level <= 9; level++)
2338 {
2339 SetLastError(0xdeadbeef);
2340 needed = (DWORD)-1;
2341 ret = GetPrinterA(hprn, level, NULL, 0, &needed);
2342 if (ret)
2343 {
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;
2348 }
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 */)
2353 {
2354 skip("Level %d not supported\n", level);
2355 continue;
2356 }
2357 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
2358 ok(needed > 0,"not expected needed buffer size %d\n", needed);
2359
2360 /* GetPrinterA returns the same number of bytes as GetPrinterW */
2361 if (!on_win9x && !ret && pGetPrinterW && level != 6 && level != 7)
2362 {
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);
2367 }
2368
2369 buf = HeapAlloc(GetProcessHeap(), 0, needed);
2370
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);
2376
2377 if (level == 2)
2378 {
2379 PRINTER_INFO_2A *pi_2 = (PRINTER_INFO_2A *)buf;
2380
2381 ok(pi_2->pPrinterName!= NULL, "not expected NULL ptr\n");
2382 ok(pi_2->pDriverName!= NULL, "not expected NULL ptr\n");
2383
2384 trace("pPrinterName %s\n", pi_2->pPrinterName);
2385 trace("pDriverName %s\n", pi_2->pDriverName);
2386 }
2387
2388 HeapFree(GetProcessHeap(), 0, buf);
2389 }
2390
2391 SetLastError(0xdeadbeef);
2392 ret = ClosePrinter(hprn);
2393 ok(ret, "ClosePrinter error %d\n", GetLastError());
2394 }
2395
2396 /* ########################### */
2397
2398 static void test_GetPrinterData(void)
2399 {
2400 HANDLE hprn = 0;
2401 DWORD res;
2402 DWORD type;
2403 CHAR buffer[MAX_PATH + 1];
2404 DWORD needed;
2405 DWORD len;
2406
2407 /* ToDo: test parameter validation, test with the default printer */
2408
2409 SetLastError(0xdeadbeef);
2410 res = OpenPrinterA(NULL, &hprn, NULL);
2411 if (!res)
2412 {
2413 /* printserver not available on win9x */
2414 if (!on_win9x)
2415 win_skip("Unable to open the printserver: %d\n", GetLastError());
2416 return;
2417 }
2418
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);
2425
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);
2431
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);
2437
2438 /* ToDo: test SPLREG_* */
2439
2440 SetLastError(0xdeadbeef);
2441 res = ClosePrinter(hprn);
2442 ok(res, "ClosePrinter error %d\n", GetLastError());
2443 }
2444
2445 /* ########################### */
2446
2447 static void test_GetPrinterDataEx(void)
2448 {
2449 HANDLE hprn = 0;
2450 DWORD res;
2451 DWORD type;
2452 CHAR buffer[MAX_PATH + 1];
2453 DWORD needed;
2454 DWORD len;
2455
2456 /* not present before w2k */
2457 if (!pGetPrinterDataExA) {
2458 win_skip("GetPrinterDataEx not found\n");
2459 return;
2460 }
2461
2462 /* ToDo: test parameter validation, test with the default printer */
2463
2464 SetLastError(0xdeadbeef);
2465 res = OpenPrinterA(NULL, &hprn, NULL);
2466 if (!res)
2467 {
2468 win_skip("Unable to open the printserver: %d\n", GetLastError());
2469 return;
2470 }
2471
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);
2480
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);
2486
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);
2498
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);
2511
2512
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);
2524
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);
2533
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);
2540
2541 SetLastError(0xdeadbeef);
2542 res = ClosePrinter(hprn);
2543 ok(res, "ClosePrinter error %d\n", GetLastError());
2544 }
2545
2546 /* ########################### */
2547
2548 static void test_GetPrinterDriver(void)
2549 {
2550 HANDLE hprn;
2551 BOOL ret;
2552 BYTE *buf;
2553 INT level;
2554 DWORD needed, filled;
2555
2556 if (!default_printer)
2557 {
2558 skip("There is no default printer installed\n");
2559 return;
2560 }
2561
2562 hprn = 0;
2563 ret = OpenPrinterA(default_printer, &hprn, NULL);
2564 if (!ret)
2565 {
2566 skip("Unable to open the default printer (%s)\n", default_printer);
2567 return;
2568 }
2569 ok(hprn != 0, "wrong hprn %p\n", hprn);
2570
2571 for (level = -1; level <= 7; level++)
2572 {
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)
2578 {
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);
2583 }
2584 else
2585 {
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;
2595 }
2596
2597 /* GetPrinterDriverA returns the same number of bytes as GetPrinterDriverW */
2598 if (!on_win9x && !ret && pGetPrinterDriverW)
2599 {
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);
2604 }
2605
2606 buf = HeapAlloc(GetProcessHeap(), 0, needed);
2607
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);
2613
2614 if (level == 2)
2615 {
2616 DRIVER_INFO_2A *di_2 = (DRIVER_INFO_2A *)buf;
2617 DWORD calculated = sizeof(*di_2);
2618 HANDLE hf;
2619
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");
2629
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;
2641
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);
2647
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);
2652
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);
2658
2659 /* XP allocates memory for both ANSI and unicode names */
2660 ok(filled >= calculated,"calculated %d != filled %d\n", calculated, filled);
2661
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");
2668 }
2669
2670 HeapFree(GetProcessHeap(), 0, buf);
2671 }
2672
2673 SetLastError(0xdeadbeef);
2674 ret = ClosePrinter(hprn);
2675 ok(ret, "ClosePrinter error %d\n", GetLastError());
2676 }
2677
2678 static void test_DEVMODEA(const DEVMODEA *dm, LONG dmSize, LPCSTR exp_prn_name)
2679 {
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);
2690 }
2691 trace("dmFields %08x\n", dm->dmFields);
2692 }
2693
2694 static void test_DocumentProperties(void)
2695 {
2696 HANDLE hprn;
2697 LONG dm_size, ret;
2698 DEVMODEA *dm;
2699 char empty_str[] = "";
2700
2701 if (!default_printer)
2702 {
2703 skip("There is no default printer installed\n");
2704 return;
2705 }
2706
2707 hprn = 0;
2708 ret = OpenPrinterA(default_printer, &hprn, NULL);
2709 if (!ret)
2710 {
2711 skip("Unable to open the default printer (%s)\n", default_printer);
2712 return;
2713 }
2714 ok(hprn != 0, "wrong hprn %p\n", hprn);
2715
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);
2719
2720 dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
2721
2722 ret = DocumentPropertiesA(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
2723 ok(ret == IDOK, "DocumentPropertiesA ret value %d != expected IDOK\n", ret);
2724
2725 ret = DocumentPropertiesA(0, hprn, empty_str, dm, dm, DM_OUT_BUFFER);
2726 ok(ret == IDOK, "DocumentPropertiesA ret value %d != expected IDOK\n", ret);
2727
2728 test_DEVMODEA(dm, dm_size, default_printer);
2729
2730 HeapFree(GetProcessHeap(), 0, dm);
2731
2732 SetLastError(0xdeadbeef);
2733 ret = ClosePrinter(hprn);
2734 ok(ret, "ClosePrinter error %d\n", GetLastError());
2735 }
2736
2737 static void test_EnumPrinters(void)
2738 {
2739 DWORD neededA, neededW, num;
2740 DWORD ret;
2741
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)
2747 {
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");
2751 }
2752 else
2753 {
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");
2757 }
2758 ok(num == 0, "num %d\n", num);
2759
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))
2765 {
2766 win_skip("EnumPrintersW is not implemented\n");
2767 return;
2768 }
2769
2770 if (!ret)
2771 {
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");
2775 }
2776 else
2777 {
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");
2781 }
2782 ok(num == 0, "num %d\n", num);
2783
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);
2787 }
2788
2789 static void test_DeviceCapabilities(void)
2790 {
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
2801 {
2802 char name[64];
2803 } *paper_name;
2804 INT n_papers, n_paper_size, n_paper_names, n_copies, ret;
2805 DWORD fields;
2806
2807 hComdlg32 = LoadLibraryA("comdlg32.dll");
2808 assert(hComdlg32);
2809 pPrintDlgA = (void *)GetProcAddress(hComdlg32, "PrintDlgA");
2810 assert(pPrintDlgA);
2811
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)
2818 {
2819 skip("PrintDlg returned no default printer\n");
2820 return;
2821 }
2822 ok(prn_dlg.hDevMode != 0, "PrintDlg returned hDevMode == NULL\n");
2823 ok(prn_dlg.hDevNames != 0, "PrintDlg returned hDevNames == NULL\n");
2824
2825 dm = GlobalLock(prn_dlg.hDevMode);
2826 ok(dm != NULL, "GlobalLock(prn_dlg.hDevMode) failed\n");
2827 trace("dmDeviceName \"%s\"\n", dm->dmDeviceName);
2828
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);
2839
2840 test_DEVMODEA(dm, dm->dmSize + dm->dmDriverExtra, device);
2841
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);
2852
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);
2864
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);
2876
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);
2880
2881 /* these capabilities are not available on all printer drivers */
2882 if (0)
2883 {
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);
2888
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);
2893 }
2894
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);
2901
2902 GlobalUnlock(prn_dlg.hDevMode);
2903 GlobalFree(prn_dlg.hDevMode);
2904 GlobalUnlock(prn_dlg.hDevNames);
2905 GlobalFree(prn_dlg.hDevNames);
2906 }
2907
2908 static void test_IsValidDevmodeW(void)
2909 {
2910 BOOL br;
2911
2912 if (!pIsValidDevmodeW)
2913 {
2914 win_skip("IsValidDevmodeW not implemented.\n");
2915 return;
2916 }
2917
2918 br = pIsValidDevmodeW(NULL, 0);
2919 ok(br == FALSE, "Got %d\n", br);
2920
2921 br = pIsValidDevmodeW(NULL, 1);
2922 ok(br == FALSE, "Got %d\n", br);
2923
2924 br = pIsValidDevmodeW(NULL, sizeof(DEVMODEW));
2925 ok(br == FALSE, "Got %d\n", br);
2926 }
2927
2928 static void test_OpenPrinter_defaults(void)
2929 {
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;
2939
2940 if (!default_printer)
2941 {
2942 skip("There is no default printer installed\n");
2943 return;
2944 }
2945
2946 /* Printer opened with NULL defaults. Retrieve default paper size
2947 and confirm that jobs have this size. */
2948
2949 ret = OpenPrinterA( default_printer, &printer, NULL );
2950 if (!ret)
2951 {
2952 skip("Unable to open the default printer (%s)\n", default_printer);
2953 return;
2954 }
2955
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 );
2963
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 */
2969 {
2970 win_skip( "AddJob is not supported on this platform\n" );
2971 ClosePrinter( printer );
2972 return;
2973 }
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() );
2979
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() );
2985
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 );
2991
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 );
2996
2997 /* Printer opened with something other than the default paper size. */
2998
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;
3003
3004 prn_def.pDatatype = NULL;
3005 prn_def.pDevMode = &my_dm;
3006 prn_def.DesiredAccess = PRINTER_ACCESS_USE;
3007
3008 ret = OpenPrinterA( default_printer, &printer, &prn_def );
3009 ok( ret, "OpenPrinterA() failed le=%d\n", GetLastError() );
3010
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 );
3019
3020 HeapFree( GetProcessHeap(), 0, pi );
3021
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() );
3028
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() );
3034
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 );
3040
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 );
3045 }
3046
3047 START_TEST(info)
3048 {
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");
3059
3060 on_win9x = check_win9x();
3061 if (on_win9x)
3062 win_skip("Several W-functions are not available on Win9x/WinMe\n");
3063
3064 find_default_printer();
3065 find_local_server();
3066 find_tempfile();
3067
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
3081 if (!winetest_interactive)
3082 skip("ROSTESTS-211: Skipping test_EnumPorts().\n");
3083 else
3084 test_EnumPorts();
3085
3086 test_EnumPrinterDrivers();
3087 test_EnumPrinters();
3088
3089 if (!winetest_interactive)
3090 skip("ROSTESTS-211: Skipping test_EnumPrintProcessors().\n");
3091 else
3092 test_EnumPrintProcessors();
3093
3094 test_GetDefaultPrinter();
3095 test_GetPrinterDriverDirectory();
3096 test_GetPrintProcessorDirectory();
3097 test_IsValidDevmodeW();
3098 test_OpenPrinter();
3099 test_OpenPrinter_defaults();
3100 test_GetPrinter();
3101 test_GetPrinterData();
3102 test_GetPrinterDataEx();
3103 test_GetPrinterDriver();
3104 test_SetDefaultPrinter();
3105 test_XcvDataW_MonitorUI();
3106 test_XcvDataW_PortIsValid();
3107
3108 /* Cleanup our temporary file */
3109 DeleteFileA(tempfileA);
3110 }