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