2 * Copyright (C) 2003, 2004 Stefan Leichter
3 * Copyright (C) 2005 Detlef Riekenberg
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/test.h"
30 #define MAGIC_DEAD 0x00dead00
31 #define DEFAULT_PRINTER_SIZE 1000
33 static char env_x86
[] = "Windows NT x86";
34 static char env_win9x_case
[] = "windowS 4.0";
36 static HANDLE hwinspool
;
37 static FARPROC pGetDefaultPrinterA
;
39 /* report common behavior only once */
40 static DWORD report_deactivated_spooler
= 1;
41 #define RETURN_ON_DEACTIVATED_SPOOLER(res) \
42 if((res == 0) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE)) \
44 if(report_deactivated_spooler > 0) { \
45 report_deactivated_spooler--; \
46 trace("The Service 'Spooler' is required for many test\n"); \
52 static LPSTR
find_default_printer(VOID
)
54 static LPSTR default_printer
= NULL
;
55 static char buffer
[DEFAULT_PRINTER_SIZE
];
60 if ((default_printer
== NULL
) && (pGetDefaultPrinterA
))
63 needed
= sizeof(buffer
);
64 res
= pGetDefaultPrinterA(buffer
, &needed
);
65 if(res
) default_printer
= buffer
;
66 trace("default_printer: '%s'\n", default_printer
);
68 if (default_printer
== NULL
)
72 /* NT 3.x and above */
73 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
74 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
75 0, KEY_QUERY_VALUE
, &hwindows
) == NO_ERROR
) {
77 needed
= sizeof(buffer
);
78 if (RegQueryValueEx(hwindows
, "device", NULL
,
79 &type
, (LPBYTE
)buffer
, &needed
) == NO_ERROR
) {
81 ptr
= strchr(buffer
, ',');
84 default_printer
= buffer
;
87 RegCloseKey(hwindows
);
89 trace("default_printer: '%s'\n", default_printer
);
91 if (default_printer
== NULL
)
94 needed
= sizeof(buffer
);
95 res
= GetProfileStringA("windows", "device", "*", buffer
, needed
);
97 ptr
= strchr(buffer
, ',');
100 default_printer
= buffer
;
103 trace("default_printer: '%s'\n", default_printer
);
105 return default_printer
;
109 static void test_GetDefaultPrinter(void)
112 DWORD exact
= DEFAULT_PRINTER_SIZE
;
114 char buffer
[DEFAULT_PRINTER_SIZE
];
116 if (!pGetDefaultPrinterA
) return;
117 /* only supported on NT like OSes starting with win2k */
119 SetLastError(ERROR_SUCCESS
);
120 retval
= pGetDefaultPrinterA(buffer
, &exact
);
121 if (!retval
|| !exact
|| !strlen(buffer
) ||
122 (ERROR_SUCCESS
!= GetLastError())) {
123 if ((ERROR_FILE_NOT_FOUND
== GetLastError()) ||
124 (ERROR_INVALID_NAME
== GetLastError()))
125 trace("this test requires a default printer to be set\n");
127 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
128 "function returned %s\n"
129 "last error 0x%08lx\n"
130 "returned buffer size 0x%08lx\n"
131 "returned buffer content %s\n",
132 retval
? "true" : "false", GetLastError(), exact
, buffer
);
136 SetLastError(ERROR_SUCCESS
);
137 retval
= pGetDefaultPrinterA(NULL
, NULL
);
138 ok( !retval
, "function result wrong! False expected\n");
139 ok( ERROR_INVALID_PARAMETER
== GetLastError(),
140 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08lx\n",
143 SetLastError(ERROR_SUCCESS
);
144 retval
= pGetDefaultPrinterA(buffer
, NULL
);
145 ok( !retval
, "function result wrong! False expected\n");
146 ok( ERROR_INVALID_PARAMETER
== GetLastError(),
147 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08lx\n",
150 SetLastError(ERROR_SUCCESS
);
152 retval
= pGetDefaultPrinterA(NULL
, &size
);
153 ok( !retval
, "function result wrong! False expected\n");
154 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
155 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
157 ok( size
== exact
, "Parameter size wrong! %ld expected got %ld\n",
160 SetLastError(ERROR_SUCCESS
);
161 size
= DEFAULT_PRINTER_SIZE
;
162 retval
= pGetDefaultPrinterA(NULL
, &size
);
163 ok( !retval
, "function result wrong! False expected\n");
164 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
165 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
167 ok( size
== exact
, "Parameter size wrong! %ld expected got %ld\n",
171 retval
= pGetDefaultPrinterA(buffer
, &size
);
172 ok( !retval
, "function result wrong! False expected\n");
173 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
174 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
176 ok( size
== exact
, "Parameter size wrong! %ld expected got %ld\n",
180 retval
= pGetDefaultPrinterA(buffer
, &size
);
181 ok( retval
, "function result wrong! True expected\n");
182 ok( size
== exact
, "Parameter size wrong! %ld expected got %ld\n",
186 static void test_GetPrinterDriverDirectory(void)
188 LPBYTE buffer
= NULL
;
189 DWORD cbBuf
= 0, pcbNeeded
= 0;
192 SetLastError(MAGIC_DEAD
);
193 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, NULL
, 0, &cbBuf
);
194 trace("first call returned 0x%04x, with %ld: buffer size 0x%08lx\n",
195 res
, GetLastError(), cbBuf
);
197 RETURN_ON_DEACTIVATED_SPOOLER(res
)
198 ok((res
== 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
199 "returned %d with lasterror=%ld (expected '0' with " \
200 "ERROR_INSUFFICIENT_BUFFER)\n", res
, GetLastError());
203 trace("no valid buffer size returned, skipping tests\n");
207 buffer
= HeapAlloc( GetProcessHeap(), 0, cbBuf
*2);
208 if (buffer
== NULL
) return ;
210 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
, &pcbNeeded
);
211 ok( res
, "expected result != 0, got %d\n", res
);
212 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %ld instead of %ld\n",
215 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
216 ok( res
, "expected result != 0, got %d\n", res
);
217 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %ld instead of %ld\n",
220 SetLastError(MAGIC_DEAD
);
221 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
-1, &pcbNeeded
);
222 ok( !res
, "expected result == 0, got %d\n", res
);
223 ok( cbBuf
== pcbNeeded
, "pcbNeeded set to %ld instead of %ld\n",
226 ok( ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
227 "last error set to %ld instead of ERROR_INSUFFICIENT_BUFFER\n",
231 Do not add the next test:
232 XPsp2: crash in this app, when the spooler is not running
233 NT3.5: ERROR_INVALID_USER_BUFFER
234 win9x: ERROR_INVALID_PARAMETER
236 pcbNeeded = MAGIC_DEAD;
237 SetLastError(MAGIC_DEAD);
238 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
241 SetLastError(MAGIC_DEAD
);
242 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, buffer
, cbBuf
, NULL
);
243 ok( (!res
&& RPC_X_NULL_REF_POINTER
== GetLastError()) || res
,
244 "expected either result == 0 and "
245 "last error == RPC_X_NULL_REF_POINTER or result != 0 "
246 "got result %d and last error == %ld\n", res
, GetLastError());
248 SetLastError(MAGIC_DEAD
);
249 res
= GetPrinterDriverDirectoryA( NULL
, NULL
, 1, NULL
, cbBuf
, NULL
);
250 ok(res
|| (GetLastError() == RPC_X_NULL_REF_POINTER
),
251 "returned %d with %ld (expected '!=0' or '0' with " \
252 "RPC_X_NULL_REF_POINTER)\n", res
, GetLastError());
255 /* with a valid buffer, but level is too large */
257 SetLastError(MAGIC_DEAD
);
258 res
= GetPrinterDriverDirectoryA(NULL
, NULL
, 2, buffer
, cbBuf
, &pcbNeeded
);
260 /* Level not checked in win9x and wine:*/
261 if((res
!= FALSE
) && buffer
[0])
263 trace("Level '2' not checked '%s'\n", buffer
);
267 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
268 "returned %d with lasterror=%ld (expected '0' with " \
269 "ERROR_INVALID_LEVEL)\n", res
, GetLastError());
272 /* printing environments are case insensitive */
273 /* "Windows 4.0" is valid for win9x and NT */
275 SetLastError(MAGIC_DEAD
);
276 res
= GetPrinterDriverDirectoryA(NULL
, env_win9x_case
, 1,
277 buffer
, cbBuf
*2, &pcbNeeded
);
279 if(!res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
281 buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, cbBuf
*2);
282 if (buffer
== NULL
) return ;
284 SetLastError(MAGIC_DEAD
);
285 res
= GetPrinterDriverDirectoryA(NULL
, env_win9x_case
, 1,
286 buffer
, cbBuf
*2, &pcbNeeded
);
289 ok(res
&& buffer
[0], "returned %d with " \
290 "lasterror=%ld and len=%d (expected '1' with 'len > 0')\n",
291 res
, GetLastError(), lstrlenA((char *)buffer
));
294 SetLastError(MAGIC_DEAD
);
295 res
= GetPrinterDriverDirectoryA(NULL
, env_x86
, 1,
296 buffer
, cbBuf
*2, &pcbNeeded
);
298 if(!res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
300 buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, cbBuf
*2);
301 if (buffer
== NULL
) return ;
304 SetLastError(MAGIC_DEAD
);
305 res
= GetPrinterDriverDirectoryA(NULL
, env_x86
, 1,
306 buffer
, cbBuf
*2, &pcbNeeded
);
309 /* "Windows NT x86" is invalid for win9x */
310 ok( (res
&& buffer
[0]) ||
311 (!res
&& (GetLastError() == ERROR_INVALID_ENVIRONMENT
)),
312 "returned %d with lasterror=%ld and len=%d (expected '!= 0' with " \
313 "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
314 res
, GetLastError(), lstrlenA((char *)buffer
));
316 /* A Setup-Programm (PDFCreator_0.8.0) use empty strings */
317 SetLastError(MAGIC_DEAD
);
318 res
= GetPrinterDriverDirectoryA("", "", 1, buffer
, cbBuf
*2, &pcbNeeded
);
319 ok(res
, "returned %d with %ld (expected '!=0')\n", res
, GetLastError() );
321 SetLastError(MAGIC_DEAD
);
322 res
= GetPrinterDriverDirectoryA(NULL
, "", 1, buffer
, cbBuf
*2, &pcbNeeded
);
323 ok(res
, "returned %d with %ld (expected '!=0')\n", res
, GetLastError() );
325 SetLastError(MAGIC_DEAD
);
326 res
= GetPrinterDriverDirectoryA("", NULL
, 1, buffer
, cbBuf
*2, &pcbNeeded
);
327 ok(res
, "returned %d with %ld (expected '!=0')\n", res
, GetLastError() );
329 HeapFree( GetProcessHeap(), 0, buffer
);
332 static void test_OpenPrinter(void)
334 PRINTER_DEFAULTSA defaults
;
336 LPSTR default_printer
;
339 CHAR buffer
[DEFAULT_PRINTER_SIZE
];
342 SetLastError(MAGIC_DEAD
);
343 res
= OpenPrinter(NULL
, NULL
, NULL
);
344 /* The deactivated Spooler is catched here on NT3.51 */
345 RETURN_ON_DEACTIVATED_SPOOLER(res
)
346 ok(!res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
347 "returned %ld with %ld (expected '0' with ERROR_INVALID_PARAMETER)\n",
348 res
, GetLastError());
351 /* Get Handle for the local Printserver (NT only)*/
352 hprinter
= (HANDLE
) MAGIC_DEAD
;
353 SetLastError(MAGIC_DEAD
);
354 res
= OpenPrinter(NULL
, &hprinter
, NULL
);
355 /* The deactivated Spooler is catched here on XPsp2 */
356 RETURN_ON_DEACTIVATED_SPOOLER(res
)
357 ok(res
|| (!res
&& GetLastError() == ERROR_INVALID_PARAMETER
),
358 "returned %ld with %ld (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
359 res
, GetLastError());
361 ClosePrinter(hprinter
);
363 defaults
.pDatatype
=NULL
;
364 defaults
.pDevMode
=NULL
;
366 defaults
.DesiredAccess
=0;
367 hprinter
= (HANDLE
) MAGIC_DEAD
;
368 SetLastError(MAGIC_DEAD
);
369 res
= OpenPrinter(NULL
, &hprinter
, &defaults
);
370 ok(res
, "returned %ld with %ld (expected '!=0')\n", res
, GetLastError());
371 if (res
) ClosePrinter(hprinter
);
373 defaults
.DesiredAccess
=-1;
374 hprinter
= (HANDLE
) MAGIC_DEAD
;
375 SetLastError(MAGIC_DEAD
);
376 res
= OpenPrinter(NULL
, &hprinter
, &defaults
);
377 ok(!res
&& GetLastError() == ERROR_ACCESS_DENIED
,
378 "returned %ld with %ld (expected '0' with ERROR_ACCESS_DENIED)\n",
379 res
, GetLastError());
380 if (res
) ClosePrinter(hprinter
);
384 size
= sizeof(buffer
) - 3 ;
390 if (GetComputerNameA(ptr
, &size
)) {
392 hprinter
= (HANDLE
) MAGIC_DEAD
;
393 SetLastError(MAGIC_DEAD
);
394 res
= OpenPrinter(buffer
, &hprinter
, NULL
);
396 ok(res
|| (!res
&& GetLastError() == ERROR_INVALID_PARAMETER
),
397 "returned %ld with %ld (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
398 res
, GetLastError());
400 if(res
) ClosePrinter(hprinter
);
403 /* Invalid Printername */
404 hprinter
= (HANDLE
) MAGIC_DEAD
;
405 SetLastError(MAGIC_DEAD
);
406 res
= OpenPrinter("illegal,name", &hprinter
, NULL
);
407 ok(!res
&& ((GetLastError() == ERROR_INVALID_PRINTER_NAME
) ||
408 (GetLastError() == ERROR_INVALID_PARAMETER
) ),
409 "returned %ld with %ld (expected '0' with: ERROR_INVALID_PARAMETER or" \
410 "ERROR_INVALID_PRINTER_NAME)\n", res
, GetLastError());
411 if(res
) ClosePrinter(hprinter
);
414 /* Get Handle for the default Printer */
415 if ((default_printer
= find_default_printer()))
417 hprinter
= (HANDLE
) MAGIC_DEAD
;
418 SetLastError(MAGIC_DEAD
);
419 res
= OpenPrinter(default_printer
, &hprinter
, NULL
);
420 if((!res
) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE
))
422 trace("The Service 'Spooler' is required for '%s'\n", default_printer
);
425 ok(res
, "returned %ld with %ld (expected '!=0')\n", res
, GetLastError());
426 if(res
) ClosePrinter(hprinter
);
428 defaults
.pDatatype
=NULL
;
429 defaults
.pDevMode
=NULL
;
430 defaults
.DesiredAccess
=0;
432 hprinter
= (HANDLE
) MAGIC_DEAD
;
433 SetLastError(MAGIC_DEAD
);
434 res
= OpenPrinter(default_printer
, &hprinter
, &defaults
);
435 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
436 "returned %ld with %ld (expected '!=0' or '0' with " \
437 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
438 if(res
) ClosePrinter(hprinter
);
440 defaults
.pDatatype
="";
442 hprinter
= (HANDLE
) MAGIC_DEAD
;
443 SetLastError(MAGIC_DEAD
);
444 res
= OpenPrinter(default_printer
, &hprinter
, &defaults
);
445 ok(res
|| ((GetLastError() == ERROR_INVALID_DATATYPE
) ||
446 (GetLastError() == ERROR_ACCESS_DENIED
)),
447 "returned %ld with %ld (expected '!=0' or '0' with: " \
448 "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n",
449 res
, GetLastError());
450 if(res
) ClosePrinter(hprinter
);
453 defaults
.pDatatype
=NULL
;
454 defaults
.DesiredAccess
=PRINTER_ACCESS_USE
;
456 hprinter
= (HANDLE
) MAGIC_DEAD
;
457 SetLastError(MAGIC_DEAD
);
458 res
= OpenPrinter(default_printer
, &hprinter
, &defaults
);
459 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
460 "returned %ld with %ld (expected '!=0' or '0' with " \
461 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
462 if(res
) ClosePrinter(hprinter
);
465 defaults
.DesiredAccess
=PRINTER_ALL_ACCESS
;
466 hprinter
= (HANDLE
) MAGIC_DEAD
;
467 SetLastError(MAGIC_DEAD
);
468 res
= OpenPrinter(default_printer
, &hprinter
, &defaults
);
469 ok(res
|| GetLastError() == ERROR_ACCESS_DENIED
,
470 "returned %ld with %ld (expected '!=0' or '0' with " \
471 "ERROR_ACCESS_DENIED)\n", res
, GetLastError());
472 if(res
) ClosePrinter(hprinter
);
479 hwinspool
= GetModuleHandleA("winspool.drv");
480 pGetDefaultPrinterA
= (void *) GetProcAddress(hwinspool
, "GetDefaultPrinterA");
482 find_default_printer();
484 test_GetDefaultPrinter();
485 test_GetPrinterDriverDirectory();