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