]> git.samba.org - samba.git/blob - testprogs/win32/spoolss/spoolss.c
testprogs: also print printer info during GetPrinter spoolss test.
[samba.git] / testprogs / win32 / spoolss / spoolss.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for spoolss rpc operations
4
5    Copyright (C) Guenther Deschner 2009-2010
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 /****************************************************************************
22 ****************************************************************************/
23
24 #include "spoolss.h"
25 #include "string.h"
26 #include "torture.h"
27
28 /****************************************************************************
29 ****************************************************************************/
30
31 static BOOL test_OpenPrinter(struct torture_context *tctx,
32                              LPSTR printername,
33                              LPPRINTER_DEFAULTS defaults,
34                              LPHANDLE handle)
35 {
36         torture_comment(tctx, "Testing OpenPrinter(%s)", printername);
37
38         if (!OpenPrinter(printername, handle, defaults)) {
39                 char tmp[1024];
40                 sprintf(tmp, "failed to open printer %s, error was: 0x%08x\n",
41                         printername, GetLastError());
42                 torture_fail(tctx, tmp);
43         }
44
45         return TRUE;
46 }
47
48 /****************************************************************************
49 ****************************************************************************/
50
51 static BOOL test_ClosePrinter(struct torture_context *tctx,
52                               HANDLE handle)
53 {
54         torture_comment(tctx, "Testing ClosePrinter");
55
56         if (!ClosePrinter(handle)) {
57                 char tmp[1024];
58                 sprintf(tmp, "failed to close printer, error was: %s\n",
59                         errstr(GetLastError()));
60                 torture_fail(tctx, tmp);
61         }
62
63         return TRUE;
64 }
65
66
67 /****************************************************************************
68 ****************************************************************************/
69
70 static BOOL test_EnumPrinters(struct torture_context *tctx,
71                               LPSTR servername)
72 {
73         DWORD levels[]  = { 1, 2, 5 };
74         DWORD success[] = { 1, 1, 1 };
75         DWORD i;
76         DWORD flags = PRINTER_ENUM_NAME;
77         LPBYTE buffer = NULL;
78
79         for (i=0; i < ARRAY_SIZE(levels); i++) {
80
81                 DWORD needed = 0;
82                 DWORD returned = 0;
83                 DWORD err = 0;
84                 char tmp[1024];
85
86                 torture_comment(tctx, "Testing EnumPrinters level %d", levels[i]);
87
88                 EnumPrinters(flags, servername, levels[i], NULL, 0, &needed, &returned);
89                 err = GetLastError();
90                 if (err == ERROR_INSUFFICIENT_BUFFER) {
91                         err = 0;
92                         buffer = malloc(needed);
93                         torture_assert(tctx, buffer, "malloc failed");
94                         if (!EnumPrinters(flags, servername, levels[i], buffer, needed, &needed, &returned)) {
95                                 err = GetLastError();
96                         }
97                 }
98                 if (err) {
99                         sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
100                                 levels[i], servername, needed, errstr(err));
101                         if (success[i]) {
102                                 torture_fail(tctx, tmp);
103                         } else {
104                                 torture_warning(tctx, tmp);
105                         }
106                 }
107
108                 if (tctx->print) {
109                         print_printer_info_bylevel(levels[i], buffer, returned);
110                 }
111
112                 free(buffer);
113                 buffer = NULL;
114         }
115
116         return TRUE;
117 }
118
119 /****************************************************************************
120 ****************************************************************************/
121
122 static BOOL test_EnumDrivers(struct torture_context *tctx,
123                              LPSTR servername,
124                              LPSTR architecture)
125 {
126         DWORD levels[]  = { 1, 2, 3, 4, 5, 6 };
127         DWORD success[] = { 1, 1, 1, 1, 1, 1 };
128         DWORD i;
129         LPBYTE buffer = NULL;
130
131         for (i=0; i < ARRAY_SIZE(levels); i++) {
132
133                 DWORD needed = 0;
134                 DWORD returned = 0;
135                 DWORD err = 0;
136                 char tmp[1024];
137
138                 torture_comment(tctx, "Testing EnumPrinterDrivers level %d", levels[i]);
139
140                 EnumPrinterDrivers(servername, architecture, levels[i], NULL, 0, &needed, &returned);
141                 err = GetLastError();
142                 if (err == ERROR_INSUFFICIENT_BUFFER) {
143                         err = 0;
144                         buffer = malloc(needed);
145                         torture_assert(tctx, buffer, "malloc failed");
146                         if (!EnumPrinterDrivers(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
147                                 err = GetLastError();
148                         }
149                 }
150                 if (err) {
151                         sprintf(tmp, "EnumPrinterDrivers failed level %d on [%s] (buffer size = %d), error: %s\n",
152                                 levels[i], servername, needed, errstr(err));
153                         if (success[i]) {
154                                 torture_fail(tctx, tmp);
155                         } else {
156                                 torture_warning(tctx, tmp);
157                         }
158                 }
159
160                 if (tctx->print) {
161                         print_driver_info_bylevel(levels[i], buffer, returned);
162                 }
163
164                 free(buffer);
165                 buffer = NULL;
166         }
167
168         return TRUE;
169 }
170
171 /****************************************************************************
172 ****************************************************************************/
173
174 static BOOL test_GetForm(struct torture_context *tctx,
175                          LPSTR servername,
176                          HANDLE handle,
177                          LPSTR formname)
178 {
179         DWORD levels[]  = { 1, 2 };
180         DWORD success[] = { 1, 0 };
181         DWORD i;
182         LPBYTE buffer = NULL;
183
184         for (i=0; i < ARRAY_SIZE(levels); i++) {
185
186                 DWORD needed = 0;
187                 DWORD err = 0;
188                 char tmp[1024];
189
190                 torture_comment(tctx, "Testing GetForm(%s) level %d", formname, levels[i]);
191
192                 GetForm(handle, formname, levels[i], NULL, 0, &needed);
193                 err = GetLastError();
194                 if (err == ERROR_INSUFFICIENT_BUFFER) {
195                         err = 0;
196                         buffer = malloc(needed);
197                         torture_assert(tctx, buffer, "malloc failed");
198                         if (!GetForm(handle, formname, levels[i], buffer, needed, &needed)) {
199                                 err = GetLastError();
200                         }
201                 }
202                 if (err) {
203                         sprintf(tmp, "GetForm failed level %d on [%s] (buffer size = %d), error: %s\n",
204                                 levels[i], servername, needed, errstr(err));
205                         if (success[i]) {
206                                 torture_fail(tctx, tmp);
207                         } else {
208                                 torture_warning(tctx, tmp);
209                         }
210                 }
211
212                 free(buffer);
213                 buffer = NULL;
214         }
215
216         return TRUE;
217 }
218
219 /****************************************************************************
220 ****************************************************************************/
221
222 static BOOL test_EnumForms(struct torture_context *tctx,
223                            LPSTR servername,
224                            HANDLE handle)
225 {
226         DWORD levels[]  = { 1, 2 };
227         DWORD success[] = { 1, 0 };
228         DWORD i;
229         LPBYTE buffer = NULL;
230
231         for (i=0; i < ARRAY_SIZE(levels); i++) {
232
233                 DWORD needed = 0;
234                 DWORD returned = 0;
235                 DWORD err = 0;
236                 char tmp[1024];
237
238                 torture_comment(tctx, "Testing EnumForms level %d", levels[i]);
239
240                 EnumForms(handle, levels[i], NULL, 0, &needed, &returned);
241                 err = GetLastError();
242                 if (err == ERROR_INSUFFICIENT_BUFFER) {
243                         err = 0;
244                         buffer = malloc(needed);
245                         torture_assert(tctx, buffer, "malloc failed");
246                         if (!EnumForms(handle, levels[i], buffer, needed, &needed, &returned)) {
247                                 err = GetLastError();
248                         }
249                 }
250                 if (err) {
251                         sprintf(tmp, "EnumForms failed level %d on [%s] (buffer size = %d), error: %s\n",
252                                 levels[i], servername, needed, errstr(err));
253                         if (success[i]) {
254                                 torture_fail(tctx, tmp);
255                         } else {
256                                 torture_warning(tctx, tmp);
257                         }
258                 }
259
260                 free(buffer);
261                 buffer = NULL;
262         }
263
264         return TRUE;
265 }
266
267 /****************************************************************************
268 ****************************************************************************/
269
270 static BOOL test_EnumPorts(struct torture_context *tctx,
271                            LPSTR servername)
272 {
273         DWORD levels[]  = { 1, 2 };
274         DWORD success[] = { 1, 1 };
275         DWORD i;
276         LPBYTE buffer = NULL;
277
278         for (i=0; i < ARRAY_SIZE(levels); i++) {
279
280                 DWORD needed = 0;
281                 DWORD returned = 0;
282                 DWORD err = 0;
283                 char tmp[1024];
284
285                 torture_comment(tctx, "Testing EnumPorts level %d", levels[i]);
286
287                 EnumPorts(servername, levels[i], NULL, 0, &needed, &returned);
288                 err = GetLastError();
289                 if (err == ERROR_INSUFFICIENT_BUFFER) {
290                         err = 0;
291                         buffer = malloc(needed);
292                         torture_assert(tctx, buffer, "malloc failed");
293                         if (!EnumPorts(servername, levels[i], buffer, needed, &needed, &returned)) {
294                                 err = GetLastError();
295                         }
296                 }
297                 if (err) {
298                         sprintf(tmp, "EnumPorts failed level %d on [%s] (buffer size = %d), error: %s\n",
299                                 levels[i], servername, needed, errstr(err));
300                         if (success[i]) {
301                                 torture_fail(tctx, tmp);
302                         } else {
303                                 torture_warning(tctx, tmp);
304                         }
305                 }
306
307                 free(buffer);
308                 buffer = NULL;
309         }
310
311         return TRUE;
312 }
313
314 /****************************************************************************
315 ****************************************************************************/
316
317 static BOOL test_EnumMonitors(struct torture_context *tctx,
318                               LPSTR servername)
319 {
320         DWORD levels[]  = { 1, 2 };
321         DWORD success[] = { 1, 1 };
322         DWORD i;
323         LPBYTE buffer = NULL;
324
325         for (i=0; i < ARRAY_SIZE(levels); i++) {
326
327                 DWORD needed = 0;
328                 DWORD returned = 0;
329                 DWORD err = 0;
330                 char tmp[1024];
331
332                 torture_comment(tctx, "Testing EnumMonitors level %d", levels[i]);
333
334                 EnumMonitors(servername, levels[i], NULL, 0, &needed, &returned);
335                 err = GetLastError();
336                 if (err == ERROR_INSUFFICIENT_BUFFER) {
337                         err = 0;
338                         buffer = malloc(needed);
339                         torture_assert(tctx, buffer, "malloc failed");
340                         if (!EnumMonitors(servername, levels[i], buffer, needed, &needed, &returned)) {
341                                 err = GetLastError();
342                         }
343                 }
344                 if (err) {
345                         sprintf(tmp, "EnumMonitors failed level %d on [%s] (buffer size = %d), error: %s\n",
346                                 levels[i], servername, needed, errstr(err));
347                         if (success[i]) {
348                                 torture_fail(tctx, tmp);
349                         } else {
350                                 torture_warning(tctx, tmp);
351                         }
352                 }
353
354                 free(buffer);
355                 buffer = NULL;
356         }
357
358         return TRUE;
359 }
360
361 /****************************************************************************
362 ****************************************************************************/
363
364 static BOOL test_EnumPrintProcessors(struct torture_context *tctx,
365                                      LPSTR servername,
366                                      LPSTR architecture)
367 {
368         DWORD levels[]  = { 1 };
369         DWORD success[] = { 1 };
370         DWORD i;
371         LPBYTE buffer = NULL;
372
373         for (i=0; i < ARRAY_SIZE(levels); i++) {
374
375                 DWORD needed = 0;
376                 DWORD returned = 0;
377                 DWORD err = 0;
378                 char tmp[1024];
379
380                 torture_comment(tctx, "Testing EnumPrintProcessors level %d", levels[i]);
381
382                 EnumPrintProcessors(servername, architecture, levels[i], NULL, 0, &needed, &returned);
383                 err = GetLastError();
384                 if (err == ERROR_INSUFFICIENT_BUFFER) {
385                         err = 0;
386                         buffer = malloc(needed);
387                         torture_assert(tctx, buffer, "malloc failed");
388                         if (!EnumPrintProcessors(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
389                                 err = GetLastError();
390                         }
391                 }
392                 if (err) {
393                         sprintf(tmp, "EnumPrintProcessors failed level %d on [%s] (buffer size = %d), error: %s\n",
394                                 levels[i], servername, needed, errstr(err));
395                         if (success[i]) {
396                                 torture_fail(tctx, tmp);
397                         } else {
398                                 torture_warning(tctx, tmp);
399                         }
400                 }
401
402                 free(buffer);
403                 buffer = NULL;
404         }
405
406         return TRUE;
407 }
408
409 /****************************************************************************
410 ****************************************************************************/
411
412 static BOOL test_EnumPrintProcessorDatatypes(struct torture_context *tctx,
413                                              LPSTR servername)
414 {
415         DWORD levels[]  = { 1 };
416         DWORD success[] = { 1 };
417         DWORD i;
418         LPBYTE buffer = NULL;
419
420         for (i=0; i < ARRAY_SIZE(levels); i++) {
421
422                 DWORD needed = 0;
423                 DWORD returned = 0;
424                 DWORD err = 0;
425                 char tmp[1024];
426
427                 torture_comment(tctx, "Testing EnumPrintProcessorDatatypes level %d", levels[i]);
428
429                 EnumPrintProcessorDatatypes(servername, "winprint", levels[i], NULL, 0, &needed, &returned);
430                 err = GetLastError();
431                 if (err == ERROR_INSUFFICIENT_BUFFER) {
432                         err = 0;
433                         buffer = malloc(needed);
434                         torture_assert(tctx, buffer, "malloc failed");
435                         if (!EnumPrintProcessorDatatypes(servername, "winprint", levels[i], buffer, needed, &needed, &returned)) {
436                                 err = GetLastError();
437                         }
438                 }
439                 if (err) {
440                         sprintf(tmp, "EnumPrintProcessorDatatypes failed level %d on [%s] (buffer size = %d), error: %s\n",
441                                 levels[i], servername, needed, errstr(err));
442                         if (success[i]) {
443                                 torture_fail(tctx, tmp);
444                         } else {
445                                 torture_warning(tctx, tmp);
446                         }
447                 }
448
449                 free(buffer);
450                 buffer = NULL;
451         }
452
453         return TRUE;
454 }
455
456 /****************************************************************************
457 ****************************************************************************/
458
459 static BOOL test_EnumPrinterKey(struct torture_context *tctx,
460                                 LPSTR servername,
461                                 HANDLE handle,
462                                 LPCSTR key)
463 {
464         LPSTR buffer = NULL;
465         DWORD needed = 0;
466         DWORD err = 0;
467         char tmp[1024];
468
469         torture_comment(tctx, "Testing EnumPrinterKey(%s)", key);
470
471         err = EnumPrinterKey(handle, key, NULL, 0, &needed);
472         if (err == ERROR_MORE_DATA) {
473                 buffer = (LPTSTR)malloc(needed);
474                 torture_assert(tctx, buffer, "malloc failed");
475                 err = EnumPrinterKey(handle, key, buffer, needed, &needed);
476         }
477         if (err) {
478                 sprintf(tmp, "EnumPrinterKey(%s) failed on [%s] (buffer size = %d), error: %s\n",
479                         key, servername, needed, errstr(err));
480                 torture_fail(tctx, tmp);
481         }
482
483         if (tctx->print) {
484                 print_printer_keys(buffer);
485         }
486
487         free(buffer);
488
489         return TRUE;
490 }
491
492 /****************************************************************************
493 ****************************************************************************/
494
495 static BOOL test_GetPrinter(struct torture_context *tctx,
496                             LPSTR printername,
497                             HANDLE handle)
498 {
499         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 7, 8 };
500         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
501         DWORD i;
502         LPBYTE buffer = NULL;
503
504         for (i=0; i < ARRAY_SIZE(levels); i++) {
505
506                 DWORD needed = 0;
507                 DWORD err = 0;
508                 char tmp[1024];
509
510                 torture_comment(tctx, "Testing GetPrinter level %d", levels[i]);
511
512                 GetPrinter(handle, levels[i], NULL, 0, &needed);
513                 err = GetLastError();
514                 if (err == ERROR_INSUFFICIENT_BUFFER) {
515                         err = 0;
516                         buffer = malloc(needed);
517                         torture_assert(tctx, buffer, "malloc failed");
518                         if (!GetPrinter(handle, levels[i], buffer, needed, &needed)) {
519                                 err = GetLastError();
520                         }
521                 }
522                 if (err) {
523                         sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
524                                 levels[i], printername, needed, errstr(err));
525                         if (success[i]) {
526                                 torture_fail(tctx, tmp);
527                         } else {
528                                 torture_warning(tctx, tmp);
529                         }
530                 }
531
532                 if (tctx->print) {
533                         print_printer_info_bylevel(levels[i], buffer, 1);
534                 }
535
536                 free(buffer);
537                 buffer = NULL;
538         }
539
540         return TRUE;
541 }
542
543 /****************************************************************************
544 ****************************************************************************/
545
546 static BOOL test_GetPrinterDriver(struct torture_context *tctx,
547                                   LPSTR printername,
548                                   LPSTR architecture,
549                                   HANDLE handle)
550 {
551         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 8 };
552         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1 };
553         DWORD i;
554         LPBYTE buffer = NULL;
555
556         for (i=0; i < ARRAY_SIZE(levels); i++) {
557
558                 DWORD needed = 0;
559                 DWORD err = 0;
560                 char tmp[1024];
561
562                 torture_comment(tctx, "Testing GetPrinterDriver level %d", levels[i]);
563
564                 GetPrinterDriver(handle, architecture, levels[i], NULL, 0, &needed);
565                 err = GetLastError();
566                 if (err == ERROR_INSUFFICIENT_BUFFER) {
567                         err = 0;
568                         buffer = malloc(needed);
569                         torture_assert(tctx, buffer, "malloc failed");
570                         if (!GetPrinterDriver(handle, architecture, levels[i], buffer, needed, &needed)) {
571                                 err = GetLastError();
572                         }
573                 }
574                 if (err) {
575                         sprintf(tmp, "GetPrinterDriver failed level %d on [%s] (buffer size = %d), error: %s\n",
576                                 levels[i], printername, needed, errstr(err));
577                         if (success[i]) {
578                                 torture_fail(tctx, tmp);
579                         } else {
580                                 torture_warning(tctx, tmp);
581                         }
582                 }
583
584                 if (tctx->print) {
585                         print_driver_info_bylevel(levels[i], buffer, 1);
586                 }
587
588                 free(buffer);
589                 buffer = NULL;
590         }
591
592         return TRUE;
593 }
594
595
596 /****************************************************************************
597 ****************************************************************************/
598
599 static BOOL test_EnumJobs(struct torture_context *tctx,
600                           LPSTR printername,
601                           HANDLE handle)
602 {
603         DWORD levels[]  = { 1, 2, 3, 4 };
604         DWORD success[] = { 1, 1, 1, 1 };
605         DWORD i;
606         LPBYTE buffer = NULL;
607
608         for (i=0; i < ARRAY_SIZE(levels); i++) {
609
610                 DWORD needed = 0;
611                 DWORD returned = 0;
612                 DWORD err = 0;
613                 char tmp[1024];
614
615                 torture_comment(tctx, "Testing EnumJobs level %d", levels[i]);
616
617                 EnumJobs(handle, 0, 100, levels[i], NULL, 0, &needed, &returned);
618                 err = GetLastError();
619                 if (err == ERROR_INSUFFICIENT_BUFFER) {
620                         err = 0;
621                         buffer = malloc(needed);
622                         torture_assert(tctx, buffer, "malloc failed");
623                         if (!EnumJobs(handle, 0, 100, levels[i], buffer, needed, &needed, &returned)) {
624                                 err = GetLastError();
625                         }
626                 }
627                 if (err) {
628                         sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
629                                 levels[i], printername, needed, errstr(err));
630                         if (success[i]) {
631                                 torture_fail(tctx, tmp);
632                         } else {
633                                 torture_warning(tctx, tmp);
634                         }
635                 }
636
637                 free(buffer);
638                 buffer = NULL;
639         }
640
641         return TRUE;
642 }
643
644 /****************************************************************************
645 ****************************************************************************/
646
647 static BOOL test_EnumPrinterDataEx(struct torture_context *tctx,
648                                    LPSTR servername,
649                                    LPSTR keyname,
650                                    HANDLE handle,
651                                    LPBYTE *buffer_p,
652                                    DWORD *returned_p)
653 {
654         LPBYTE buffer = NULL;
655         DWORD needed = 0;
656         DWORD returned = 0;
657         DWORD err = 0;
658         char tmp[1024];
659
660         torture_comment(tctx, "Testing EnumPrinterDataEx(%s)", keyname);
661
662         err = EnumPrinterDataEx(handle, keyname, NULL, 0, &needed, &returned);
663         if (err == ERROR_MORE_DATA) {
664                 buffer = malloc(needed);
665                 torture_assert(tctx, buffer, "malloc failed");
666                 err = EnumPrinterDataEx(handle, keyname, buffer, needed, &needed, &returned);
667         }
668         if (err) {
669                 sprintf(tmp, "EnumPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
670                         keyname, servername, needed, errstr(err));
671                 torture_fail(tctx, tmp);
672         }
673
674         if (tctx->print) {
675                 DWORD i;
676                 LPPRINTER_ENUM_VALUES v = (LPPRINTER_ENUM_VALUES)buffer;
677                 for (i=0; i < returned; i++) {
678                         print_printer_enum_values(&v[i]);
679                 }
680         }
681
682         if (returned_p) {
683                 *returned_p = returned;
684         }
685
686         if (buffer_p) {
687                 *buffer_p = buffer;
688         } else {
689                 free(buffer);
690         }
691
692         return TRUE;
693 }
694
695
696 /****************************************************************************
697 ****************************************************************************/
698
699 static BOOL test_OnePrinter(struct torture_context *tctx,
700                             LPSTR printername,
701                             LPSTR architecture,
702                             LPPRINTER_DEFAULTS defaults)
703 {
704         HANDLE handle;
705         BOOL ret = TRUE;
706
707         torture_comment(tctx, "Testing Printer %s", printername);
708
709         ret &= test_OpenPrinter(tctx, printername, defaults, &handle);
710         ret &= test_GetPrinter(tctx, printername, handle);
711         ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
712         ret &= test_EnumForms(tctx, printername, handle);
713         ret &= test_EnumJobs(tctx, printername, handle);
714         ret &= test_EnumPrinterKey(tctx, printername, handle, "");
715         ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
716         ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL);
717         ret &= test_ClosePrinter(tctx, handle);
718
719         return ret;
720 }
721
722 /****************************************************************************
723 ****************************************************************************/
724
725 static BOOL test_EachPrinter(struct torture_context *tctx,
726                              LPSTR servername,
727                              LPSTR architecture,
728                              LPPRINTER_DEFAULTS defaults)
729 {
730         DWORD needed = 0;
731         DWORD returned = 0;
732         DWORD err = 0;
733         char tmp[1024];
734         DWORD i;
735         DWORD flags = PRINTER_ENUM_NAME;
736         PPRINTER_INFO_1 buffer = NULL;
737         BOOL ret = TRUE;
738
739         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
740
741         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
742         err = GetLastError();
743         if (err == ERROR_INSUFFICIENT_BUFFER) {
744                 err = 0;
745                 buffer = (PPRINTER_INFO_1)malloc(needed);
746                 torture_assert(tctx, buffer, "malloc failed");
747                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
748                         err = GetLastError();
749                 }
750         }
751         if (err) {
752                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
753                         1, servername, needed, errstr(err));
754                 torture_fail(tctx, tmp);
755         }
756
757         for (i=0; i < returned; i++) {
758                 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
759         }
760
761         free(buffer);
762
763         return ret;
764 }
765
766 /****************************************************************************
767 ****************************************************************************/
768
769 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
770                                             LPSTR servername,
771                                             LPSTR architecture)
772 {
773         DWORD levels[]  = { 1 };
774         DWORD success[] = { 1 };
775         DWORD i;
776         LPBYTE buffer = NULL;
777
778         for (i=0; i < ARRAY_SIZE(levels); i++) {
779
780                 DWORD needed = 0;
781                 DWORD err = 0;
782                 char tmp[1024];
783
784                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
785
786                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
787                 err = GetLastError();
788                 if (err == ERROR_INSUFFICIENT_BUFFER) {
789                         err = 0;
790                         buffer = malloc(needed);
791                         torture_assert(tctx, buffer, "malloc failed");
792                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
793                                 err = GetLastError();
794                         }
795                 }
796                 if (err) {
797                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
798                                 levels[i], servername, needed, errstr(err));
799                         if (success[i]) {
800                                 torture_fail(tctx, tmp);
801                         } else {
802                                 torture_warning(tctx, tmp);
803                         }
804                 }
805
806                 free(buffer);
807                 buffer = NULL;
808         }
809
810         return TRUE;
811 }
812
813 /****************************************************************************
814 ****************************************************************************/
815
816 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
817                                            LPSTR servername,
818                                            LPSTR architecture)
819 {
820         DWORD levels[]  = { 1 };
821         DWORD success[] = { 1 };
822         DWORD i;
823         LPBYTE buffer = NULL;
824
825         for (i=0; i < ARRAY_SIZE(levels); i++) {
826
827                 DWORD needed = 0;
828                 DWORD err = 0;
829                 char tmp[1024];
830
831                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
832
833                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
834                 err = GetLastError();
835                 if (err == ERROR_INSUFFICIENT_BUFFER) {
836                         err = 0;
837                         buffer = malloc(needed);
838                         torture_assert(tctx, buffer, "malloc failed");
839                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
840                                 err = GetLastError();
841                         }
842                 }
843                 if (err) {
844                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
845                                 levels[i], servername, needed, errstr(err));
846                         if (success[i]) {
847                                 torture_fail(tctx, tmp);
848                         } else {
849                                 torture_warning(tctx, tmp);
850                         }
851                 }
852
853                 free(buffer);
854                 buffer = NULL;
855         }
856
857         return TRUE;
858 }
859
860 /****************************************************************************
861 ****************************************************************************/
862
863 static BOOL test_GetPrinterData(struct torture_context *tctx,
864                                 LPSTR servername,
865                                 LPSTR valuename,
866                                 HANDLE handle,
867                                 DWORD *type_p,
868                                 LPBYTE *buffer_p,
869                                 DWORD *size_p)
870 {
871         LPBYTE buffer = NULL;
872         DWORD needed = 0;
873         DWORD type;
874         DWORD err = 0;
875         char tmp[1024];
876
877         torture_comment(tctx, "Testing GetPrinterData(%s)", valuename);
878
879         err = GetPrinterData(handle, valuename, &type, NULL, 0, &needed);
880         if (err == ERROR_MORE_DATA) {
881                 buffer = (LPBYTE)malloc(needed);
882                 torture_assert(tctx, buffer, "malloc failed");
883                 err = GetPrinterData(handle, valuename, &type, buffer, needed, &needed);
884         }
885         if (err) {
886                 sprintf(tmp, "GetPrinterData(%s) failed on [%s] (buffer size = %d), error: %s\n",
887                         valuename, servername, needed, errstr(err));
888                 torture_fail(tctx, tmp);
889         }
890
891         if (tctx->print) {
892                 print_printer_data("PrinterDriverData", valuename, needed, buffer, type);
893         }
894
895         if (type_p) {
896                 *type_p = type;
897         }
898
899         if (size_p) {
900                 *size_p = needed;
901         }
902
903         if (buffer_p) {
904                 *buffer_p = buffer;
905         } else {
906                 free(buffer);
907         }
908
909         return TRUE;
910 }
911
912 /****************************************************************************
913 ****************************************************************************/
914
915 static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
916                                   LPSTR servername,
917                                   LPSTR keyname,
918                                   LPSTR valuename,
919                                   HANDLE handle,
920                                   DWORD *type_p,
921                                   LPBYTE *buffer_p,
922                                   DWORD *size_p)
923 {
924         LPBYTE buffer = NULL;
925         DWORD needed = 0;
926         DWORD type;
927         DWORD err = 0;
928         char tmp[1024];
929
930         torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)", keyname, valuename);
931
932         err = GetPrinterDataEx(handle, keyname, valuename, &type, NULL, 0, &needed);
933         if (err == ERROR_MORE_DATA) {
934                 buffer = (LPBYTE)malloc(needed);
935                 torture_assert(tctx, buffer, "malloc failed");
936                 err = GetPrinterDataEx(handle, keyname, valuename, &type, buffer, needed, &needed);
937         }
938         if (err) {
939                 sprintf(tmp, "GetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
940                         valuename, servername, needed, errstr(err));
941                 torture_fail(tctx, tmp);
942         }
943
944         if (tctx->print) {
945                 print_printer_data(keyname, valuename, needed, buffer, type);
946         }
947
948         if (type_p) {
949                 *type_p = type;
950         }
951
952         if (size_p) {
953                 *size_p = needed;
954         }
955
956         if (buffer_p) {
957                 *buffer_p = buffer;
958         } else {
959                 free(buffer);
960         }
961
962         return TRUE;
963 }
964
965 /****************************************************************************
966 ****************************************************************************/
967
968 static BOOL test_PrinterData(struct torture_context *tctx,
969                              LPSTR servername,
970                              HANDLE handle)
971 {
972         BOOL ret = TRUE;
973         DWORD i;
974         DWORD type, type_ex;
975         LPBYTE buffer, buffer_ex;
976         DWORD size, size_ex;
977         LPSTR valuenames[] = {
978                 SPLREG_DEFAULT_SPOOL_DIRECTORY,
979                 SPLREG_MAJOR_VERSION,
980                 SPLREG_MINOR_VERSION,
981                 SPLREG_DS_PRESENT,
982                 SPLREG_DNS_MACHINE_NAME,
983                 SPLREG_ARCHITECTURE,
984                 SPLREG_OS_VERSION
985         };
986
987         for (i=0; i < ARRAY_SIZE(valuenames); i++) {
988                 ret &= test_GetPrinterData(tctx, servername, valuenames[i], handle, &type, &buffer, &size);
989                 ret &= test_GetPrinterDataEx(tctx, servername, "random", valuenames[i], handle, &type_ex, &buffer_ex, &size_ex);
990                 torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
991                 torture_assert_int_equal(tctx, size, size_ex, "size mismatch");
992                 torture_assert_mem_equal(tctx, buffer, buffer_ex, size, "buffer mismatch");
993                 free(buffer);
994                 free(buffer_ex);
995         }
996
997         return ret;
998 }
999
1000 /****************************************************************************
1001 ****************************************************************************/
1002
1003 int main(int argc, char *argv[])
1004 {
1005         BOOL ret = FALSE;
1006         LPSTR servername;
1007         LPSTR architecture = "Windows NT x86";
1008         HANDLE server_handle;
1009         PRINTER_DEFAULTS defaults_admin, defaults_use;
1010         struct torture_context *tctx;
1011
1012         if (argc < 2) {
1013                 fprintf(stderr, "usage: %s <servername> [print]\n", argv[0]);
1014                 exit(-1);
1015         }
1016
1017         tctx = malloc(sizeof(struct torture_context));
1018         if (!tctx) {
1019                 fprintf(stderr, "out of memory\n");
1020                 exit(-1);
1021         }
1022         memset(tctx, '\0', sizeof(*tctx));
1023
1024         servername = argv[1];
1025
1026         if (argc >= 3) {
1027                 if (strcmp(argv[2], "print") == 0) {
1028                         tctx->print = TRUE;
1029                 }
1030         }
1031
1032         defaults_admin.pDatatype = NULL;
1033         defaults_admin.pDevMode = NULL;
1034         defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
1035
1036         defaults_use.pDatatype = NULL;
1037         defaults_use.pDevMode = NULL;
1038         defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
1039
1040         ret &= test_EnumPrinters(tctx, servername);
1041         ret &= test_EnumDrivers(tctx, servername, architecture);
1042         ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
1043 /*      ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
1044         ret &= test_PrinterData(tctx, servername, server_handle);
1045         ret &= test_EnumForms(tctx, servername, server_handle);
1046         ret &= test_ClosePrinter(tctx, server_handle);
1047         ret &= test_EnumPorts(tctx, servername);
1048         ret &= test_EnumMonitors(tctx, servername);
1049         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
1050         ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
1051         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
1052         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
1053         ret &= test_EachPrinter(tctx, servername, architecture, NULL);
1054
1055         if (!ret) {
1056                 if (tctx->last_reason) {
1057                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
1058                 }
1059                 free(tctx);
1060                 return -1;
1061         }
1062
1063         printf("%s run successfully\n", argv[0]);
1064
1065         free(tctx);
1066         return 0;
1067 }