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