kernel: Add some more tests for FindFirstChangeNotification.
[wine] / dlls / winspool / tests / info.c
1 /*
2  * Copyright (C) 2003, 2004 Stefan Leichter
3  * Copyright (C) 2005 Detlef Riekenberg
4  *
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.
9  *
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.
14  *
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
18  */
19
20 #include <stdarg.h>
21
22 #include "wine/test.h"
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "wingdi.h"
27 #include "winreg.h"
28 #include "winspool.h"
29
30 #define MAGIC_DEAD  0x00dead00
31 #define DEFAULT_PRINTER_SIZE 1000
32
33 static char env_x86[] = "Windows NT x86";
34 static char env_win9x_case[] = "windowS 4.0";
35
36 static HANDLE  hwinspool;
37 static FARPROC pGetDefaultPrinterA;
38
39
40 static LPSTR find_default_printer(VOID)
41 {
42     static  LPSTR   default_printer = NULL;
43     static  char    buffer[DEFAULT_PRINTER_SIZE];
44     DWORD   needed;
45     DWORD   res;
46     LPSTR   ptr;
47
48     if ((default_printer == NULL) && (pGetDefaultPrinterA))
49     {
50         /* w2k and above */
51         needed = sizeof(buffer);
52         res = pGetDefaultPrinterA(buffer, &needed);
53         if(res)  default_printer = buffer;
54         trace("default_printer: '%s'\n", default_printer);
55     }
56     if (default_printer == NULL)
57     {
58         HKEY hwindows;
59         DWORD   type;
60         /* NT 3.x and above */
61         if (RegOpenKeyEx(HKEY_CURRENT_USER, 
62                         "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
63                         0, KEY_QUERY_VALUE, &hwindows) == NO_ERROR) {
64
65             needed = sizeof(buffer);
66             if (RegQueryValueEx(hwindows, "device", NULL, 
67                                 &type, (LPBYTE)buffer, &needed) == NO_ERROR) {
68
69                 ptr = strchr(buffer, ',');
70                 if (ptr) {
71                     ptr[0] = '\0';
72                     default_printer = buffer;
73                 }
74             }
75             RegCloseKey(hwindows);
76         }
77         trace("default_printer: '%s'\n", default_printer);
78     }
79     if (default_printer == NULL)
80     {
81         /* win9x */
82         needed = sizeof(buffer);
83         res = GetProfileStringA("windows", "device", "*", buffer, needed);
84         if(res) {
85             ptr = strchr(buffer, ',');
86             if (ptr) {
87                 ptr[0] = '\0';
88                 default_printer = buffer;
89             }
90         }
91         trace("default_printer: '%s'\n", default_printer);
92     }
93     return default_printer;
94 }
95
96
97 static void test_default_printer(void)
98 {
99     BOOL    retval;
100     DWORD   exact = DEFAULT_PRINTER_SIZE;
101     DWORD   size;
102     char    buffer[DEFAULT_PRINTER_SIZE];
103
104     if (!pGetDefaultPrinterA)  return;
105         /* only supported on NT like OSes starting with win2k */
106
107     SetLastError(ERROR_SUCCESS);
108     retval = pGetDefaultPrinterA(buffer, &exact);
109     if (!retval || !exact || !strlen(buffer) ||
110         (ERROR_SUCCESS != GetLastError())) {
111         if ((ERROR_FILE_NOT_FOUND == GetLastError()) ||
112             (ERROR_INVALID_NAME == GetLastError()))
113             trace("this test requires a default printer to be set\n");
114         else {
115                 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n"
116                 "function returned %s\n"
117                 "last error 0x%08lx\n"
118                 "returned buffer size 0x%08lx\n"
119                 "returned buffer content %s\n",
120                 retval ? "true" : "false", GetLastError(), exact, buffer);
121         }
122         return;
123     }
124     SetLastError(ERROR_SUCCESS);
125     retval = pGetDefaultPrinterA(NULL, NULL); 
126     ok( !retval, "function result wrong! False expected\n");
127     ok( ERROR_INVALID_PARAMETER == GetLastError(),
128         "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08lx\n",
129         GetLastError());
130
131     SetLastError(ERROR_SUCCESS);
132     retval = pGetDefaultPrinterA(buffer, NULL); 
133     ok( !retval, "function result wrong! False expected\n");
134     ok( ERROR_INVALID_PARAMETER == GetLastError(),
135         "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08lx\n",
136         GetLastError());
137
138     SetLastError(ERROR_SUCCESS);
139     size = 0;
140     retval = pGetDefaultPrinterA(NULL, &size); 
141     ok( !retval, "function result wrong! False expected\n");
142     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
143         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
144         GetLastError());
145     ok( size == exact, "Parameter size wrong! %ld expected got %ld\n",
146         exact, size);
147
148     SetLastError(ERROR_SUCCESS);
149     size = DEFAULT_PRINTER_SIZE;
150     retval = pGetDefaultPrinterA(NULL, &size); 
151     ok( !retval, "function result wrong! False expected\n");
152     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
153         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
154         GetLastError());
155     ok( size == exact, "Parameter size wrong! %ld expected got %ld\n",
156         exact, size);
157
158     size = 0;
159     retval = pGetDefaultPrinterA(buffer, &size); 
160     ok( !retval, "function result wrong! False expected\n");
161     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
162         "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08lx\n",
163         GetLastError());
164     ok( size == exact, "Parameter size wrong! %ld expected got %ld\n",
165         exact, size);
166
167     size = exact;
168     retval = pGetDefaultPrinterA(buffer, &size); 
169     ok( retval, "function result wrong! True expected\n");
170     ok( size == exact, "Parameter size wrong! %ld expected got %ld\n",
171         exact, size);
172 }
173
174 static void test_printer_directory(void)
175 {   LPBYTE buffer = NULL;
176     DWORD  cbBuf = 0, pcbNeeded = 0;
177     BOOL   res;
178
179     SetLastError(0x00dead00);
180     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf);
181     trace("GetPrinterDriverDirectoryA: first call returned 0x%04x, "
182           "buffer size 0x%08lx\n", res, cbBuf);
183
184     if((res == 0) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
185     {
186         trace("The Service 'Spooler' is required for this test\n");
187         return;
188     }
189     ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
190         "returned %d with lasterror=%ld (expected '0' with " \
191         "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError());
192
193     if (!cbBuf) {
194         trace("no valid buffer size returned, skipping tests\n");
195         return;
196     }
197
198     buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2);
199     if (buffer == NULL)  return ;
200
201     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded);
202     ok( res, "expected result != 0, got %d\n", res);
203     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
204                             pcbNeeded, cbBuf);
205
206     res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded);
207     ok( res, "expected result != 0, got %d\n", res);
208     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
209                             pcbNeeded, cbBuf);
210  
211     SetLastError(0x00dead00);
212     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded);
213     ok( !res , "expected result == 0, got %d\n", res);
214     ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n",
215                             pcbNeeded, cbBuf);
216     
217     ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(),
218         "last error set to %ld instead of ERROR_INSUFFICIENT_BUFFER\n",
219         GetLastError());
220
221     SetLastError(0x00dead00);
222     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded);
223     ok( (!res && ERROR_INVALID_USER_BUFFER == GetLastError()) || 
224         ( res && ERROR_INVALID_PARAMETER == GetLastError()) ,
225          "expected either result == 0 and "
226          "last error == ERROR_INVALID_USER_BUFFER "
227          "or result != 0 and last error == ERROR_INVALID_PARAMETER "
228          "got result %d and last error == %ld\n", res, GetLastError());
229
230     SetLastError(0x00dead00);
231     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL);
232     ok( (!res && RPC_X_NULL_REF_POINTER == GetLastError()) || res,
233          "expected either result == 0 and "
234          "last error == RPC_X_NULL_REF_POINTER or result != 0 "
235          "got result %d and last error == %ld\n", res, GetLastError());
236
237     SetLastError(0x00dead00);
238     res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL);
239     ok( (!res && RPC_X_NULL_REF_POINTER == GetLastError()) || 
240         ( res && ERROR_INVALID_PARAMETER == GetLastError()) ,
241          "expected either result == 0 and "
242          "last error == RPC_X_NULL_REF_POINTER "
243          "or result != 0 and last error == ERROR_INVALID_PARAMETER "
244          "got result %d and last error == %ld\n", res, GetLastError());
245
246     /* with a valid buffer, but level is too large */
247     buffer[0] = '\0';
248     SetLastError(0x00dead00);
249     res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded);
250
251     /* Level not checked in win9x and wine:*/
252     if((res != FALSE) && buffer[0])
253     {
254         trace("invalid Level '2' not checked (valid Level is '1') => '%s'\n", 
255                 buffer);
256     }
257     else
258     {
259         ok( !res && (GetLastError() == ERROR_INVALID_LEVEL),
260         "returned %d with lasterror=%ld (expected '0' with " \
261         "ERROR_INVALID_LEVEL)\n", res, GetLastError());
262     }
263
264     /* printing environments are case insensitive */
265     /* "Windows 4.0" is valid for win9x and NT */
266     buffer[0] = '\0';
267     SetLastError(0x00dead00);
268     res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
269                                         buffer, cbBuf*2, &pcbNeeded);
270
271     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
272         cbBuf = pcbNeeded;
273         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
274         if (buffer == NULL)  return ;
275
276         SetLastError(0x00dead00);
277         res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 
278                                         buffer, cbBuf*2, &pcbNeeded);
279     }
280
281     ok(res && buffer[0], "returned %d with " \
282         "lasterror=%ld and len=%d (expected '1' with 'len > 0')\n", 
283         res, GetLastError(), lstrlenA((char *)buffer));
284
285     buffer[0] = '\0';
286     SetLastError(0x00dead00);
287     res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
288                                         buffer, cbBuf*2, &pcbNeeded);
289
290     if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
291         cbBuf = pcbNeeded;
292         buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2);
293         if (buffer == NULL)  return ;
294
295         buffer[0] = '\0';
296         SetLastError(0x00dead00);
297         res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 
298                                         buffer, cbBuf*2, &pcbNeeded);
299     }
300
301     /* "Windows NT x86" is invalid for win9x */
302     ok( (res && buffer[0]) ||
303         (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 
304         "returned %d with lasterror=%ld and len=%d (expected '!= 0' with " \
305         "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n",
306         res, GetLastError(), lstrlenA((char *)buffer));
307
308     HeapFree( GetProcessHeap(), 0, buffer);
309 }
310
311 static void test_openprinter(void)
312 {
313     PRINTER_DEFAULTSA defaults;
314     HANDLE  hprinter;
315     LPSTR   default_printer;
316     DWORD   res;
317     DWORD   size;
318     CHAR    buffer[DEFAULT_PRINTER_SIZE];
319     LPSTR   ptr;
320
321     SetLastError(MAGIC_DEAD);
322     res = OpenPrinter(NULL, NULL, NULL);    
323     if((res == 0) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE))
324     {
325         trace("The Service 'Spooler' is required for this test\n");
326         return;
327     }
328     ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER),
329         "returned %ld with %ld (expected '0' with ERROR_INVALID_PARAMETER)\n",
330         res, GetLastError());
331
332
333     /* Get Handle for the local Printserver (NT only)*/
334     hprinter = (HANDLE) MAGIC_DEAD;
335     SetLastError(MAGIC_DEAD);
336     res = OpenPrinter(NULL, &hprinter, NULL);
337     ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
338         "returned %ld with %ld (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
339         res, GetLastError());
340     if(res) {
341         ClosePrinter(hprinter);
342
343         defaults.pDatatype=NULL;
344         defaults.pDevMode=NULL;
345
346         defaults.DesiredAccess=0;
347         hprinter = (HANDLE) MAGIC_DEAD;
348         SetLastError(MAGIC_DEAD);
349         res = OpenPrinter(NULL, &hprinter, &defaults);
350         ok(res, "returned %ld with %ld (expected '!=0')\n", res, GetLastError());
351         if (res) ClosePrinter(hprinter);
352
353         defaults.DesiredAccess=-1;
354         hprinter = (HANDLE) MAGIC_DEAD;
355         SetLastError(MAGIC_DEAD);
356         res = OpenPrinter(NULL, &hprinter, &defaults);
357         ok(!res && GetLastError() == ERROR_ACCESS_DENIED,
358             "returned %ld with %ld (expected '0' with ERROR_ACCESS_DENIED)\n", 
359             res, GetLastError());
360         if (res) ClosePrinter(hprinter);
361
362     }
363
364     size = sizeof(buffer) - 3 ;
365     ptr = buffer;
366     ptr[0] = '\\';
367     ptr++;
368     ptr[0] = '\\';
369     ptr++;
370     if (GetComputerNameA(ptr, &size)) {
371
372         hprinter = (HANDLE) MAGIC_DEAD;
373         SetLastError(MAGIC_DEAD);
374         res = OpenPrinter(buffer, &hprinter, NULL);
375         todo_wine {
376         ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
377             "returned %ld with %ld (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
378             res, GetLastError());
379         }
380         if(res) ClosePrinter(hprinter);
381     }
382
383     /* Invalid Printername */
384     hprinter = (HANDLE) MAGIC_DEAD;
385     SetLastError(MAGIC_DEAD);
386     res = OpenPrinter("illegal,name", &hprinter, NULL);
387     ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 
388                 (GetLastError() == ERROR_INVALID_PARAMETER) ),
389        "returned %ld with %ld (expected '0' with: ERROR_INVALID_PARAMETER or" \
390        "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError());
391     if(res) ClosePrinter(hprinter);
392
393
394     /* Get Handle for the default Printer */
395     if ((default_printer = find_default_printer()))
396     {
397         hprinter = (HANDLE) MAGIC_DEAD;
398         SetLastError(MAGIC_DEAD);
399         res = OpenPrinter(default_printer, &hprinter, NULL);
400         ok(res, "returned %ld with %ld (expected '!=0')\n", res, GetLastError());
401         if(res) ClosePrinter(hprinter);
402
403         defaults.pDatatype=NULL;
404         defaults.pDevMode=NULL;
405         defaults.DesiredAccess=0;
406
407         hprinter = (HANDLE) MAGIC_DEAD;
408         SetLastError(MAGIC_DEAD);
409         res = OpenPrinter(default_printer, &hprinter, &defaults);
410         ok(res, "returned %ld with %ld (expected '!=0')\n", res, GetLastError());
411         if(res) ClosePrinter(hprinter);
412
413         defaults.pDatatype="";
414
415         hprinter = (HANDLE) MAGIC_DEAD;
416         SetLastError(MAGIC_DEAD);
417         res = OpenPrinter(default_printer, &hprinter, &defaults);
418         ok(res || (GetLastError() == ERROR_INVALID_DATATYPE ||
419                    GetLastError() == RPC_S_SERVER_UNAVAILABLE),
420             "returned %ld with %ld (expected '!=0' or '0' with: " \
421             "ERROR_INVALID_DATATYPE or RPC_S_SERVER_UNAVAILABLE)\n",
422             res, GetLastError());
423         if(res) ClosePrinter(hprinter);
424
425
426         defaults.pDatatype=NULL;
427         defaults.DesiredAccess=PRINTER_ACCESS_USE;
428
429         hprinter = (HANDLE) MAGIC_DEAD;
430         SetLastError(MAGIC_DEAD);
431         res = OpenPrinter(default_printer, &hprinter, &defaults);
432         ok(res || (GetLastError() == ERROR_ACCESS_DENIED ||
433                    GetLastError() == RPC_S_SERVER_UNAVAILABLE),
434             "returned %ld with %ld (expected '!=0' or '0' with: " \
435             "ERROR_ACCESS_DENIED or RPC_S_SERVER_UNAVAILABLE)\n",
436             res, GetLastError());
437         if(res) ClosePrinter(hprinter);
438
439
440         defaults.DesiredAccess=PRINTER_ALL_ACCESS;
441         hprinter = (HANDLE) MAGIC_DEAD;
442         SetLastError(MAGIC_DEAD);
443         res = OpenPrinter(default_printer, &hprinter, &defaults);
444         ok(res || (GetLastError() == ERROR_ACCESS_DENIED ||
445                    GetLastError() == RPC_S_SERVER_UNAVAILABLE),
446             "returned %ld with %ld (expected '!=0' or '0' with: " \
447             "ERROR_ACCESS_DENIED or RPC_S_SERVER_UNAVAILABLE)\n",
448             res, GetLastError());
449         if(res) ClosePrinter(hprinter);
450     }
451
452 }
453
454 START_TEST(info)
455 {
456     hwinspool = GetModuleHandleA("winspool.drv");
457     pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA");
458
459     find_default_printer();
460
461     test_default_printer();
462     test_printer_directory();
463     test_openprinter();
464 }