ReactOS 0.4.15-dev-7788-g1ad9096
info.c
Go to the documentation of this file.
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
41static CHAR defaultspooldirectory[] = "DefaultSpoolDirectory";
42static CHAR does_not_exist_dll[]= "does_not_exist.dll";
43static CHAR does_not_exist[] = "does_not_exist";
44static CHAR empty[] = "";
45static CHAR env_x64[] = "Windows x64";
46static CHAR env_x86[] = "Windows NT x86";
47static CHAR env_win9x_case[] = "windowS 4.0";
48static CHAR illegal_name[] = "illegal,name";
49static CHAR invalid_env[] = "invalid_env";
50static CHAR LocalPortA[] = "Local Port";
51static CHAR portname_com1[] = "COM1:";
52static CHAR portname_file[] = "FILE:";
53static CHAR portname_lpt1[] = "LPT1:";
54static CHAR server_does_not_exist[] = "\\\\does_not_exist";
55static CHAR version_dll[] = "version.dll";
56static CHAR winetest[] = "winetest";
57static CHAR xcv_localport[] = ",XcvMonitor Local Port";
58
59static const WCHAR cmd_MonitorUIW[] = {'M','o','n','i','t','o','r','U','I',0};
60static const WCHAR cmd_PortIsValidW[] = {'P','o','r','t','I','s','V','a','l','i','d',0};
61static WCHAR emptyW[] = {0};
62
63static WCHAR portname_com1W[] = {'C','O','M','1',':',0};
64static WCHAR portname_com2W[] = {'C','O','M','2',':',0};
65static WCHAR portname_fileW[] = {'F','I','L','E',':',0};
66static WCHAR portname_lpt1W[] = {'L','P','T','1',':',0};
67static WCHAR portname_lpt2W[] = {'L','P','T','2',':',0};
68
70static BOOL (WINAPI * pAddPortExA)(LPSTR, DWORD, LPBYTE, LPSTR);
71static BOOL (WINAPI * pEnumPrinterDriversW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
72static BOOL (WINAPI * pGetDefaultPrinterA)(LPSTR, LPDWORD);
73static DWORD (WINAPI * pGetPrinterDataExA)(HANDLE, LPCSTR, LPCSTR, LPDWORD, LPBYTE, DWORD, LPDWORD);
74static BOOL (WINAPI * pGetPrinterDriverW)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
75static BOOL (WINAPI * pGetPrinterW)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
76static BOOL (WINAPI * pSetDefaultPrinterA)(LPCSTR);
78
79/* ################################ */
80
84};
85
92
94{
95 if (!res && lasterror == RPC_S_SERVER_UNAVAILABLE)
96 {
97 static int deactivated_spooler_reported = 0;
98 if (!deactivated_spooler_reported)
99 {
100 deactivated_spooler_reported = 1;
101 skip("The service 'Spooler' is required for many tests\n");
102 }
103 return TRUE;
104 }
105 return FALSE;
106}
107
109{
110 if (!res && lasterror == ERROR_ACCESS_DENIED)
111 {
112 static int access_denied_reported = 0;
113 if (!access_denied_reported)
114 {
115 access_denied_reported = 1;
116 skip("More access rights are required for many tests\n");
117 }
118 return TRUE;
119 }
120 return FALSE;
121}
122
124{
125 static char buffer[DEFAULT_PRINTER_SIZE];
126 DWORD needed;
127 DWORD res;
128 LPSTR ptr;
129
130 if ((default_printer == NULL) && (pGetDefaultPrinterA))
131 {
132 /* w2k and above */
133 needed = sizeof(buffer);
134 res = pGetDefaultPrinterA(buffer, &needed);
136 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
137 }
138 if (default_printer == NULL)
139 {
140 HKEY hwindows;
141 DWORD type;
142 /* NT 3.x and above */
144 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
145 0, KEY_QUERY_VALUE, &hwindows) == NO_ERROR) {
146
147 needed = sizeof(buffer);
148 if (RegQueryValueExA(hwindows, "device", NULL, &type, (LPBYTE)buffer, &needed) == NO_ERROR) {
149 ptr = strchr(buffer, ',');
150 if (ptr) {
151 ptr[0] = '\0';
153 }
154 }
155 RegCloseKey(hwindows);
156 }
157 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
158 }
159 if (default_printer == NULL)
160 {
161 /* win9x */
162 needed = sizeof(buffer);
163 res = GetProfileStringA("windows", "device", "*", buffer, needed);
164 if(res) {
165 ptr = strchr(buffer, ',');
166 if (ptr) {
167 ptr[0] = '\0';
169 }
170 }
171 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)");
172 }
173}
174
175
177{
178 MONITOR_INFO_2A mi2a;
179 static struct monitor_entry * entry = NULL;
181 DWORD i = 0;
182
183 static struct monitor_entry monitor_table[] = {
184 {env_win9x_case, "localspl.dll"},
185 {env_x86, "localspl.dll"},
186 {env_x64, "localspl.dll"},
187 {env_win9x_case, "localmon.dll"},
188 {env_x86, "localmon.dll"},
189 {env_win9x_case, "tcpmon.dll"},
190 {env_x86, "tcpmon.dll"},
191 {env_win9x_case, "usbmon.dll"},
192 {env_x86, "usbmon.dll"},
193 {env_win9x_case, "mspp32.dll"},
194 {env_x86, "win32spl.dll"},
195 {env_x86, "redmonnt.dll"},
196 {env_x86, "redmon35.dll"},
197 {env_win9x_case, "redmon95.dll"},
198 {env_x86, "pdfcmnnt.dll"},
199 {env_win9x_case, "pdfcmn95.dll"},
200 };
201
202 if (entry) return entry;
203
204 num_tests = ARRAY_SIZE(monitor_table);
205
206 /* cleanup */
210
211 /* find a usable monitor from the table */
212 mi2a.pName = winetest;
213 while ((entry == NULL) && (i < num_tests)) {
214 entry = &monitor_table[i];
215 i++;
216 mi2a.pEnvironment = entry->env;
217 mi2a.pDLLName = entry->dllname;
218
219 if (AddMonitorA(NULL, 2, (LPBYTE) &mi2a)) {
220 /* we got one */
221 trace("using '%s', '%s'\n", entry->env, entry->dllname);
223 }
224 else
225 {
226 entry = NULL;
227 }
228 }
229 return entry;
230}
231
232
233/* ########################### */
234
236{
237 static char buffer[MAX_PATH];
238 DWORD res;
239 DWORD size;
240
241 size = sizeof(buffer) - 3 ;
242 buffer[0] = '\\';
243 buffer[1] = '\\';
244 buffer[2] = '\0';
245
246 SetLastError(0xdeadbeef);
248 trace("returned %d with %d and %d: '%s'\n", res, GetLastError(), size, buffer);
249
250 ok( res != 0, "returned %d with %d and %d: '%s' (expected '!= 0')\n",
252
253 if (res) local_server = buffer;
254}
255
256/* ########################### */
257
258static void find_tempfile(VOID)
259{
260 static CHAR buffer_dirA[MAX_PATH];
261 static CHAR buffer_fileA[MAX_PATH];
262 static WCHAR buffer_dirW[MAX_PATH];
263 static WCHAR buffer_fileW[MAX_PATH];
264 DWORD res;
265 int resint;
266
267 memset(buffer_dirA, 0, MAX_PATH - 1);
268 buffer_dirA[MAX_PATH - 1] = '\0';
269 SetLastError(0xdeadbeef);
270 res = GetTempPathA(MAX_PATH, buffer_dirA);
271 ok(res, "returned %u with %u and '%s' (expected '!= 0')\n", res, GetLastError(), buffer_dirA);
272 if (res == 0) return;
273
274 memset(buffer_fileA, 0, MAX_PATH - 1);
275 buffer_fileA[MAX_PATH - 1] = '\0';
276 SetLastError(0xdeadbeef);
277 res = GetTempFileNameA(buffer_dirA, winetest, 0, buffer_fileA);
278 ok(res, "returned %u with %u and '%s' (expected '!= 0')\n", res, GetLastError(), buffer_fileA);
279 if (res == 0) return;
280
281 SetLastError(0xdeadbeef);
282 resint = MultiByteToWideChar(CP_ACP, 0, buffer_dirA, -1, buffer_dirW, MAX_PATH);
283 ok(res, "returned %u with %u (expected '!= 0')\n", resint, GetLastError());
284 if (resint == 0) return;
285
286 SetLastError(0xdeadbeef);
287 resint = MultiByteToWideChar(CP_ACP, 0, buffer_fileA, -1, buffer_fileW, MAX_PATH);
288 ok(res, "returned %u with %u (expected '!= 0')\n", resint, GetLastError());
289 if (resint == 0) return;
290
291 tempdirA = buffer_dirA;
292 tempfileA = buffer_fileA;
293 tempdirW = buffer_dirW;
294 tempfileW = buffer_fileW;
295 trace("tempfile: '%s'\n", tempfileA);
296}
297
298/* ########################### */
299
300static void test_AddMonitor(void)
301{
302 MONITOR_INFO_2A mi2a;
303 struct monitor_entry * entry = NULL;
304 DWORD res;
305
307
309 res = AddMonitorA(NULL, 1, NULL);
311 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
312 res, GetLastError());
313
315 res = AddMonitorA(NULL, 3, NULL);
317 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
318 res, GetLastError());
319
320 /* This test crashes win9x on vmware (works with win9x on qemu 0.8.1) */
322 res = AddMonitorA(NULL, 2, NULL);
323 /* NT: unchanged, 9x: ERROR_PRIVILEGE_NOT_HELD */
324 ok(!res &&
325 ((GetLastError() == MAGIC_DEAD) ||
327 "returned %d with %d (expected '0' with: MAGIC_DEAD or "
328 "ERROR_PRIVILEGE_NOT_HELD)\n", res, GetLastError());
329
330 ZeroMemory(&mi2a, sizeof(MONITOR_INFO_2A));
332 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
334 if (is_access_denied(res, GetLastError())) return;
335
336 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_INVALID_ENVIRONMENT */
339 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
340 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
341
342 if (!entry) {
343 skip("No usable Monitor found\n");
344 return;
345 }
346
347 if (0)
348 {
349 /* The test is deactivated, because when mi2a.pName is NULL, the subkey
350 HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM
351 or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì
352 is created on win9x and we do not want to hit this bug here. */
353
354 mi2a.pEnvironment = entry->env;
356 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
357 ok(res, "AddMonitor error %d\n", GetLastError());
358 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
359 }
360
361 mi2a.pEnvironment = entry->env;
362 mi2a.pName = empty;
364 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
365 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
366 ok( !res &&
369 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
370 "ERROR_PRIVILEGE_NOT_HELD)\n",
371 res, GetLastError());
372
373 mi2a.pName = winetest;
375 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
376 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */
377 ok( !res &&
380 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
381 "ERROR_PRIVILEGE_NOT_HELD)\n",
382 res, GetLastError());
383
384 mi2a.pDLLName = empty;
386 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
388 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
389 res, GetLastError());
390
393 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
394 /* NT: ERROR_MOD_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
395 ok( !res &&
398 "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or "
399 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
400
401 mi2a.pDLLName = version_dll;
403 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
404 /* NT: ERROR_PROC_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */
405 ok( !res &&
408 "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or "
409 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
410 if (res) DeleteMonitorA(NULL, entry->env, winetest);
411
412 /* Test AddMonitor with real options */
413 mi2a.pDLLName = entry->dllname;
415 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
416 /* Some apps depend on the result of GetLastError() also on success of AddMonitor */
418 "returned %d with %d (expected '!= 0' with ERROR_SUCCESS)\n", res, GetLastError());
419
420 /* add a monitor twice */
422 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
423 /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */
424 ok( !res &&
427 "returned %d with %d (expected '0' with: "
428 "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n",
429 res, GetLastError());
430
433 res = AddMonitorA(empty, 2, (LPBYTE) &mi2a);
434 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
435
436 /* cleanup */
438
439}
440
441/* ########################### */
442
443static void test_AddPort(void)
444{
445 DWORD res;
446
447 SetLastError(0xdeadbeef);
448 res = AddPortA(NULL, 0, NULL);
450 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
453 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
454 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
455
456
457 SetLastError(0xdeadbeef);
458 res = AddPortA(NULL, 0, empty);
459 /* Allowed only for (Printer-)Administrators */
460 if (is_access_denied(res, GetLastError())) return;
461
462 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
463 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
465 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
466 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
467
468
469 SetLastError(0xdeadbeef);
471 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
472 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
474 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
475 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
476
477}
478
479/* ########################### */
480
481static void test_AddPortEx(void)
482{
484 DWORD res;
485
486
487 if (!pAddPortExA) {
488 win_skip("AddPortEx not supported\n");
489 return;
490 }
491
492 /* start test with a clean system */
494
495 pi.pPortName = tempfileA;
496 SetLastError(0xdeadbeef);
497 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
499
500 /* Allowed only for (Printer-)Administrators.
501 W2K+XP: ERROR_INVALID_PARAMETER */
503 skip("ACCESS_DENIED (ERROR_INVALID_PARAMETER)\n");
504 return;
505 }
506 ok( res, "got %u with %u (expected '!= 0')\n", res, GetLastError());
507
508 /* add a port that already exists */
509 SetLastError(0xdeadbeef);
510 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
512 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
513 res, GetLastError());
515
516
517 /* the Monitorname must match */
518 SetLastError(0xdeadbeef);
519 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, NULL);
521 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
522 res, GetLastError());
523 if (res) DeletePortA(NULL, 0, tempfileA);
524
525 SetLastError(0xdeadbeef);
526 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, empty);
528 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
529 res, GetLastError());
530 if (res) DeletePortA(NULL, 0, tempfileA);
531
532 SetLastError(0xdeadbeef);
533 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, does_not_exist);
535 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
536 res, GetLastError());
537 if (res) DeletePortA(NULL, 0, tempfileA);
538
539
540 /* We need a Portname */
541 SetLastError(0xdeadbeef);
542 res = pAddPortExA(NULL, 1, NULL, LocalPortA);
544 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
545 res, GetLastError());
546
547 pi.pPortName = NULL;
548 SetLastError(0xdeadbeef);
549 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA);
551 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
552 res, GetLastError());
553 if (res) DeletePortA(NULL, 0, tempfileA);
554
555
556 /* level 2 is documented as supported for Printmonitors,
557 but that is not supported for "Local Port" (localspl.dll) and
558 AddPortEx fails with ERROR_INVALID_LEVEL */
559
560 pi.pPortName = tempfileA;
561 pi.pMonitorName = LocalPortA;
562 pi.pDescription = winetest;
563 pi.fPortType = PORT_TYPE_WRITE;
564
565 SetLastError(0xdeadbeef);
566 res = pAddPortExA(NULL, 2, (LPBYTE) &pi, LocalPortA);
568 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
569 res, GetLastError());
570 if (res) DeletePortA(NULL, 0, tempfileA);
571
572
573 /* invalid levels */
574 SetLastError(0xdeadbeef);
575 res = pAddPortExA(NULL, 0, (LPBYTE) &pi, LocalPortA);
577 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
578 res, GetLastError());
579
580 SetLastError(0xdeadbeef);
581 res = pAddPortExA(NULL, 3, (LPBYTE) &pi, LocalPortA);
583 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
584 res, GetLastError());
585
586
587 /* cleanup */
589
590}
591
592/* ########################### */
593
594static void test_ConfigurePort(void)
595{
596 DWORD res;
597
598
599 SetLastError(0xdeadbeef);
602 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */
605 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
606 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
607
608 SetLastError(0xdeadbeef);
610 /* Allowed only for (Printer-)Administrators */
611 if (is_access_denied(res, GetLastError())) return;
612
613 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
614 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
616 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
617 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
618
619
620 SetLastError(0xdeadbeef);
622 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
623 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
625 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
626 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
627
628
629 /* Testing-Results:
630 - Case of Portnames is ignored
631 - Portname without ":" => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
632 - Empty Servername (LPT1:) => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up
633
634 - Port not present => 9x: ERROR_INVALID_PARAMETER, NT:ERROR_NOT_SUPPORTED
635 - "FILE:" => 9x:Success, NT:ERROR_CANCELED
636 - Cancel ("Local Port") => ERROR_CANCELED
637 - Cancel ("Redirected Port") => Success
638 */
639 if (winetest_interactive > 0) {
640 SetLastError(0xdeadbeef);
642 trace("'%s' returned %d with %d\n", portname_com1, res, GetLastError());
643
644 SetLastError(0xdeadbeef);
646 trace("'%s' returned %d with %d\n", portname_lpt1, res, GetLastError());
647
648 SetLastError(0xdeadbeef);
650 trace("'%s' returned %d with %d\n", portname_file, res, GetLastError());
651 }
652}
653
654/* ########################### */
655
656static void test_ClosePrinter(void)
657{
658 HANDLE printer = 0;
659 BOOL res;
660
661 /* NULL is handled */
662 SetLastError(0xdeadbeef);
665 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
666 res, GetLastError());
667
668 /* A random value as HANDLE is handled */
669 SetLastError(0xdeadbeef);
670 res = ClosePrinter( (void *) -1);
673 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
674 res, GetLastError());
675
676
677 /* Normal use (The Spooler service is needed) */
678 SetLastError(0xdeadbeef);
679 res = OpenPrinterA(default_printer, &printer, NULL);
681 if (res)
682 {
683 SetLastError(0xdeadbeef);
684 res = ClosePrinter(printer);
685 ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError());
686
687
688 /* double free is handled */
689 SetLastError(0xdeadbeef);
690 res = ClosePrinter(printer);
692 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n",
693 res, GetLastError());
694
695 }
696}
697
698/* ########################### */
699
700static void test_DeleteMonitor(void)
701{
702 MONITOR_INFO_2A mi2a;
703 struct monitor_entry * entry = NULL;
704 DWORD res;
705
706
708
709 if (!entry) {
710 skip("No usable Monitor found\n");
711 return;
712 }
713
714 mi2a.pName = winetest;
715 mi2a.pEnvironment = entry->env;
716 mi2a.pDLLName = entry->dllname;
717
718 /* Testing DeleteMonitor with real options */
719 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
720
723 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
724
725 /* Delete the Monitor twice */
728 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
729 ok( !res &&
732 "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR"
733 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
734
735 /* the environment */
736 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
739 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
740
741 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
744 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
745
746 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
749 ok( res || GetLastError() == ERROR_INVALID_ENVIRONMENT /* Vista/W2K8 */,
750 "returned %d with %d\n", res, GetLastError());
751
752 /* the monitor-name */
753 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
755 res = DeleteMonitorA(NULL, entry->env, NULL);
756 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
757 ok( !res &&
760 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
761 "ERROR_INVALID_NAME)\n", res, GetLastError());
762
763 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
766 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/
767 ok( !res &&
770 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or "
771 "ERROR_INVALID_NAME)\n", res, GetLastError());
772
773 AddMonitorA(NULL, 2, (LPBYTE) &mi2a);
776 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
777
778 /* cleanup */
780}
781
782/* ########################### */
783
784static void test_DeletePort(void)
785{
786 DWORD res;
787
788 SetLastError(0xdeadbeef);
789 res = DeletePortA(NULL, 0, NULL);
791
792 SetLastError(0xdeadbeef);
793 res = DeletePortA(NULL, 0, empty);
794 /* Allowed only for (Printer-)Administrators */
795 if (is_access_denied(res, GetLastError())) return;
796
797 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
798 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
800 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
801 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
802
803
804 SetLastError(0xdeadbeef);
806 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */
807 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) ||
809 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or "
810 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
811
812}
813
814/* ########################### */
815
817{
818 DWORD res;
819 HANDLE hprinter = 0;
821 DWORD cbBuf;
823 DWORD pcReturned;
824 DWORD level;
825 UINT i;
826 const char *formtype;
827 static const char * const formtypes[] = { "FORM_USER", "FORM_BUILTIN", "FORM_PRINTER", "FORM_flag_unknown" };
828#define FORMTYPE_MAX 2
829 PFORM_INFO_1A pFI_1a;
830 PFORM_INFO_2A pFI_2a;
831
832 res = OpenPrinterA(pName, &hprinter, NULL);
834 if (!res || !hprinter)
835 {
836 /* opening the local Printserver is not supported on win9x */
837 if (pName) skip("Failed to open '%s' (not supported on win9x)\n", pName);
838 return;
839 }
840
841 /* valid levels are 1 and 2 */
842 for(level = 0; level < 4; level++) {
843 cbBuf = 0xdeadbeef;
844 pcReturned = 0xdeadbeef;
845 SetLastError(0xdeadbeef);
846 res = EnumFormsA(hprinter, level, NULL, 0, &cbBuf, &pcReturned);
847
848 /* EnumForms is not implemented on win9x */
849 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
850
851 /* EnumForms for the server is not implemented on all NT-versions */
852 if (!res && (GetLastError() == ERROR_INVALID_HANDLE) && !pName) continue;
853
854 /* Level 2 for EnumForms is not supported on all systems */
855 if (!res && (GetLastError() == ERROR_INVALID_LEVEL) && (level == 2)) continue;
856
857 /* use only a short test when testing an invalid level */
858 if(!level || (level > 2)) {
859 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
860 (res && (pcReturned == 0)),
861 "(%d) returned %d with %d and 0x%08x (expected '0' with "
862 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
863 level, res, GetLastError(), pcReturned);
864 continue;
865 }
866
868 "(%d) returned %d with %d (expected '0' with "
869 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
870
871 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
872 if (buffer == NULL) continue;
873
874 SetLastError(0xdeadbeef);
875 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
876 ok(res, "(%d) returned %d with %d (expected '!=0')\n",
878
879 if (winetest_debug > 1) {
880 trace("dumping %d forms level %d\n", pcReturned, level);
881 pFI_1a = (PFORM_INFO_1A)buffer;
882 pFI_2a = (PFORM_INFO_2A)buffer;
883 for (i = 0; i < pcReturned; i++)
884 {
885 /* first part is same in FORM_INFO_1 and FORM_INFO_2 */
886 formtype = (pFI_1a->Flags <= FORMTYPE_MAX) ? formtypes[pFI_1a->Flags] : formtypes[3];
887 trace("%u (%s): %.03fmm x %.03fmm, %s\n", i, pFI_1a->pName,
888 (float)pFI_1a->Size.cx/1000, (float)pFI_1a->Size.cy/1000, formtype);
889
890 if (level == 1) pFI_1a ++;
891 else {
892 /* output additional FORM_INFO_2 fields */
893 trace("\tkeyword=%s strtype=%u muidll=%s resid=%u dispname=%s langid=%u\n",
894 pFI_2a->pKeyword, pFI_2a->StringType, pFI_2a->pMuiDll,
895 pFI_2a->dwResourceId, pFI_2a->pDisplayName, pFI_2a->wLangId);
896
897 /* offset pointer pFI_1a by 1*sizeof(FORM_INFO_2A) Bytes */
898 pFI_2a ++;
899 pFI_1a = (PFORM_INFO_1A)pFI_2a;
900 }
901 }
902 }
903
904 SetLastError(0xdeadbeef);
905 res = EnumFormsA(hprinter, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
906 ok( res, "(%d) returned %d with %d (expected '!=0')\n",
908
909 SetLastError(0xdeadbeef);
910 res = EnumFormsA(hprinter, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
912 "(%d) returned %d with %d (expected '0' with "
913 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
914
915
916 SetLastError(0xdeadbeef);
917 res = EnumFormsA(hprinter, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
919 "(%d) returned %d with %d (expected '0' with "
920 "ERROR_INVALID_USER_BUFFER)\n", level, res, GetLastError());
921
922
923 SetLastError(0xdeadbeef);
924 res = EnumFormsA(hprinter, level, buffer, cbBuf, NULL, &pcReturned);
926 "(%d) returned %d with %d (expected '0' with "
927 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
928
929 SetLastError(0xdeadbeef);
930 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, NULL);
932 "(%d) returned %d with %d (expected '0' with "
933 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
934
935 SetLastError(0xdeadbeef);
936 res = EnumFormsA(0, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
938 "(%d) returned %d with %d (expected '0' with "
939 "ERROR_INVALID_HANDLE)\n", level, res, GetLastError());
940
942 } /* for(level ... */
943
944 ClosePrinter(hprinter);
945}
946
947/* ########################### */
948
949static void test_EnumMonitors(void)
950{
951 DWORD res;
953 DWORD cbBuf;
955 DWORD pcReturned;
956 DWORD level;
957
958 /* valid levels are 1 and 2 */
959 for(level = 0; level < 4; level++) {
960 cbBuf = MAGIC_DEAD;
961 pcReturned = MAGIC_DEAD;
963 res = EnumMonitorsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
965 /* not implemented yet in wine */
966 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue;
967
968
969 /* use only a short test when testing an invalid level */
970 if(!level || (level > 2)) {
971 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
972 (res && (pcReturned == 0)),
973 "(%d) returned %d with %d and 0x%08x (expected '0' with "
974 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
975 level, res, GetLastError(), pcReturned);
976 continue;
977 }
978
979 /* Level 2 is not supported on win9x */
980 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
981 skip("Level %d not supported\n", level);
982 continue;
983 }
984
986 "(%d) returned %d with %d (expected '0' with "
987 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
988
989 if (!cbBuf) {
990 skip("no valid buffer size returned\n");
991 continue;
992 }
993
994 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
995 if (buffer == NULL) continue;
996
999 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
1000 ok(res, "(%d) returned %d with %d (expected '!=0')\n",
1001 level, res, GetLastError());
1002 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n",
1003 level, pcbNeeded, cbBuf);
1004 /* We can validate the returned Data with the Registry here */
1005
1006
1008 pcReturned = MAGIC_DEAD;
1010 res = EnumMonitorsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1011 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level,
1012 res, GetLastError());
1013 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
1014 pcbNeeded, cbBuf);
1015
1018 res = EnumMonitorsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1020 "(%d) returned %d with %d (expected '0' with "
1021 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1022
1023 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level,
1024 pcbNeeded, cbBuf);
1025
1026/*
1027 Do not add the next test:
1028 w2k+: RPC_X_NULL_REF_POINTER
1029 NT3.5: ERROR_INVALID_USER_BUFFER
1030 win9x: crash in winspool.drv
1031
1032 res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1033*/
1034
1037 pcReturned = MAGIC_DEAD;
1038 res = EnumMonitorsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
1040 "(%d) returned %d with %d (expected '!=0' or '0' with "
1041 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1042
1044 pcReturned = MAGIC_DEAD;
1048 "(%d) returned %d with %d (expected '!=0' or '0' with "
1049 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1050
1052 } /* for(level ... */
1053}
1054
1055/* ########################### */
1056
1057static void test_EnumPorts(void)
1058{
1059 DWORD res;
1060 DWORD level;
1061 LPBYTE buffer;
1062 DWORD cbBuf;
1064 DWORD pcReturned;
1065
1066 /* valid levels are 1 and 2 */
1067 for(level = 0; level < 4; level++) {
1068
1069 cbBuf = 0xdeadbeef;
1070 pcReturned = 0xdeadbeef;
1071 SetLastError(0xdeadbeef);
1072 res = EnumPortsA(NULL, level, NULL, 0, &cbBuf, &pcReturned);
1073 if (is_spooler_deactivated(res, GetLastError())) return;
1074
1075 /* use only a short test when testing an invalid level */
1076 if(!level || (level > 2)) {
1077 /* NT: ERROR_INVALID_LEVEL, 9x: success */
1078 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1079 (res && (pcReturned == 0)),
1080 "(%d) returned %d with %d and 0x%08x (expected '0' with "
1081 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1082 level, res, GetLastError(), pcReturned);
1083 continue;
1084 }
1085
1086
1087 /* Level 2 is not supported on NT 3.x */
1088 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
1089 skip("Level %d not supported\n", level);
1090 continue;
1091 }
1092
1094 "(%d) returned %d with %d (expected '0' with "
1095 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1096
1097 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2);
1098 if (buffer == NULL) continue;
1099
1100 pcbNeeded = 0xdeadbeef;
1101 SetLastError(0xdeadbeef);
1102 res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
1103 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
1104 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1105 /* ToDo: Compare the returned Data with the Registry / "win.ini",[Ports] here */
1106
1107 pcbNeeded = 0xdeadbeef;
1108 pcReturned = 0xdeadbeef;
1109 SetLastError(0xdeadbeef);
1110 res = EnumPortsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1111 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError());
1112 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1113
1114 pcbNeeded = 0xdeadbeef;
1115 SetLastError(0xdeadbeef);
1116 res = EnumPortsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1118 "(%d) returned %d with %d (expected '0' with "
1119 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError());
1120 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1121
1122 /*
1123 Do not add this test:
1124 res = EnumPortsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1125 w2k+: RPC_X_NULL_REF_POINTER
1126 NT3.5: ERROR_INVALID_USER_BUFFER
1127 win9x: crash in winspool.drv
1128 */
1129
1130 SetLastError(0xdeadbeef);
1131 res = EnumPortsA(NULL, level, buffer, cbBuf, NULL, &pcReturned);
1132 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
1133 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
1134 ( res && (GetLastError() == ERROR_SUCCESS) ),
1135 "(%d) returned %d with %d (expected '0' with "
1136 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1137 level, res, GetLastError());
1138
1139
1140 SetLastError(0xdeadbeef);
1141 res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL);
1142 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */
1143 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) ||
1144 ( res && (GetLastError() == ERROR_SUCCESS) ),
1145 "(%d) returned %d with %d (expected '0' with "
1146 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n",
1147 level, res, GetLastError());
1148
1150 }
1151}
1152
1153/* ########################### */
1154
1156{
1157 static char env_all[] = "all";
1158
1159 DWORD res;
1160 LPBYTE buffer;
1161 DWORD cbBuf;
1163 DWORD pcReturned;
1164 DWORD level;
1165
1166 /* 1-3 for w95/w98/NT4; 1-3+6 for me; 1-6 for w2k/xp/2003; 1-6+8 for vista */
1167 for(level = 0; level < 10; level++) {
1168 cbBuf = 0xdeadbeef;
1169 pcReturned = 0xdeadbeef;
1170 SetLastError(0xdeadbeef);
1171 res = EnumPrinterDriversA(NULL, NULL, level, NULL, 0, &cbBuf, &pcReturned);
1172 if (is_spooler_deactivated(res, GetLastError())) return;
1173
1174 /* use only a short test when testing an invalid level */
1175 if(!level || (level == 7) || (level > 8)) {
1176
1177 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1178 (res && (pcReturned == 0)),
1179 "(%d) got %u with %u and 0x%x "
1180 "(expected '0' with ERROR_INVALID_LEVEL or '!=0' and 0x0)\n",
1181 level, res, GetLastError(), pcReturned);
1182 continue;
1183 }
1184
1185 /* some levels are not supported on all windows versions */
1186 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) {
1187 skip("Level %d not supported\n", level);
1188 continue;
1189 }
1190
1191 ok( ((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) ||
1192 (res && (default_printer == NULL)),
1193 "(%u) got %u with %u for %s (expected '0' with "
1194 "ERROR_INSUFFICIENT_BUFFER or '!= 0' without a printer)\n",
1196
1197 if (!cbBuf) {
1198 skip("no valid buffer size returned\n");
1199 continue;
1200 }
1201
1202 /* EnumPrinterDriversA returns the same number of bytes as EnumPrinterDriversW */
1203 if (pEnumPrinterDriversW)
1204 {
1205 DWORD double_needed;
1206 DWORD double_returned;
1207 pEnumPrinterDriversW(NULL, NULL, level, NULL, 0, &double_needed, &double_returned);
1208 ok(double_needed == cbBuf, "level %d: EnumPrinterDriversA returned different size %d than EnumPrinterDriversW (%d)\n", level, cbBuf, double_needed);
1209 }
1210
1211 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4);
1212 if (buffer == NULL) continue;
1213
1214 SetLastError(0xdeadbeef);
1215 pcbNeeded = 0xdeadbeef;
1216 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned);
1217 ok(res, "(%u) got %u with %u (expected '!=0')\n", level, res, GetLastError());
1218 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf);
1219
1220 /* validate the returned data here */
1221 if (level > 1) {
1223
1224 ok( strrchr(di->pDriverPath, '\\') != NULL,
1225 "(%u) got %s for %s (expected a full path)\n",
1226 level, di->pDriverPath, di->pName);
1227
1228 }
1229
1230 SetLastError(0xdeadbeef);
1231 pcReturned = 0xdeadbeef;
1232 pcbNeeded = 0xdeadbeef;
1233 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1234 ok(res, "(%u) got %u with %u (expected '!=0')\n", level, res, GetLastError());
1235 ok(pcbNeeded == cbBuf, "(%u) returned %u (expected %u)\n", level, pcbNeeded, cbBuf);
1236
1237 SetLastError(0xdeadbeef);
1238 pcbNeeded = 0xdeadbeef;
1239 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1241 "(%u) got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1242 level, res, GetLastError());
1243 ok(pcbNeeded == cbBuf, "(%u) returned %u (expected %u)\n", level, pcbNeeded, cbBuf);
1244
1245/*
1246 Do not add the next test:
1247 NT: ERROR_INVALID_USER_BUFFER
1248 win9x: crash or 100% CPU
1249
1250 res = EnumPrinterDriversA(NULL, NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned);
1251*/
1252
1253 SetLastError(0xdeadbeef);
1254 pcbNeeded = 0xdeadbeef;
1255 pcReturned = 0xdeadbeef;
1256 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, NULL, &pcReturned);
1258 "(%u) got %u with %u (expected '!=0' or '0' with "
1259 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1260
1261 pcbNeeded = 0xdeadbeef;
1262 pcReturned = 0xdeadbeef;
1263 SetLastError(0xdeadbeef);
1266 "(%u) got %u with %u (expected '!=0' or '0' with "
1267 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError());
1268
1270 } /* for(level ... */
1271
1272 pcbNeeded = 0;
1273 pcReturned = 0;
1274 SetLastError(0xdeadbeef);
1275 res = EnumPrinterDriversA(NULL, env_all, 1, NULL, 0, &pcbNeeded, &pcReturned);
1276 if (res)
1277 {
1278 skip("no printer drivers found\n");
1279 return;
1280 }
1282 {
1283 win_skip("NT4 and below don't support the 'all' environment value\n");
1284 return;
1285 }
1286 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "unexpected error %u\n", GetLastError());
1287
1289 res = EnumPrinterDriversA(NULL, env_all, 1, buffer, pcbNeeded, &pcbNeeded, &pcReturned);
1290 ok(res, "EnumPrinterDriversA failed %u\n", GetLastError());
1291 if (res && pcReturned > 0)
1292 {
1294 ok((LPBYTE) di_1->pName == NULL || (LPBYTE) di_1->pName < buffer ||
1295 (LPBYTE) di_1->pName >= (LPBYTE)(di_1 + pcReturned),
1296 "Driver Information not in sequence; pName %p, top of data %p\n",
1297 di_1->pName, di_1 + pcReturned);
1298 }
1299
1301}
1302
1303/* ########################### */
1304
1306{
1307 DWORD res;
1308 LPBYTE buffer;
1309 DWORD cbBuf;
1311 DWORD pcReturned;
1312
1313
1314 cbBuf = 0xdeadbeef;
1315 pcReturned = 0xdeadbeef;
1316 SetLastError(0xdeadbeef);
1317 res = EnumPrintProcessorsA(NULL, NULL, 1, NULL, 0, &cbBuf, &pcReturned);
1318 if (is_spooler_deactivated(res, GetLastError())) return;
1319
1320 if (res && !cbBuf) {
1321 skip("No Printprocessor installed\n");
1322 return;
1323 }
1324
1326 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1327 res, GetLastError());
1328
1329 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4);
1330 if (buffer == NULL)
1331 return;
1332
1333 SetLastError(0xdeadbeef);
1334 pcbNeeded = 0xdeadbeef;
1335 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1336 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1337 /* validate the returned data here. */
1338
1339
1340 SetLastError(0xdeadbeef);
1341 pcReturned = 0xdeadbeef;
1342 pcbNeeded = 0xdeadbeef;
1343 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf+1, &pcbNeeded, &pcReturned);
1344 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1345
1346 SetLastError(0xdeadbeef);
1347 pcbNeeded = 0xdeadbeef;
1348 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded, &pcReturned);
1350 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1351 res, GetLastError());
1352
1353 /* only level 1 is valid */
1354 if (0) {
1355 /* both tests crash on win98se */
1356 SetLastError(0xdeadbeef);
1357 pcbNeeded = 0xdeadbeef;
1358 pcReturned = 0xdeadbeef;
1359 res = EnumPrintProcessorsA(NULL, NULL, 0, buffer, cbBuf, &pcbNeeded, &pcReturned);
1361 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1362 res, GetLastError());
1363
1364 SetLastError(0xdeadbeef);
1365 pcbNeeded = 0xdeadbeef;
1366 res = EnumPrintProcessorsA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded, &pcReturned);
1368 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
1369 res, GetLastError());
1370 }
1371
1372 /* an empty environment is ignored */
1373 SetLastError(0xdeadbeef);
1374 pcbNeeded = 0xdeadbeef;
1375 res = EnumPrintProcessorsA(NULL, empty, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1376 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError());
1377
1378 /* the environment is checked */
1379 SetLastError(0xdeadbeef);
1380 pcbNeeded = 0xdeadbeef;
1381 res = EnumPrintProcessorsA(NULL, invalid_env, 1, buffer, cbBuf, &pcbNeeded, &pcReturned);
1382 /* NT5: ERROR_INVALID_ENVIRONMENT, NT4: res != 0, 9x: ERROR_INVALID_PARAMETER */
1383 ok( broken(res) || /* NT4 */
1386 "got %u with %u (expected '0' with ERROR_INVALID_ENVIRONMENT or "
1387 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1388
1389
1390 /* failure-Codes for NULL */
1391 SetLastError(0xdeadbeef);
1392 pcbNeeded = 0xdeadbeef;
1393 pcReturned = 0xdeadbeef;
1394 res = EnumPrintProcessorsA(NULL, NULL, 1, NULL, cbBuf, &pcbNeeded, &pcReturned);
1395 todo_wine {
1397 "got %u with %u (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1398 res, GetLastError());
1399 }
1400
1401 SetLastError(0xdeadbeef);
1402 pcbNeeded = 0xdeadbeef;
1403 pcReturned = 0xdeadbeef;
1404 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, NULL, &pcReturned);
1405 /* the NULL is ignored on win9x */
1407 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1408 res, GetLastError());
1409
1410 pcbNeeded = 0xdeadbeef;
1411 pcReturned = 0xdeadbeef;
1412 SetLastError(0xdeadbeef);
1414 /* the NULL is ignored on win9x */
1416 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n",
1417 res, GetLastError());
1418
1420
1421}
1422
1423/* ########################### */
1424
1425static void test_GetDefaultPrinter(void)
1426{
1427 BOOL retval;
1429 DWORD size;
1431
1432 if (!pGetDefaultPrinterA) return;
1433 /* only supported on NT like OSes starting with win2k */
1434
1436 retval = pGetDefaultPrinterA(buffer, &exact);
1437 if (!retval || !exact || !*buffer ||
1438 (ERROR_SUCCESS != GetLastError())) {
1441 trace("this test requires a default printer to be set\n");
1442 else {
1443 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
1444 "function returned %s\n"
1445 "last error 0x%08x\n"
1446 "returned buffer size 0x%08x\n"
1447 "returned buffer content %s\n",
1448 retval ? "true" : "false", GetLastError(), exact, buffer);
1449 }
1450 return;
1451 }
1453 retval = pGetDefaultPrinterA(NULL, NULL);
1454 ok( !retval, "function result wrong! False expected\n");
1456 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1457 GetLastError());
1458
1460 retval = pGetDefaultPrinterA(buffer, NULL);
1461 ok( !retval, "function result wrong! False expected\n");
1463 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n",
1464 GetLastError());
1465
1467 size = 0;
1468 retval = pGetDefaultPrinterA(NULL, &size);
1469 ok( !retval, "function result wrong! False expected\n");
1471 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1472 GetLastError());
1473 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1474 exact, size);
1475
1478 retval = pGetDefaultPrinterA(NULL, &size);
1479 ok( !retval, "function result wrong! False expected\n");
1481 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1482 GetLastError());
1483 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1484 exact, size);
1485
1486 size = 0;
1487 retval = pGetDefaultPrinterA(buffer, &size);
1488 ok( !retval, "function result wrong! False expected\n");
1490 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n",
1491 GetLastError());
1492 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1493 exact, size);
1494
1495 size = exact;
1496 retval = pGetDefaultPrinterA(buffer, &size);
1497 ok( retval, "function result wrong! True expected\n");
1498 ok( size == exact, "Parameter size wrong! %d expected got %d\n",
1499 exact, size);
1500}
1501
1503{
1504 LPBYTE buffer = NULL;
1505 DWORD cbBuf = 0, pcbNeeded = 0;
1506 BOOL res;
1507
1508
1510 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
1511 if (is_spooler_deactivated(res, GetLastError())) return;
1512
1513 trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n",
1514 res, GetLastError(), cbBuf);
1515
1517 "returned %d with lasterror=%d (expected '0' with "
1518 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
1519
1520 if (!cbBuf) {
1521 skip("no valid buffer size returned\n");
1522 return;
1523 }
1524
1525 buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
1526 if (buffer == NULL) return ;
1527
1529 ok( res, "expected result != 0, got %d\n", res);
1530 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1531 pcbNeeded, cbBuf);
1532
1534 ok( res, "expected result != 0, got %d\n", res);
1535 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1536 pcbNeeded, cbBuf);
1537
1540 ok( !res , "expected result == 0, got %d\n", res);
1541 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n",
1542 pcbNeeded, cbBuf);
1543
1545 "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n",
1546 GetLastError());
1547
1548/*
1549 Do not add the next test:
1550 XPsp2: crash in this app, when the spooler is not running
1551 NT3.5: ERROR_INVALID_USER_BUFFER
1552 win9x: ERROR_INVALID_PARAMETER
1553
1554 pcbNeeded = MAGIC_DEAD;
1555 SetLastError(MAGIC_DEAD);
1556 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
1557*/
1558
1561 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1562 NT: RPC_X_NULL_REF_POINTER */
1565 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1566 "or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1567
1570 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1571 NT: RPC_X_NULL_REF_POINTER */
1574 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER "
1575 "or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1576
1577 /* with a valid buffer, but level is too large */
1578 buffer[0] = '\0';
1581
1582 /* Level not checked in win9x and wine:*/
1583 if((res != FALSE) && buffer[0])
1584 {
1585 trace("Level '2' not checked '%s'\n", buffer);
1586 }
1587 else
1588 {
1590 "returned %d with lasterror=%d (expected '0' with "
1591 "ERROR_INVALID_LEVEL)\n", res, GetLastError());
1592 }
1593
1594 /* printing environments are case insensitive */
1595 /* "Windows 4.0" is valid for win9x and NT */
1596 buffer[0] = '\0';
1599 buffer, cbBuf*2, &pcbNeeded);
1600
1602 cbBuf = pcbNeeded;
1603 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1604 if (buffer == NULL) return ;
1605
1608 buffer, cbBuf*2, &pcbNeeded);
1609 }
1610
1611 ok(res && buffer[0], "returned %d with "
1612 "lasterror=%d and len=%d (expected '1' with 'len > 0')\n",
1613 res, GetLastError(), lstrlenA((char *)buffer));
1614
1615 buffer[0] = '\0';
1618 buffer, cbBuf*2, &pcbNeeded);
1619
1621 cbBuf = pcbNeeded;
1622 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
1623 if (buffer == NULL) return ;
1624
1625 buffer[0] = '\0';
1628 buffer, cbBuf*2, &pcbNeeded);
1629 }
1630
1631 /* "Windows NT x86" is invalid for win9x */
1632 ok( (res && buffer[0]) ||
1634 "returned %d with lasterror=%d and len=%d (expected '!= 0' with "
1635 "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
1636 res, GetLastError(), lstrlenA((char *)buffer));
1637
1638 /* A setup program (PDFCreator_0.8.0) use empty strings */
1641 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1642
1645 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1646
1649 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() );
1650
1652}
1653
1654/* ##### */
1655
1657{
1658 LPBYTE buffer = NULL;
1659 DWORD cbBuf = 0;
1660 DWORD pcbNeeded = 0;
1661 BOOL res;
1662
1663
1664 SetLastError(0xdeadbeef);
1665 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf);
1666 if (is_spooler_deactivated(res, GetLastError())) return;
1667
1669 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1670 res, GetLastError());
1671
1672 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2);
1673 if(buffer == NULL) return;
1674
1675 buffer[0] = '\0';
1676 SetLastError(0xdeadbeef);
1678 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1679
1680 SetLastError(0xdeadbeef);
1681 buffer[0] = '\0';
1683 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1684
1685 /* Buffer too small */
1686 buffer[0] = '\0';
1687 SetLastError(0xdeadbeef);
1690 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n",
1691 res, GetLastError());
1692
1693 if (0)
1694 {
1695 /* XPsp2: the program will crash here, when the spooler is not running */
1696 /* GetPrinterDriverDirectory has the same bug */
1697 pcbNeeded = 0;
1698 SetLastError(0xdeadbeef);
1700 /* NT: ERROR_INVALID_USER_BUFFER, 9x: res != 0 */
1702 broken(res),
1703 "returned %d with %d (expected '0' with ERROR_INVALID_USER_BUFFER)\n",
1704 res, GetLastError());
1705 }
1706
1707 buffer[0] = '\0';
1708 SetLastError(0xdeadbeef);
1710 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1711 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1714 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1715 "or with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1716
1717 buffer[0] = '\0';
1718 SetLastError(0xdeadbeef);
1720 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER,
1721 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */
1724 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER "
1725 "or with ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1726
1727 /* with a valid buffer, but level is invalid */
1728 buffer[0] = '\0';
1729 SetLastError(0xdeadbeef);
1731 /* Level is ignored in win9x*/
1732 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1733 broken(res && buffer[0]),
1734 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1735 res, GetLastError());
1736
1737 buffer[0] = '\0';
1738 SetLastError(0xdeadbeef);
1740 /* Level is ignored on win9x*/
1741 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) ||
1742 broken(res && buffer[0]),
1743 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n",
1744 res, GetLastError());
1745
1746 /* Empty environment is the same as the default environment */
1747 buffer[0] = '\0';
1748 SetLastError(0xdeadbeef);
1750 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1751
1752 /* "Windows 4.0" is valid for win9x and NT */
1753 buffer[0] = '\0';
1754 SetLastError(0xdeadbeef);
1756 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1757
1758
1759 /* "Windows NT x86" is invalid for win9x */
1760 buffer[0] = '\0';
1761 SetLastError(0xdeadbeef);
1764 "returned %d with %d (expected '!= 0' or '0' with "
1765 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError());
1766
1767 /* invalid on all systems */
1768 buffer[0] = '\0';
1769 SetLastError(0xdeadbeef);
1772 "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n",
1773 res, GetLastError());
1774
1775 /* Empty servername is the same as the local computer */
1776 buffer[0] = '\0';
1777 SetLastError(0xdeadbeef);
1779 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
1780
1781 /* invalid on all systems */
1782 buffer[0] = '\0';
1783 SetLastError(0xdeadbeef);
1785 ok( !res, "expected failure\n");
1786 ok( GetLastError() == RPC_S_SERVER_UNAVAILABLE || /* NT */
1787 GetLastError() == ERROR_INVALID_PARAMETER || /* 9x */
1788 GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista */
1789 "unexpected last error %d\n", GetLastError());
1790
1792}
1793
1794/* ##### */
1795
1796static void test_OpenPrinter(void)
1797{
1799 HANDLE hprinter;
1800 DWORD res;
1801
1804 if (is_spooler_deactivated(res, GetLastError())) return;
1805
1807 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n",
1808 res, GetLastError());
1809
1810
1811 /* Get Handle for the local Printserver (NT only)*/
1812 hprinter = (HANDLE) MAGIC_DEAD;
1814 res = OpenPrinterA(NULL, &hprinter, NULL);
1815 if (is_spooler_deactivated(res, GetLastError())) return;
1817 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1818 res, GetLastError());
1819 if(res) {
1820 ClosePrinter(hprinter);
1821
1822 defaults.pDatatype=NULL;
1823 defaults.pDevMode=NULL;
1824
1825 defaults.DesiredAccess=0;
1826 hprinter = (HANDLE) MAGIC_DEAD;
1828 res = OpenPrinterA(NULL, &hprinter, &defaults);
1829 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1830 if (res) ClosePrinter(hprinter);
1831
1832 defaults.DesiredAccess=-1;
1833 hprinter = (HANDLE) MAGIC_DEAD;
1835 res = OpenPrinterA(NULL, &hprinter, &defaults);
1836 todo_wine {
1838 "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n",
1839 res, GetLastError());
1840 }
1841 if (res) ClosePrinter(hprinter);
1842
1843 }
1844
1845
1846 if (local_server != NULL) {
1847 hprinter = (HANDLE) 0xdeadbeef;
1848 SetLastError(0xdeadbeef);
1849 res = OpenPrinterA(local_server, &hprinter, NULL);
1851 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
1852 res, GetLastError());
1853 if(res) ClosePrinter(hprinter);
1854 }
1855
1856 /* Invalid Printername */
1857 hprinter = (HANDLE) MAGIC_DEAD;
1859 res = OpenPrinterA(illegal_name, &hprinter, NULL);
1862 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or"
1863 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1864 if(res) ClosePrinter(hprinter);
1865
1866 hprinter = (HANDLE) MAGIC_DEAD;
1868 res = OpenPrinterA(empty, &hprinter, NULL);
1869 /* NT: ERROR_INVALID_PRINTER_NAME, 9x: ERROR_INVALID_PARAMETER */
1870 ok( !res &&
1873 "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME"
1874 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1875 if(res) ClosePrinter(hprinter);
1876
1877
1878 /* get handle for the default printer */
1879 if (default_printer)
1880 {
1881 hprinter = (HANDLE) MAGIC_DEAD;
1883 res = OpenPrinterA(default_printer, &hprinter, NULL);
1885 {
1886 trace("The service 'Spooler' is required for '%s'\n", default_printer);
1887 return;
1888 }
1889 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError());
1890 if(res) ClosePrinter(hprinter);
1891
1894 /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
1896 "returned %d with %d (expected '!=0' or '0' with "
1897 "ERROR_INVALID_PARAMETER)\n", res, GetLastError());
1898
1899 defaults.pDatatype=NULL;
1900 defaults.pDevMode=NULL;
1901 defaults.DesiredAccess=0;
1902
1903 hprinter = (HANDLE) MAGIC_DEAD;
1905 res = OpenPrinterA(default_printer, &hprinter, &defaults);
1907 "returned %d with %d (expected '!=0' or '0' with "
1908 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1909 if(res) ClosePrinter(hprinter);
1910
1911 defaults.pDatatype = empty;
1912
1913 hprinter = (HANDLE) MAGIC_DEAD;
1915 res = OpenPrinterA(default_printer, &hprinter, &defaults);
1916 /* stop here, when a remote Printserver has no RPC-Service running */
1917 if (is_spooler_deactivated(res, GetLastError())) return;
1920 "returned %d with %d (expected '!=0' or '0' with: "
1921 "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
1922 res, GetLastError());
1923 if(res) ClosePrinter(hprinter);
1924
1925
1926 defaults.pDatatype=NULL;
1927 defaults.DesiredAccess=PRINTER_ACCESS_USE;
1928
1929 hprinter = (HANDLE) MAGIC_DEAD;
1931 res = OpenPrinterA(default_printer, &hprinter, &defaults);
1933 "returned %d with %d (expected '!=0' or '0' with "
1934 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1935 if(res) ClosePrinter(hprinter);
1936
1937
1938 defaults.DesiredAccess=PRINTER_ALL_ACCESS;
1939 hprinter = (HANDLE) MAGIC_DEAD;
1941 res = OpenPrinterA(default_printer, &hprinter, &defaults);
1943 "returned %d with %d (expected '!=0' or '0' with "
1944 "ERROR_ACCESS_DENIED)\n", res, GetLastError());
1945 if(res) ClosePrinter(hprinter);
1946 }
1947
1948}
1949
1950
1951static void test_SetDefaultPrinter(void)
1952{
1953 DWORD res;
1956 CHAR org_value[DEFAULT_PRINTER_SIZE];
1957
1958 if (!default_printer)
1959 {
1960 skip("There is no default printer installed\n");
1961 return;
1962 }
1963
1964 if (!pSetDefaultPrinterA) return;
1965 /* only supported on win2k and above */
1966
1967 /* backup the original value */
1968 org_value[0] = '\0';
1970 res = GetProfileStringA("windows", "device", NULL, org_value, size);
1971 ok(res, "GetProfileString error %d\n", GetLastError());
1972
1973 /* first part: with the default Printer */
1975 res = pSetDefaultPrinterA("no_printer_with_this_name");
1976 if (is_spooler_deactivated(res, GetLastError())) return;
1977
1978 /* Not implemented in wine */
1980 trace("SetDefaultPrinterA() not implemented yet.\n");
1981 return;
1982 }
1983
1985 "returned %d with %d (expected '0' with "
1986 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1987
1988 WriteProfileStringA("windows", "device", org_value);
1990 res = pSetDefaultPrinterA("");
1992 "returned %d with %d (expected '!=0' or '0' with "
1993 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
1994
1995 WriteProfileStringA("windows", "device", org_value);
1997 res = pSetDefaultPrinterA(NULL);
1999 "returned %d with %d (expected '!=0' or '0' with "
2000 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2001
2002 WriteProfileStringA("windows", "device", org_value);
2004 res = pSetDefaultPrinterA(default_printer);
2006 "returned %d with %d (expected '!=0' or '0' with "
2007 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2008
2009
2010 /* second part: always without a default Printer */
2011 WriteProfileStringA("windows", "device", NULL);
2013 res = pSetDefaultPrinterA("no_printer_with_this_name");
2014
2016 "returned %d with %d (expected '0' with "
2017 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2018
2019 WriteProfileStringA("windows", "device", NULL);
2021 res = pSetDefaultPrinterA("");
2023 goto restore_old_printer;
2024
2025 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2027 "returned %d with %d (expected '!=0' or '0' with "
2028 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2029
2030 WriteProfileStringA("windows", "device", NULL);
2032 res = pSetDefaultPrinterA(NULL);
2033 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */
2035 "returned %d with %d (expected '!=0' or '0' with "
2036 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2037
2038 WriteProfileStringA("windows", "device", NULL);
2040 res = pSetDefaultPrinterA(default_printer);
2042 "returned %d with %d (expected '!=0' or '0' with "
2043 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
2044
2045 /* restore the original value */
2046restore_old_printer:
2047 res = pSetDefaultPrinterA(default_printer); /* the nice way */
2048 ok(res, "SetDefaultPrinter error %d\n", GetLastError());
2049 WriteProfileStringA("windows", "device", org_value); /* the old way */
2050
2051 buffer[0] = '\0';
2053 res = GetProfileStringA("windows", "device", NULL, buffer, size);
2054 ok(res, "GetProfileString error %d\n", GetLastError());
2055 ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value);
2056
2057}
2058
2059/* ########################### */
2060
2062{
2063 DWORD res;
2064 HANDLE hXcv;
2065 BYTE buffer[MAX_PATH + 4];
2066 DWORD needed;
2067 DWORD status;
2068 DWORD len;
2070
2071 /* api is not present before w2k */
2072 if (pXcvDataW == NULL) return;
2073
2074 pd.pDatatype = NULL;
2075 pd.pDevMode = NULL;
2077
2078 hXcv = NULL;
2079 SetLastError(0xdeadbeef);
2081 if (is_spooler_deactivated(res, GetLastError())) return;
2082 if (is_access_denied(res, GetLastError())) return;
2083
2084 ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv);
2085 if (!res) return;
2086
2087 /* ask for needed size */
2088 needed = (DWORD) 0xdeadbeef;
2089 status = (DWORD) 0xdeadbeef;
2090 SetLastError(0xdeadbeef);
2091 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, NULL, 0, &needed, &status);
2092 ok( res && (status == ERROR_INSUFFICIENT_BUFFER) && (needed <= MAX_PATH),
2093 "returned %d with %u and %u for status %u (expected '!= 0' and "
2094 "'<= MAX_PATH' for status ERROR_INSUFFICIENT_BUFFER)\n",
2095 res, GetLastError(), needed, status);
2096
2097 if (needed > MAX_PATH) {
2099 skip("buffer overflow (%u)\n", needed);
2100 return;
2101 }
2102 len = needed; /* Size is in bytes */
2103
2104 /* the command is required */
2105 needed = (DWORD) 0xdeadbeef;
2106 status = (DWORD) 0xdeadbeef;
2107 SetLastError(0xdeadbeef);
2108 res = pXcvDataW(hXcv, emptyW, NULL, 0, NULL, 0, &needed, &status);
2110 "returned %d with %u and %u for status %u (expected '!= 0' with "
2111 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), needed, status);
2112
2113 needed = (DWORD) 0xdeadbeef;
2114 status = (DWORD) 0xdeadbeef;
2115 SetLastError(0xdeadbeef);
2116 res = pXcvDataW(hXcv, NULL, NULL, 0, buffer, MAX_PATH, &needed, &status);
2118 "returned %d with %u and %u for status %u (expected '0' with "
2119 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2120
2121 /* "PDWORD needed" is checked before RPC-Errors */
2122 needed = (DWORD) 0xdeadbeef;
2123 status = (DWORD) 0xdeadbeef;
2124 SetLastError(0xdeadbeef);
2125 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, NULL, &status);
2127 "returned %d with %u and %u for status %u (expected '0' with "
2128 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), needed, status);
2129
2130 needed = (DWORD) 0xdeadbeef;
2131 status = (DWORD) 0xdeadbeef;
2132 SetLastError(0xdeadbeef);
2133 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, NULL, len, &needed, &status);
2135 "returned %d with %u and %u for status %u (expected '0' with "
2136 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2137
2138 needed = (DWORD) 0xdeadbeef;
2139 status = (DWORD) 0xdeadbeef;
2140 SetLastError(0xdeadbeef);
2141 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, &needed, NULL);
2143 "returned %d with %u and %u for status %u (expected '0' with "
2144 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status);
2145
2146 /* off by one: larger */
2147 needed = (DWORD) 0xdeadbeef;
2148 status = (DWORD) 0xdeadbeef;
2149 SetLastError(0xdeadbeef);
2150 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len+1, &needed, &status);
2151 ok( res && (status == ERROR_SUCCESS),
2152 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2153 "ERROR_SUCCESS)\n", res, GetLastError(), needed, status);
2154
2155 /* off by one: smaller */
2156 /* the buffer is not modified for NT4, w2k, XP */
2157 needed = (DWORD) 0xdeadbeef;
2158 status = (DWORD) 0xdeadbeef;
2159 SetLastError(0xdeadbeef);
2160 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len-1, &needed, &status);
2162 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2163 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError(), needed, status);
2164
2165
2166 /* Normal use. The DLL-Name without a Path is returned */
2167 memset(buffer, 0, len);
2168 needed = (DWORD) 0xdeadbeef;
2169 status = (DWORD) 0xdeadbeef;
2170 SetLastError(0xdeadbeef);
2171 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, &needed, &status);
2172 ok( res && (status == ERROR_SUCCESS),
2173 "returned %d with %u and %u for status %u (expected '!= 0' for status "
2174 "ERROR_SUCCESS)\n", res, GetLastError(), needed, status);
2175
2177}
2178
2179/* ########################### */
2180
2182{
2183 DWORD res;
2184 HANDLE hXcv;
2185 DWORD needed;
2186 DWORD status;
2188
2189 /* api is not present before w2k */
2190 if (pXcvDataW == NULL) return;
2191
2192 pd.pDatatype = NULL;
2193 pd.pDevMode = NULL;
2195
2196 hXcv = NULL;
2197 SetLastError(0xdeadbeef);
2199 if (is_spooler_deactivated(res, GetLastError())) return;
2200 if (is_access_denied(res, GetLastError())) return;
2201
2202 ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv);
2203 if (!res) return;
2204
2205
2206 /* "PDWORD needed" is always required */
2207 needed = (DWORD) 0xdeadbeef;
2208 status = (DWORD) 0xdeadbeef;
2209 SetLastError(0xdeadbeef);
2210 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt1W, sizeof(portname_lpt1W), NULL, 0, NULL, &status);
2212 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_INVALID_PARAMETER)\n",
2213 res, GetLastError(), needed, status);
2214
2215 /* an empty name is not allowed */
2216 needed = (DWORD) 0xdeadbeef;
2217 status = (DWORD) 0xdeadbeef;
2218 SetLastError(0xdeadbeef);
2219 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) emptyW, sizeof(emptyW), NULL, 0, &needed, &status);
2221 "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2222 "ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND)\n",
2223 res, GetLastError(), needed, status);
2224
2225 /* a directory is not allowed */
2226 needed = (DWORD) 0xdeadbeef;
2227 status = (DWORD) 0xdeadbeef;
2228 SetLastError(0xdeadbeef);
2229 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) tempdirW, (lstrlenW(tempdirW) + 1) * sizeof(WCHAR), NULL, 0, &needed, &status);
2230 /* XP: ERROR_PATH_NOT_FOUND, w2k ERROR_ACCESS_DENIED */
2232 "returned %d with %u and %u for status %u (expected '!= 0' for status: "
2233 "ERROR_PATH_NOT_FOUND or ERROR_ACCESS_DENIED)\n",
2234 res, GetLastError(), needed, status);
2235
2236 /* more valid well known ports */
2237 needed = (DWORD) 0xdeadbeef;
2238 status = (DWORD) 0xdeadbeef;
2239 SetLastError(0xdeadbeef);
2240 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt1W, sizeof(portname_lpt1W), NULL, 0, &needed, &status);
2241 ok( res && (status == ERROR_SUCCESS),
2242 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2243 res, GetLastError(), needed, status);
2244
2245 needed = (DWORD) 0xdeadbeef;
2246 status = (DWORD) 0xdeadbeef;
2247 SetLastError(0xdeadbeef);
2248 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt2W, sizeof(portname_lpt2W), NULL, 0, &needed, &status);
2249 ok( res && (status == ERROR_SUCCESS),
2250 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2251 res, GetLastError(), needed, status);
2252
2253 needed = (DWORD) 0xdeadbeef;
2254 status = (DWORD) 0xdeadbeef;
2255 SetLastError(0xdeadbeef);
2256 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_com1W, sizeof(portname_com1W), NULL, 0, &needed, &status);
2257 ok( res && (status == ERROR_SUCCESS),
2258 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2259 res, GetLastError(), needed, status);
2260
2261 needed = (DWORD) 0xdeadbeef;
2262 status = (DWORD) 0xdeadbeef;
2263 SetLastError(0xdeadbeef);
2264 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_com2W, sizeof(portname_com2W), NULL, 0, &needed, &status);
2265 ok( res && (status == ERROR_SUCCESS),
2266 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n",
2267 res, GetLastError(), needed, status);
2268
2269 needed = (DWORD) 0xdeadbeef;
2270 status = (DWORD) 0xdeadbeef;
2271 SetLastError(0xdeadbeef);
2272 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_fileW, sizeof(portname_fileW), NULL, 0, &needed, &status);
2273 ok( res && (status == ERROR_SUCCESS),
2274 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2275 res, GetLastError(), needed, status);
2276
2277
2278 /* a normal, writable file is allowed */
2279 needed = (DWORD) 0xdeadbeef;
2280 status = (DWORD) 0xdeadbeef;
2281 SetLastError(0xdeadbeef);
2282 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) tempfileW, (lstrlenW(tempfileW) + 1) * sizeof(WCHAR), NULL, 0, &needed, &status);
2283 ok( res && (status == ERROR_SUCCESS),
2284 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n",
2285 res, GetLastError(), needed, status);
2286
2288}
2289
2290/* ########################### */
2291
2292static void test_GetPrinter(void)
2293{
2294 HANDLE hprn;
2295 BOOL ret;
2296 BYTE *buf;
2297 INT level;
2298 DWORD needed, filled;
2299
2300 if (!default_printer)
2301 {
2302 skip("There is no default printer installed\n");
2303 return;
2304 }
2305
2306 hprn = 0;
2308 if (!ret)
2309 {
2310 skip("Unable to open the default printer (%s)\n", default_printer);
2311 return;
2312 }
2313 ok(hprn != 0, "wrong hprn %p\n", hprn);
2314
2315 for (level = 1; level <= 9; level++)
2316 {
2317 SetLastError(0xdeadbeef);
2318 needed = (DWORD)-1;
2319 ret = GetPrinterA(hprn, level, NULL, 0, &needed);
2320 if (ret)
2321 {
2322 win_skip("Level %d is not supported on Win9x/WinMe\n", level);
2323 ok(GetLastError() == ERROR_SUCCESS, "wrong error %d\n", GetLastError());
2324 ok(needed == 0,"Expected 0, got %d\n", needed);
2325 continue;
2326 }
2327 ok(!ret, "level %d: GetPrinter should fail\n", level);
2328 /* Not all levels are supported on all Windows-Versions */
2330 GetLastError() == ERROR_NOT_SUPPORTED /* Win9x/WinMe */)
2331 {
2332 skip("Level %d not supported\n", level);
2333 continue;
2334 }
2335 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
2336 ok(needed > 0,"not expected needed buffer size %d\n", needed);
2337
2338 /* GetPrinterA returns the same number of bytes as GetPrinterW */
2339 if (!ret && pGetPrinterW && level != 6 && level != 7)
2340 {
2341 DWORD double_needed;
2342 ret = pGetPrinterW(hprn, level, NULL, 0, &double_needed);
2343 ok(!ret, "level %d: GetPrinter error %d\n", level, GetLastError());
2344 ok(double_needed == needed, "level %d: GetPrinterA returned different size %d than GetPrinterW (%d)\n", level, needed, double_needed);
2345 }
2346
2347 buf = HeapAlloc(GetProcessHeap(), 0, needed);
2348
2349 SetLastError(0xdeadbeef);
2350 filled = -1;
2351 ret = GetPrinterA(hprn, level, buf, needed, &filled);
2352 ok(ret, "level %d: GetPrinter error %d\n", level, GetLastError());
2353 ok(needed == filled, "needed %d != filled %d\n", needed, filled);
2354
2355 if (level == 2)
2356 {
2358
2359 ok(pi_2->pPrinterName!= NULL, "not expected NULL ptr\n");
2360 ok(pi_2->pDriverName!= NULL, "not expected NULL ptr\n");
2361
2362 trace("pPrinterName %s\n", pi_2->pPrinterName);
2363 trace("pDriverName %s\n", pi_2->pDriverName);
2364 }
2365
2367 }
2368
2369 SetLastError(0xdeadbeef);
2370 ret = ClosePrinter(hprn);
2371 ok(ret, "ClosePrinter error %d\n", GetLastError());
2372}
2373
2374/* ########################### */
2375
2376static void test_GetPrinterData(void)
2377{
2378 HANDLE hprn = 0;
2379 DWORD res;
2380 DWORD type;
2381 CHAR buffer[MAX_PATH + 1];
2382 DWORD needed;
2383 DWORD len;
2384
2385 /* ToDo: test parameter validation, test with the default printer */
2386
2387 SetLastError(0xdeadbeef);
2388 res = OpenPrinterA(NULL, &hprn, NULL);
2389 if (!res)
2390 {
2391 return;
2392 }
2393
2394 memset(buffer, '#', sizeof(buffer));
2395 buffer[MAX_PATH] = 0;
2396 type = 0xdeadbeef;
2397 needed = 0xdeadbeef;
2398 SetLastError(0xdeadbeef);
2399 res = GetPrinterDataA(hprn, defaultspooldirectory, &type, (LPBYTE) buffer, sizeof(buffer), &needed);
2400
2401 len = lstrlenA(buffer) + sizeof(CHAR);
2402 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2403 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2404 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2405 res, type, needed, buffer, len);
2406
2407 needed = 0xdeadbeef;
2408 SetLastError(0xdeadbeef);
2409 res = GetPrinterDataA(hprn, defaultspooldirectory, NULL, NULL, 0, &needed);
2410 ok( (res == ERROR_MORE_DATA) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2411 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2412
2413 /* ToDo: test SPLREG_* */
2414
2415 SetLastError(0xdeadbeef);
2416 res = ClosePrinter(hprn);
2417 ok(res, "ClosePrinter error %d\n", GetLastError());
2418}
2419
2420/* ########################### */
2421
2422static void test_GetPrinterDataEx(void)
2423{
2424 HANDLE hprn = 0;
2425 DWORD res;
2426 DWORD type;
2427 CHAR buffer[MAX_PATH + 1];
2428 DWORD needed;
2429 DWORD len;
2430
2431 /* not present before w2k */
2432 if (!pGetPrinterDataExA) {
2433 win_skip("GetPrinterDataEx not found\n");
2434 return;
2435 }
2436
2437 /* ToDo: test parameter validation, test with the default printer */
2438
2439 SetLastError(0xdeadbeef);
2440 res = OpenPrinterA(NULL, &hprn, NULL);
2441 if (!res)
2442 {
2443 win_skip("Unable to open the printserver: %d\n", GetLastError());
2444 return;
2445 }
2446
2447 /* keyname is ignored, when hprn is a HANDLE for a printserver */
2448 memset(buffer, '#', sizeof(buffer));
2449 buffer[MAX_PATH] = 0;
2450 type = 0xdeadbeef;
2451 needed = 0xdeadbeef;
2452 SetLastError(0xdeadbeef);
2453 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, &type,
2454 (LPBYTE) buffer, sizeof(buffer), &needed);
2455
2456 len = lstrlenA(buffer) + sizeof(CHAR);
2457 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */
2458 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2459 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2460 res, type, needed, buffer, len);
2461
2462 memset(buffer, '#', sizeof(buffer));
2463 buffer[MAX_PATH] = 0;
2464 type = 0xdeadbeef;
2465 needed = 0xdeadbeef;
2466 SetLastError(0xdeadbeef);
2467 res = pGetPrinterDataExA(hprn, "", defaultspooldirectory, &type,
2468 (LPBYTE) buffer, sizeof(buffer), &needed);
2469 len = lstrlenA(buffer) + sizeof(CHAR);
2470 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2471 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2472 res, type, needed, buffer, len);
2473
2474 memset(buffer, '#', sizeof(buffer));
2475 buffer[MAX_PATH] = 0;
2476 type = 0xdeadbeef;
2477 needed = 0xdeadbeef;
2478 SetLastError(0xdeadbeef);
2479 /* Wine uses GetPrinterDataEx with "PrinterDriverData" to implement GetPrinterData */
2480 res = pGetPrinterDataExA(hprn, "PrinterDriverData", defaultspooldirectory,
2481 &type, (LPBYTE) buffer, sizeof(buffer), &needed);
2482 len = lstrlenA(buffer) + sizeof(CHAR);
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
2488 memset(buffer, '#', sizeof(buffer));
2489 buffer[MAX_PATH] = 0;
2490 type = 0xdeadbeef;
2491 needed = 0xdeadbeef;
2492 SetLastError(0xdeadbeef);
2493 res = pGetPrinterDataExA(hprn, does_not_exist, defaultspooldirectory, &type,
2494 (LPBYTE) buffer, sizeof(buffer), &needed);
2495 len = lstrlenA(buffer) + sizeof(CHAR);
2496 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2497 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n",
2498 res, type, needed, buffer, len);
2499
2500 needed = 0xdeadbeef;
2501 SetLastError(0xdeadbeef);
2502 /* vista and w2k8 have a bug in GetPrinterDataEx:
2503 the current LastError value is returned as result */
2504 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, NULL, NULL, 0, &needed);
2505 ok( ((res == ERROR_MORE_DATA) || broken(res == 0xdeadbeef)) &&
2506 ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2507 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2508
2509 needed = 0xdeadbeef;
2510 SetLastError(0xdeaddead);
2511 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, NULL, NULL, 0, &needed);
2512 ok( ((res == ERROR_MORE_DATA) || broken(res == 0xdeaddead)) &&
2513 ((needed == len) || (needed == (len * sizeof(WCHAR)))),
2514 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len);
2515
2516 SetLastError(0xdeadbeef);
2517 res = ClosePrinter(hprn);
2518 ok(res, "ClosePrinter error %d\n", GetLastError());
2519}
2520
2521/* ########################### */
2522
2523static void test_GetPrinterDriver(void)
2524{
2525 HANDLE hprn;
2526 BOOL ret;
2527 BYTE *buf;
2528 INT level;
2529 DWORD needed, filled;
2530
2531 if (!default_printer)
2532 {
2533 skip("There is no default printer installed\n");
2534 return;
2535 }
2536
2537 hprn = 0;
2539 if (!ret)
2540 {
2541 skip("Unable to open the default printer (%s)\n", default_printer);
2542 return;
2543 }
2544 ok(hprn != 0, "wrong hprn %p\n", hprn);
2545
2546 for (level = -1; level <= 7; level++)
2547 {
2548 SetLastError(0xdeadbeef);
2549 needed = (DWORD)-1;
2550 ret = GetPrinterDriverA(hprn, NULL, level, NULL, 0, &needed);
2551 ok(!ret, "level %d: GetPrinterDriver should fail\n", level);
2552 if (level >= 1 && level <= 6)
2553 {
2554 /* Not all levels are supported on all Windows-Versions */
2555 if(GetLastError() == ERROR_INVALID_LEVEL) continue;
2556 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError());
2557 ok(needed > 0,"not expected needed buffer size %d\n", needed);
2558 }
2559 else
2560 {
2561 /* ERROR_OUTOFMEMORY found on win9x */
2564 "%d: returned %d with %d (expected '0' with: "
2565 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n",
2566 level, ret, GetLastError());
2567 /* needed is modified in win9x. The modified Value depends on the
2568 default Printer. testing for "needed == (DWORD)-1" will fail */
2569 continue;
2570 }
2571
2572 /* GetPrinterDriverA returns the same number of bytes as GetPrinterDriverW */
2573 if (!ret && pGetPrinterDriverW)
2574 {
2575 DWORD double_needed;
2576 ret = pGetPrinterDriverW(hprn, NULL, level, NULL, 0, &double_needed);
2577 ok(!ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
2578 ok(double_needed == needed, "GetPrinterDriverA returned different size %d than GetPrinterDriverW (%d)\n", needed, double_needed);
2579 }
2580
2581 buf = HeapAlloc(GetProcessHeap(), 0, needed);
2582
2583 SetLastError(0xdeadbeef);
2584 filled = -1;
2585 ret = GetPrinterDriverA(hprn, NULL, level, buf, needed, &filled);
2586 ok(ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError());
2587 ok(needed == filled, "needed %d != filled %d\n", needed, filled);
2588
2589 if (level == 2)
2590 {
2592 DWORD calculated = sizeof(*di_2);
2593 HANDLE hf;
2594
2595 /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400
2596 NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k-win7(Usermode): 3, win8 and above(Usermode): 4 */
2597 ok( (di_2->cVersion <= 4) ||
2598 (di_2->cVersion == 0x0400), "di_2->cVersion = %d\n", di_2->cVersion);
2599 ok(di_2->pName != NULL, "not expected NULL ptr\n");
2600 ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n");
2601 ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n");
2602 ok(di_2->pDataFile != NULL, "not expected NULL ptr\n");
2603 ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n");
2604
2605 trace("cVersion %d\n", di_2->cVersion);
2606 trace("pName %s\n", di_2->pName);
2607 calculated += strlen(di_2->pName) + 1;
2608 trace("pEnvironment %s\n", di_2->pEnvironment);
2609 calculated += strlen(di_2->pEnvironment) + 1;
2610 trace("pDriverPath %s\n", di_2->pDriverPath);
2611 calculated += strlen(di_2->pDriverPath) + 1;
2612 trace("pDataFile %s\n", di_2->pDataFile);
2613 calculated += strlen(di_2->pDataFile) + 1;
2614 trace("pConfigFile %s\n", di_2->pConfigFile);
2615 calculated += strlen(di_2->pConfigFile) + 1;
2616
2618 if(hf != INVALID_HANDLE_VALUE)
2619 CloseHandle(hf);
2620 todo_wine
2621 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pDriverPath);
2622
2624 if(hf != INVALID_HANDLE_VALUE)
2625 CloseHandle(hf);
2626 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pDataFile);
2627
2629 if(hf != INVALID_HANDLE_VALUE)
2630 CloseHandle(hf);
2631 todo_wine
2632 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pConfigFile);
2633
2634 /* XP allocates memory for both ANSI and unicode names */
2635 ok(filled >= calculated,"calculated %d != filled %d\n", calculated, filled);
2636
2637 /* Obscure test - demonstrate that Windows zero fills the buffer, even on failure */
2638 ret = GetPrinterDriverA(hprn, NULL, level, buf, needed - 2, &filled);
2639 ok(!ret, "level %d: GetPrinterDriver succeeded with less buffer than it should\n", level);
2640 ok(di_2->pDataFile == NULL ||
2641 broken(di_2->pDataFile != NULL), /* Win9x/WinMe */
2642 "Even on failure, GetPrinterDriver clears the buffer to zeros\n");
2643 }
2644
2646 }
2647
2648 SetLastError(0xdeadbeef);
2649 ret = ClosePrinter(hprn);
2650 ok(ret, "ClosePrinter error %d\n", GetLastError());
2651}
2652
2653static void test_DEVMODEA(const DEVMODEA *dm, LONG dmSize, LPCSTR exp_prn_name)
2654{
2655 /* On NT3.51, some fields in DEVMODEA are empty/zero
2656 (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra)
2657 We skip the Tests on this Platform */
2658 if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) {
2659 /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */
2660 ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1) ||
2661 !strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -2), /* XP+ */
2662 "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName);
2663 ok(dm->dmSize + dm->dmDriverExtra == dmSize,
2664 "%u != %d\n", dm->dmSize + dm->dmDriverExtra, dmSize);
2665 }
2666 trace("dmFields %08x\n", dm->dmFields);
2667}
2668
2670{
2671 HANDLE hprn;
2672 LONG dm_size, ret;
2673 DEVMODEA *dm;
2674 char empty_str[] = "";
2675
2676 if (!default_printer)
2677 {
2678 skip("There is no default printer installed\n");
2679 return;
2680 }
2681
2682 hprn = 0;
2684 if (!ret)
2685 {
2686 skip("Unable to open the default printer (%s)\n", default_printer);
2687 return;
2688 }
2689 ok(hprn != 0, "wrong hprn %p\n", hprn);
2690
2691 dm_size = DocumentPropertiesA(0, hprn, NULL, NULL, NULL, 0);
2692 trace("DEVMODEA required size %d\n", dm_size);
2693 ok(dm_size >= sizeof(DEVMODEA), "unexpected DocumentPropertiesA ret value %d\n", dm_size);
2694
2695 dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size);
2696
2697 ret = DocumentPropertiesA(0, hprn, NULL, dm, dm, DM_OUT_BUFFER);
2698 ok(ret == IDOK, "DocumentPropertiesA ret value %d != expected IDOK\n", ret);
2699
2700 ret = DocumentPropertiesA(0, hprn, empty_str, dm, dm, DM_OUT_BUFFER);
2701 ok(ret == IDOK, "DocumentPropertiesA ret value %d != expected IDOK\n", ret);
2702
2703 test_DEVMODEA(dm, dm_size, default_printer);
2704
2705 HeapFree(GetProcessHeap(), 0, dm);
2706
2707 SetLastError(0xdeadbeef);
2708 ret = ClosePrinter(hprn);
2709 ok(ret, "ClosePrinter error %d\n", GetLastError());
2710}
2711
2712static void test_EnumPrinters(void)
2713{
2714 DWORD neededA, neededW, num;
2715 DWORD ret;
2716
2717 SetLastError(0xdeadbeef);
2718 neededA = -1;
2719 ret = EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededA, &num);
2720 if (is_spooler_deactivated(ret, GetLastError())) return;
2721 if (!ret)
2722 {
2723 /* We have 1 or more printers */
2725 ok(neededA > 0, "Expected neededA to show the number of needed bytes\n");
2726 }
2727 else
2728 {
2729 /* We don't have any printers defined */
2730 ok(GetLastError() == S_OK, "gle %d\n", GetLastError());
2731 ok(neededA == 0, "Expected neededA to be zero\n");
2732 }
2733 ok(num == 0, "num %d\n", num);
2734
2735 SetLastError(0xdeadbeef);
2736 neededW = -1;
2737 ret = EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededW, &num);
2738 /* EnumPrintersW is not supported on all platforms */
2740 {
2741 win_skip("EnumPrintersW is not implemented\n");
2742 return;
2743 }
2744
2745 if (!ret)
2746 {
2747 /* We have 1 or more printers */
2749 ok(neededW > 0, "Expected neededW to show the number of needed bytes\n");
2750 }
2751 else
2752 {
2753 /* We don't have any printers defined */
2754 ok(GetLastError() == S_OK, "gle %d\n", GetLastError());
2755 ok(neededW == 0, "Expected neededW to be zero\n");
2756 }
2757 ok(num == 0, "num %d\n", num);
2758
2759 /* Outlook2003 relies on the buffer size returned by EnumPrintersA being big enough
2760 to hold the buffer returned by EnumPrintersW */
2761 ok(neededA == neededW, "neededA %d neededW %d\n", neededA, neededW);
2762}
2763
2765{
2766 HANDLE hComdlg32;
2767 BOOL (WINAPI *pPrintDlgA)(PRINTDLGA *);
2768 PRINTDLGA prn_dlg;
2769 DEVMODEA *dm;
2770 DEVNAMES *dn;
2771 const char *driver, *device, *port;
2772 WORD *papers;
2773 POINT *paper_size;
2774 POINTS ext;
2775 struct
2776 {
2777 char name[64];
2778 } *paper_name;
2779 INT n_papers, n_paper_size, n_paper_names, n_copies, ret;
2780 DWORD fields;
2781
2782 hComdlg32 = LoadLibraryA("comdlg32.dll");
2783 assert(hComdlg32);
2784 pPrintDlgA = (void *)GetProcAddress(hComdlg32, "PrintDlgA");
2785 assert(pPrintDlgA);
2786
2787 memset(&prn_dlg, 0, sizeof(prn_dlg));
2788 prn_dlg.lStructSize = sizeof(prn_dlg);
2789 prn_dlg.Flags = PD_RETURNDEFAULT;
2790 ret = pPrintDlgA(&prn_dlg);
2791 FreeLibrary(hComdlg32);
2792 if (!ret)
2793 {
2794 skip("PrintDlg returned no default printer\n");
2795 return;
2796 }
2797 ok(prn_dlg.hDevMode != 0, "PrintDlg returned hDevMode == NULL\n");
2798 ok(prn_dlg.hDevNames != 0, "PrintDlg returned hDevNames == NULL\n");
2799
2800 dm = GlobalLock(prn_dlg.hDevMode);
2801 ok(dm != NULL, "GlobalLock(prn_dlg.hDevMode) failed\n");
2802 trace("dmDeviceName \"%s\"\n", dm->dmDeviceName);
2803
2804 dn = GlobalLock(prn_dlg.hDevNames);
2805 ok(dn != NULL, "GlobalLock(prn_dlg.hDevNames) failed\n");
2806 ok(dn->wDriverOffset, "expected not 0 wDriverOffset\n");
2807 ok(dn->wDeviceOffset, "expected not 0 wDeviceOffset\n");
2808 ok(dn->wOutputOffset, "expected not 0 wOutputOffset\n");
2809 ok(dn->wDefault == DN_DEFAULTPRN, "expected DN_DEFAULTPRN got %x\n", dn->wDefault);
2810 driver = (const char *)dn + dn->wDriverOffset;
2811 device = (const char *)dn + dn->wDeviceOffset;
2812 port = (const char *)dn + dn->wOutputOffset;
2813 trace("driver \"%s\" device \"%s\" port \"%s\"\n", driver, device, port);
2814
2815 test_DEVMODEA(dm, dm->dmSize + dm->dmDriverExtra, device);
2816
2818 ok(n_papers > 0, "DeviceCapabilitiesA DC_PAPERS failed\n");
2819 papers = HeapAlloc(GetProcessHeap(), 0, sizeof(*papers) * n_papers);
2821 ok(ret == n_papers, "expected %d, got %d\n", n_papers, ret);
2822#ifdef VERBOSE
2823 for (ret = 0; ret < n_papers; ret++)
2824 trace("papers[%d] = %d\n", ret, papers[ret]);
2825#endif
2826 HeapFree(GetProcessHeap(), 0, papers);
2827
2829 ok(n_paper_size > 0, "DeviceCapabilitiesA DC_PAPERSIZE failed\n");
2830 ok(n_paper_size == n_papers, "n_paper_size %d != n_papers %d\n", n_paper_size, n_papers);
2831 paper_size = HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_size) * n_paper_size);
2833 ok(ret == n_paper_size, "expected %d, got %d\n", n_paper_size, ret);
2834#ifdef VERBOSE
2835 for (ret = 0; ret < n_paper_size; ret++)
2836 trace("paper_size[%d] = %d x %d\n", ret, paper_size[ret].x, paper_size[ret].y);
2837#endif
2838 HeapFree(GetProcessHeap(), 0, paper_size);
2839
2841 ok(n_paper_names > 0, "DeviceCapabilitiesA DC_PAPERNAMES failed\n");
2842 ok(n_paper_names == n_papers, "n_paper_names %d != n_papers %d\n", n_paper_names, n_papers);
2843 paper_name = HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_name) * n_paper_names);
2845 ok(ret == n_paper_names, "expected %d, got %d\n", n_paper_names, ret);
2846#ifdef VERBOSE
2847 for (ret = 0; ret < n_paper_names; ret++)
2848 trace("paper_name[%u] = %s\n", ret, paper_name[ret].name);
2849#endif
2850 HeapFree(GetProcessHeap(), 0, paper_name);
2851
2852 n_copies = DeviceCapabilitiesA(device, port, DC_COPIES, NULL, dm);
2853 ok(n_copies > 0, "DeviceCapabilitiesA DC_COPIES failed\n");
2854 trace("n_copies = %d\n", n_copies);
2855
2856 /* these capabilities are not available on all printer drivers */
2857 if (0)
2858 {
2860 ok(ret != -1, "DeviceCapabilitiesA DC_MAXEXTENT failed\n");
2861 ext = MAKEPOINTS(ret);
2862 trace("max ext = %d x %d\n", ext.x, ext.y);
2863
2865 ok(ret != -1, "DeviceCapabilitiesA DC_MINEXTENT failed\n");
2866 ext = MAKEPOINTS(ret);
2867 trace("min ext = %d x %d\n", ext.x, ext.y);
2868 }
2869
2871 ok(fields != (DWORD)-1, "DeviceCapabilitiesA DC_FIELDS failed\n");
2872 ok(fields == (dm->dmFields | DM_FORMNAME) ||
2874 broken(fields == dm->dmFields), /* Win9x/WinMe */
2875 "fields %x, dm->dmFields %x\n", fields, dm->dmFields);
2876
2877 GlobalUnlock(prn_dlg.hDevMode);
2878 GlobalFree(prn_dlg.hDevMode);
2879 GlobalUnlock(prn_dlg.hDevNames);
2880 GlobalFree(prn_dlg.hDevNames);
2881}
2882
2884{
2885 HANDLE printer;
2886 BOOL ret;
2887 DWORD needed;
2888 short default_size;
2889 ADDJOB_INFO_1A *add_job;
2891 DEVMODEA my_dm;
2892 PRINTER_DEFAULTSA prn_def;
2894
2895 if (!default_printer)
2896 {
2897 skip("There is no default printer installed\n");
2898 return;
2899 }
2900
2901 /* Printer opened with NULL defaults. Retrieve default paper size
2902 and confirm that jobs have this size. */
2903
2904 ret = OpenPrinterA( default_printer, &printer, NULL );
2905 if (!ret)
2906 {
2907 skip("Unable to open the default printer (%s)\n", default_printer);
2908 return;
2909 }
2910
2911 ret = GetPrinterA( printer, 2, NULL, 0, &needed );
2912 ok( !ret, "got %d\n", ret );
2913 pi = HeapAlloc( GetProcessHeap(), 0, needed );
2914 ret = GetPrinterA( printer, 2, (BYTE *)pi, needed, &needed );
2915 ok( ret, "GetPrinterA() failed le=%d\n", GetLastError() );
2916 default_size = pi->pDevMode->u1.s1.dmPaperSize;
2917 HeapFree( GetProcessHeap(), 0, pi );
2918
2919 needed = 0;
2920 SetLastError( 0xdeadbeef );
2921 ret = AddJobA( printer, 1, NULL, 0, &needed );
2922 ok( !ret, "got %d\n", ret );
2923 if (GetLastError() == ERROR_NOT_SUPPORTED) /* win8 */
2924 {
2925 win_skip( "AddJob is not supported on this platform\n" );
2926 ClosePrinter( printer );
2927 return;
2928 }
2929 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError() );
2930 ok( needed > sizeof(ADDJOB_INFO_1A), "AddJob needs %u bytes\n", needed);
2931 add_job = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, needed );
2932 ret = AddJobA( printer, 1, (BYTE *)add_job, needed, &needed );
2933 ok( ret, "AddJobA() failed le=%d\n", GetLastError() );
2934
2935 ret = GetJobA( printer, add_job->JobId, 2, NULL, 0, &needed );
2936 ok( !ret, "got %d\n", ret );
2937 job_info = HeapAlloc( GetProcessHeap(), 0, needed );
2938 ret = GetJobA( printer, add_job->JobId, 2, (BYTE *)job_info, needed, &needed );
2939 ok( ret, "GetJobA() failed le=%d\n", GetLastError() );
2940
2941 todo_wine
2942 ok( job_info->pDevMode != NULL, "got NULL DEVMODEA\n");
2943 if (job_info->pDevMode)
2944 ok( job_info->pDevMode->u1.s1.dmPaperSize == default_size, "got %d default %d\n",
2945 job_info->pDevMode->u1.s1.dmPaperSize, default_size );
2946
2948 ScheduleJob( printer, add_job->JobId ); /* remove the empty job */
2949 HeapFree( GetProcessHeap(), 0, add_job );
2950 ClosePrinter( printer );
2951
2952 /* Printer opened with something other than the default paper size. */
2953
2954 memset( &my_dm, 0, sizeof(my_dm) );
2955 my_dm.dmSize = sizeof(my_dm);
2956 my_dm.dmFields = DM_PAPERSIZE;
2957 my_dm.u1.s1.dmPaperSize = (default_size == DMPAPER_A4) ? DMPAPER_LETTER : DMPAPER_A4;
2958
2959 prn_def.pDatatype = NULL;
2960 prn_def.pDevMode = &my_dm;
2962
2963 ret = OpenPrinterA( default_printer, &printer, &prn_def );
2964 ok( ret, "OpenPrinterA() failed le=%d\n", GetLastError() );
2965
2966 /* GetPrinter stills returns default size */
2967 ret = GetPrinterA( printer, 2, NULL, 0, &needed );
2968 ok( !ret, "got %d\n", ret );
2969 pi = HeapAlloc( GetProcessHeap(), 0, needed );
2970 ret = GetPrinterA( printer, 2, (BYTE *)pi, needed, &needed );
2971 ok( ret, "GetPrinterA() failed le=%d\n", GetLastError() );
2972 ok( pi->pDevMode->u1.s1.dmPaperSize == default_size, "got %d default %d\n",
2973 pi->pDevMode->u1.s1.dmPaperSize, default_size );
2974
2975 HeapFree( GetProcessHeap(), 0, pi );
2976
2977 /* However the GetJobA has the new size */
2978 ret = AddJobA( printer, 1, NULL, 0, &needed );
2979 ok( !ret, "got %d\n", ret );
2980 add_job = HeapAlloc( GetProcessHeap(), 0, needed );
2981 ret = AddJobA( printer, 1, (BYTE *)add_job, needed, &needed );
2982 ok( ret, "AddJobA() failed le=%d\n", GetLastError() );
2983
2984 ret = GetJobA( printer, add_job->JobId, 2, NULL, 0, &needed );
2985 ok( !ret, "got %d\n", ret );
2986 job_info = HeapAlloc( GetProcessHeap(), 0, needed );
2987 ret = GetJobA( printer, add_job->JobId, 2, (BYTE *)job_info, needed, &needed );
2988 ok( ret, "GetJobA() failed le=%d\n", GetLastError() );
2989
2990 ok( job_info->pDevMode->dmFields == DM_PAPERSIZE, "got %08x\n",
2991 job_info->pDevMode->dmFields );
2992 ok( job_info->pDevMode->u1.s1.dmPaperSize == my_dm.u1.s1.dmPaperSize,
2993 "got %d new size %d\n",
2994 job_info->pDevMode->u1.s1.dmPaperSize, my_dm.u1.s1.dmPaperSize );
2995
2997 ScheduleJob( printer, add_job->JobId ); /* remove the empty job */
2998 HeapFree( GetProcessHeap(), 0, add_job );
2999 ClosePrinter( printer );
3000}
3001
3002static void test_IsValidDevmodeW(void)
3003{
3004 static const struct
3005 {
3006 DWORD dmFields;
3007 WORD dmSize;
3008 BOOL ret;
3009 } test[] =
3010 {
3011 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 0, FALSE },
3012 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 1, FALSE },
3013 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 2, FALSE },
3014 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 3, FALSE },
3015 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 4, TRUE },
3016
3020
3026
3027 };
3028 DEVMODEW dm;
3029 int i;
3030 BOOL ret;
3031
3032 ret = IsValidDevmodeW(NULL, 0);
3033 ok(!ret, "got %d\n", ret);
3034
3035 ret = IsValidDevmodeW(NULL, sizeof(DEVMODEW));
3036 ok(!ret, "got %d\n", ret);
3037
3038 memset(&dm, 0, sizeof(dm));
3039
3040 for (i = 0; i < ARRAY_SIZE(test); i++)
3041 {
3042 dm.dmSize = test[i].dmSize;
3043 dm.dmFields = test[i].dmFields;
3044 ret = IsValidDevmodeW(&dm, dm.dmSize);
3045 ok(ret == test[i].ret, "%d: got %d\n", i, ret);
3046 }
3047}
3048
3050{
3051 hwinspool = LoadLibraryA("winspool.drv");
3052 pAddPortExA = (void *) GetProcAddress(hwinspool, "AddPortExA");
3053 pEnumPrinterDriversW = (void *) GetProcAddress(hwinspool, "EnumPrinterDriversW");
3054 pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
3055 pGetPrinterDataExA = (void *) GetProcAddress(hwinspool, "GetPrinterDataExA");
3056 pGetPrinterDriverW = (void *) GetProcAddress(hwinspool, "GetPrinterDriverW");
3057 pGetPrinterW = (void *) GetProcAddress(hwinspool, "GetPrinterW");
3058 pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA");
3059 pXcvDataW = (void *) GetProcAddress(hwinspool, "XcvDataW");
3060
3063 find_tempfile();
3064
3066 test_AddPort();
3094
3095 /* Cleanup our temporary file */
3097}
#define broken(x)
Definition: _sntprintf.h:21
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
static const TCHAR empty_str[]
Definition: dialog.c:20
#define ARRAY_SIZE(A)
Definition: main.h:33
#define CHAR(Char)
#define RegCloseKey(hKey)
Definition: registry.h:49
return
Definition: dirsup.c:529
#define DN_DEFAULTPRN
Definition: commdlg.h:199
#define PD_RETURNDEFAULT
Definition: commdlg.h:157
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define CCHDEVICENAME
Definition: ddrawi.h:63
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3327
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4038
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_MOD_NOT_FOUND
Definition: compat.h:104
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define FreeLibrary(x)
Definition: compat.h:748
#define GENERIC_READ
Definition: compat.h:135
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrlenW
Definition: compat.h:750
static const WCHAR *const ext[]
Definition: module.c:53
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
BOOL WINAPI WriteProfileStringA(LPCSTR section, LPCSTR entry, LPCSTR string)
Definition: profile.c:1278
INT WINAPI GetProfileStringA(LPCSTR section, LPCSTR entry, LPCSTR def_val, LPSTR buffer, UINT len)
Definition: profile.c:1252
USHORT port
Definition: uri.c:228
#define assert(x)
Definition: debug.h:53
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLint level
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLdouble GLdouble u2
Definition: glext.h:8308
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLdouble u1
Definition: glext.h:8308
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
static const WCHAR emptyW[]
Definition: navigate.c:40
#define S_OK
Definition: intsafe.h:52
uint32_t entry
Definition: isohybrid.c:63
#define REG_SZ
Definition: layer.c:22
static HANDLE hXcv
Definition: localmon.c:73
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
static LPSTR pName
Definition: security.c:75
static const ASMPROP_RES defaults[ASM_NAME_MAX_PARAMS]
Definition: asmname.c:82
#define todo_wine
Definition: custom.c:79
static const void void SIZE_T *static SIZE_T *static const OBJECT_ATTRIBUTES const LARGE_INTEGER HANDLE
Definition: info.c:35
static float(__cdecl *square_half_float)(float x
static refpint_t pi[]
Definition: server.c:96
const char * fields[10]
Definition: parser.c:313
static CHAR version_dll[]
Definition: info.c:55
static CHAR invalid_env[]
Definition: info.c:49
static LPWSTR tempdirW
Definition: info.c:90
static void test_EnumPrintProcessors(void)
Definition: info.c:1305
static CHAR env_x64[]
Definition: info.c:45
static void find_local_server(VOID)
Definition: info.c:235
static void test_GetPrintProcessorDirectory(void)
Definition: info.c:1656
static LPSTR
Definition: info.c:70
static CHAR env_x86[]
Definition: info.c:46
static LPBYTE
Definition: info.c:70
#define FORMTYPE_MAX
#define DEFAULT_PRINTER_SIZE
Definition: info.c:39
static void test_ConfigurePort(void)
Definition: info.c:594
static struct monitor_entry * find_installed_monitor(void)
Definition: info.c:176
static void test_EnumPrinters(void)
Definition: info.c:2712
static CHAR does_not_exist[]
Definition: info.c:43
static void test_XcvDataW_MonitorUI(void)
Definition: info.c:2061
static void test_DocumentProperties(void)
Definition: info.c:2669
static void test_DEVMODEA(const DEVMODEA *dm, LONG dmSize, LPCSTR exp_prn_name)
Definition: info.c:2653
static void test_AddMonitor(void)
Definition: info.c:300
static LPSTR tempdirA
Definition: info.c:88
static CHAR winetest[]
Definition: info.c:56
static void test_OpenPrinter_defaults(void)
Definition: info.c:2883
static void test_DeleteMonitor(void)
Definition: info.c:700
static CHAR illegal_name[]
Definition: info.c:48
static void test_XcvDataW_PortIsValid(void)
Definition: info.c:2181
static LPSTR tempfileA
Definition: info.c:89
static CHAR portname_file[]
Definition: info.c:52
static LPWSTR
Definition: info.c:71
static void test_GetPrinterDataEx(void)
Definition: info.c:2422
static WCHAR portname_lpt1W[]
Definition: info.c:66
static CHAR defaultspooldirectory[]
Definition: info.c:41
static void test_SetDefaultPrinter(void)
Definition: info.c:1951
static BOOL is_spooler_deactivated(DWORD res, DWORD lasterror)
Definition: info.c:93
static LPSTR default_printer
Definition: info.c:86
static void test_AddPort(void)
Definition: info.c:443
static void find_tempfile(VOID)
Definition: info.c:258
static CHAR server_does_not_exist[]
Definition: info.c:54
static const WCHAR cmd_PortIsValidW[]
Definition: info.c:60
static CHAR does_not_exist_dll[]
Definition: info.c:42
static void test_AddPortEx(void)
Definition: info.c:481
static void test_GetPrinter(void)
Definition: info.c:2292
static void test_GetPrinterData(void)
Definition: info.c:2376
static HANDLE hwinspool
Definition: info.c:69
static CHAR env_win9x_case[]
Definition: info.c:47
static CHAR xcv_localport[]
Definition: info.c:57
static void test_EnumMonitors(void)
Definition: info.c:949
static CHAR LocalPortA[]
Definition: info.c:50
static WCHAR portname_com2W[]
Definition: info.c:64
static void test_EnumForms(LPSTR pName)
Definition: info.c:816
static void test_GetDefaultPrinter(void)
Definition: info.c:1425
static WCHAR portname_lpt2W[]
Definition: info.c:67
static CHAR portname_lpt1[]
Definition: info.c:53
static void find_default_printer(VOID)
Definition: info.c:123
static WCHAR portname_com1W[]
Definition: info.c:63
static const WCHAR cmd_MonitorUIW[]
Definition: info.c:59
static void test_DeviceCapabilities(void)
Definition: info.c:2764
static BOOL is_access_denied(DWORD res, DWORD lasterror)
Definition: info.c:108
static void test_GetPrinterDriver(void)
Definition: info.c:2523
static WCHAR portname_fileW[]
Definition: info.c:65
static PDWORD
Definition: info.c:77
static LPCSTR
Definition: info.c:73
static void test_IsValidDevmodeW(void)
Definition: info.c:3002
static LPWSTR tempfileW
Definition: info.c:91
static PBYTE
Definition: info.c:77
static void test_GetPrinterDriverDirectory(void)
Definition: info.c:1502
static void test_DeletePort(void)
Definition: info.c:784
static CHAR portname_com1[]
Definition: info.c:51
#define MAGIC_DEAD
Definition: info.c:38
static void test_EnumPrinterDrivers(void)
Definition: info.c:1155
static CHAR empty[]
Definition: info.c:44
static void test_EnumPorts(void)
Definition: info.c:1057
static void test_OpenPrinter(void)
Definition: info.c:1796
static void test_ClosePrinter(void)
Definition: info.c:656
struct @1664::@1665 driver
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define LPDWORD
Definition: nt_native.h:46
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define DWORD
Definition: nt_native.h:44
BYTE * PBYTE
Definition: pedump.c:66
long LONG
Definition: pedump.c:60
#define test
Definition: rosglue.h:37
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
int winetest_debug
#define win_skip
Definition: test.h:160
int winetest_interactive
#define memset(x, y, z)
Definition: compat.h:39
BOOL WINAPI SHIM_OBJ_NAME() GetComputerNameA(LPSTR lpBuffer, LPDWORD lpnSize)
Definition: shimtest.c:21
LPSTR pConfigFile
Definition: winspool.h:386
LPSTR pDriverPath
Definition: winspool.h:384
DWORD cVersion
Definition: winspool.h:381
LPSTR pDataFile
Definition: winspool.h:385
LPSTR pEnvironment
Definition: winspool.h:383
DWORD Flags
Definition: winspool.h:626
LPSTR pName
Definition: winspool.h:627
SIZEL Size
Definition: winspool.h:628
DWORD dwResourceId
Definition: winspool.h:651
LPCSTR pKeyword
Definition: winspool.h:648
LPCSTR pDisplayName
Definition: winspool.h:652
DWORD StringType
Definition: winspool.h:649
LANGID wLangId
Definition: winspool.h:653
LPCSTR pMuiDll
Definition: winspool.h:650
LPSTR pEnvironment
Definition: winspool.h:828
LPDEVMODEA pDevMode
Definition: winspool.h:856
ACCESS_MASK DesiredAccess
Definition: winspool.h:857
LPSTR pDriverName
Definition: winspool.h:42
LPSTR pPrinterName
Definition: winspool.h:39
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
WORD dmDriverVersion
Definition: wingdi.h:1567
DWORD dmFields
Definition: wingdi.h:1570
WORD dmSpecVersion
Definition: wingdi.h:1566
short dmPaperSize
Definition: wingdi.h:1574
WORD dmDriverExtra
Definition: wingdi.h:1569
BYTE dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1565
WORD dmSize
Definition: wingdi.h:1568
DWORD dmNup
Definition: wingdi.h:1652
DWORD dmFields
Definition: wingdi.h:1622
short dmOrientation
Definition: wingdi.h:1625
WORD dmSize
Definition: wingdi.h:1620
Definition: devices.h:37
Definition: info.c:81
LPSTR env
Definition: info.c:82
CHAR dllname[32]
Definition: info.c:83
Definition: name.c:39
Definition: ps.c:97
WORD wDeviceOffset
Definition: commdlg.h:298
WORD wDriverOffset
Definition: commdlg.h:297
WORD wDefault
Definition: commdlg.h:300
WORD wOutputOffset
Definition: commdlg.h:299
DWORD Flags
Definition: commdlg.h:470
HGLOBAL hDevMode
Definition: commdlg.h:467
HGLOBAL hDevNames
Definition: commdlg.h:468
DWORD lStructSize
Definition: commdlg.h:465
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
int ret
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3828
#define DC_FIELDS
Definition: windef.h:362
#define DC_MAXEXTENT
Definition: windef.h:366
#define DC_COPIES
Definition: windef.h:379
#define DC_PAPERNAMES
Definition: windef.h:377
#define DC_PAPERSIZE
Definition: windef.h:364
#define DC_MINEXTENT
Definition: windef.h:365
#define DC_PAPERS
Definition: windef.h:363
#define DM_OUT_BUFFER
Definition: windef.h:359
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_DATATYPE
Definition: winerror.h:1111
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define ERROR_INVALID_ENVIRONMENT
Definition: winerror.h:1112
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_UNKNOWN_PRINT_MONITOR
Definition: winerror.h:1205
#define RPC_X_NULL_REF_POINTER
Definition: winerror.h:1087
#define ERROR_PROC_NOT_FOUND
Definition: winerror.h:199
#define ERROR_INVALID_PRINTER_NAME
Definition: winerror.h:1108
#define RPC_S_SERVER_UNAVAILABLE
Definition: winerror.h:1033
#define RPC_S_INVALID_NET_ADDR
Definition: winerror.h:1018
#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED
Definition: winerror.h:1211
#define ERROR_PRIVILEGE_NOT_HELD
Definition: winerror.h:796
DWORD WINAPI DeviceCapabilitiesA(_In_ LPCSTR pDevice, _In_opt_ LPCSTR pPort, _In_ WORD fwCapability, _Out_writes_opt_(_Inexpressible_(1)) LPSTR pOutput, _In_opt_ const DEVMODEA *pDevMode)
#define DM_PAPERWIDTH
Definition: wingdi.h:1253
#define DM_ORIENTATION
Definition: wingdi.h:1250
#define DM_FORMNAME
Definition: wingdi.h:1266
#define DMPAPER_A4
Definition: wingdi.h:1121
#define DMPAPER_LETTER
Definition: wingdi.h:1113
#define DM_NUP
Definition: wingdi.h:1256
#define MAKEPOINTS(l)
Definition: wingdi.h:2945
#define DM_PAPERLENGTH
Definition: wingdi.h:1252
#define DM_PAPERSIZE
Definition: wingdi.h:1251
#define HKEY_CURRENT_USER
Definition: winreg.h:11
WINBOOL WINAPI OpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefault)
Definition: printers.c:2582
WINBOOL WINAPI AddPortA(LPSTR pName, HWND hWnd, LPSTR pMonitorName)
Definition: ports.c:420
struct _FORM_INFO_1A * PFORM_INFO_1A
#define PRINTER_ENUM_LOCAL
Definition: winspool.h:896
struct _DRIVER_INFO_2A * LPDRIVER_INFO_2A
WINBOOL WINAPI EnumPrintersW(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
WINBOOL WINAPI DeletePortA(LPSTR pName, HWND hWnd, LPSTR pPortName)
Definition: ports.c:705
WINBOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
WINBOOL WINAPI AddMonitorA(LPSTR pName, DWORD Level, LPBYTE pMonitorInfo)
WINBOOL WINAPI DeleteMonitorA(LPSTR pName, LPSTR pEnvironment, LPSTR pMonitorName)
Definition: monitors.c:111
WINBOOL WINAPI GetPrinterDriverDirectoryA(LPSTR pName, LPSTR pEnvironment, DWORD Level, LPBYTE pDriverDirectory, DWORD cbBuf, LPDWORD pcbNeeded)
DWORD WINAPI GetPrinterDataA(HANDLE hPrinter, LPSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:326
#define SERVER_ACCESS_ADMINISTER
Definition: winspool.h:1366
LONG WINAPI DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput, DWORD fMode)
Definition: printers.c:666
WINBOOL WINAPI EnumPortsA(LPSTR pName, DWORD Level, LPBYTE pPorts, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
struct _FORM_INFO_2A * PFORM_INFO_2A
#define PORT_TYPE_WRITE
Definition: winspool.h:776
WINBOOL WINAPI EnumPrintProcessorsA(LPSTR pName, LPSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
WINBOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded)
Definition: printers.c:2062
WINBOOL WINAPI EnumFormsA(HANDLE hPrinter, DWORD Level, LPBYTE pForm, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
WINBOOL WINAPI EnumPrinterDriversA(LPSTR pName, LPSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
WINBOOL WINAPI ClosePrinter(HANDLE hPrinter)
Definition: printers.c:176
#define PRINTER_ACCESS_USE
Definition: winspool.h:1370
WINBOOL WINAPI ConfigurePortA(LPSTR pName, HWND hWnd, LPSTR pPortName)
Definition: ports.c:629
WINBOOL WINAPI ScheduleJob(HANDLE hPrinter, DWORD JobId)
Definition: jobs.c:56
WINBOOL WINAPI AddJobA(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
WINBOOL WINAPI GetPrintProcessorDirectoryA(LPSTR pName, LPSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded)
WINBOOL WINAPI EnumMonitorsA(LPSTR pName, DWORD Level, LPBYTE pMonitor, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
#define PRINTER_ALL_ACCESS
Definition: winspool.h:1379
WINBOOL WINAPI IsValidDevmodeW(PDEVMODEW pDevmode, size_t DevmodeSize)
Definition: devmode.c:186
WINBOOL WINAPI EnumPrintersA(DWORD Flags, LPSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
WINBOOL WINAPI GetJobA(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD pcbNeeded)
#define IDOK
Definition: winuser.h:830
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193