testprogs: print all driver info levels in spoolss testsuite.
[abartlet/samba.git/.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                 free(buffer);
533                 buffer = NULL;
534         }
535
536         return TRUE;
537 }
538
539 /****************************************************************************
540 ****************************************************************************/
541
542 static BOOL test_GetPrinterDriver(struct torture_context *tctx,
543                                   LPSTR printername,
544                                   LPSTR architecture,
545                                   HANDLE handle)
546 {
547         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 8 };
548         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1 };
549         DWORD i;
550         LPBYTE buffer = NULL;
551
552         for (i=0; i < ARRAY_SIZE(levels); i++) {
553
554                 DWORD needed = 0;
555                 DWORD err = 0;
556                 char tmp[1024];
557
558                 torture_comment(tctx, "Testing GetPrinterDriver level %d", levels[i]);
559
560                 GetPrinterDriver(handle, architecture, levels[i], NULL, 0, &needed);
561                 err = GetLastError();
562                 if (err == ERROR_INSUFFICIENT_BUFFER) {
563                         err = 0;
564                         buffer = malloc(needed);
565                         torture_assert(tctx, buffer, "malloc failed");
566                         if (!GetPrinterDriver(handle, architecture, levels[i], buffer, needed, &needed)) {
567                                 err = GetLastError();
568                         }
569                 }
570                 if (err) {
571                         sprintf(tmp, "GetPrinterDriver failed level %d on [%s] (buffer size = %d), error: %s\n",
572                                 levels[i], printername, needed, errstr(err));
573                         if (success[i]) {
574                                 torture_fail(tctx, tmp);
575                         } else {
576                                 torture_warning(tctx, tmp);
577                         }
578                 }
579
580                 if (tctx->print) {
581                         print_driver_info_bylevel(levels[i], buffer, 1);
582                 }
583
584                 free(buffer);
585                 buffer = NULL;
586         }
587
588         return TRUE;
589 }
590
591
592 /****************************************************************************
593 ****************************************************************************/
594
595 static BOOL test_EnumJobs(struct torture_context *tctx,
596                           LPSTR printername,
597                           HANDLE handle)
598 {
599         DWORD levels[]  = { 1, 2, 3, 4 };
600         DWORD success[] = { 1, 1, 1, 1 };
601         DWORD i;
602         LPBYTE buffer = NULL;
603
604         for (i=0; i < ARRAY_SIZE(levels); i++) {
605
606                 DWORD needed = 0;
607                 DWORD returned = 0;
608                 DWORD err = 0;
609                 char tmp[1024];
610
611                 torture_comment(tctx, "Testing EnumJobs level %d", levels[i]);
612
613                 EnumJobs(handle, 0, 100, levels[i], NULL, 0, &needed, &returned);
614                 err = GetLastError();
615                 if (err == ERROR_INSUFFICIENT_BUFFER) {
616                         err = 0;
617                         buffer = malloc(needed);
618                         torture_assert(tctx, buffer, "malloc failed");
619                         if (!EnumJobs(handle, 0, 100, levels[i], buffer, needed, &needed, &returned)) {
620                                 err = GetLastError();
621                         }
622                 }
623                 if (err) {
624                         sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
625                                 levels[i], printername, needed, errstr(err));
626                         if (success[i]) {
627                                 torture_fail(tctx, tmp);
628                         } else {
629                                 torture_warning(tctx, tmp);
630                         }
631                 }
632
633                 free(buffer);
634                 buffer = NULL;
635         }
636
637         return TRUE;
638 }
639
640 /****************************************************************************
641 ****************************************************************************/
642
643 static BOOL test_EnumPrinterDataEx(struct torture_context *tctx,
644                                    LPSTR servername,
645                                    LPSTR keyname,
646                                    HANDLE handle,
647                                    LPBYTE *buffer_p,
648                                    DWORD *returned_p)
649 {
650         LPBYTE buffer = NULL;
651         DWORD needed = 0;
652         DWORD returned = 0;
653         DWORD err = 0;
654         char tmp[1024];
655
656         torture_comment(tctx, "Testing EnumPrinterDataEx(%s)", keyname);
657
658         err = EnumPrinterDataEx(handle, keyname, NULL, 0, &needed, &returned);
659         if (err == ERROR_MORE_DATA) {
660                 buffer = malloc(needed);
661                 torture_assert(tctx, buffer, "malloc failed");
662                 err = EnumPrinterDataEx(handle, keyname, buffer, needed, &needed, &returned);
663         }
664         if (err) {
665                 sprintf(tmp, "EnumPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
666                         keyname, servername, needed, errstr(err));
667                 torture_fail(tctx, tmp);
668         }
669
670         if (tctx->print) {
671                 DWORD i;
672                 LPPRINTER_ENUM_VALUES v = (LPPRINTER_ENUM_VALUES)buffer;
673                 for (i=0; i < returned; i++) {
674                         print_printer_enum_values(&v[i]);
675                 }
676         }
677
678         if (returned_p) {
679                 *returned_p = returned;
680         }
681
682         if (buffer_p) {
683                 *buffer_p = buffer;
684         } else {
685                 free(buffer);
686         }
687
688         return TRUE;
689 }
690
691
692 /****************************************************************************
693 ****************************************************************************/
694
695 static BOOL test_OnePrinter(struct torture_context *tctx,
696                             LPSTR printername,
697                             LPSTR architecture,
698                             LPPRINTER_DEFAULTS defaults)
699 {
700         HANDLE handle;
701         BOOL ret = TRUE;
702
703         torture_comment(tctx, "Testing Printer %s", printername);
704
705         ret &= test_OpenPrinter(tctx, printername, defaults, &handle);
706         ret &= test_GetPrinter(tctx, printername, handle);
707         ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
708         ret &= test_EnumForms(tctx, printername, handle);
709         ret &= test_EnumJobs(tctx, printername, handle);
710         ret &= test_EnumPrinterKey(tctx, printername, handle, "");
711         ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
712         ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL);
713         ret &= test_ClosePrinter(tctx, handle);
714
715         return ret;
716 }
717
718 /****************************************************************************
719 ****************************************************************************/
720
721 static BOOL test_EachPrinter(struct torture_context *tctx,
722                              LPSTR servername,
723                              LPSTR architecture,
724                              LPPRINTER_DEFAULTS defaults)
725 {
726         DWORD needed = 0;
727         DWORD returned = 0;
728         DWORD err = 0;
729         char tmp[1024];
730         DWORD i;
731         DWORD flags = PRINTER_ENUM_NAME;
732         PPRINTER_INFO_1 buffer = NULL;
733         BOOL ret = TRUE;
734
735         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
736
737         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
738         err = GetLastError();
739         if (err == ERROR_INSUFFICIENT_BUFFER) {
740                 err = 0;
741                 buffer = (PPRINTER_INFO_1)malloc(needed);
742                 torture_assert(tctx, buffer, "malloc failed");
743                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
744                         err = GetLastError();
745                 }
746         }
747         if (err) {
748                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
749                         1, servername, needed, errstr(err));
750                 torture_fail(tctx, tmp);
751         }
752
753         for (i=0; i < returned; i++) {
754                 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
755         }
756
757         free(buffer);
758
759         return ret;
760 }
761
762 /****************************************************************************
763 ****************************************************************************/
764
765 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
766                                             LPSTR servername,
767                                             LPSTR architecture)
768 {
769         DWORD levels[]  = { 1 };
770         DWORD success[] = { 1 };
771         DWORD i;
772         LPBYTE buffer = NULL;
773
774         for (i=0; i < ARRAY_SIZE(levels); i++) {
775
776                 DWORD needed = 0;
777                 DWORD err = 0;
778                 char tmp[1024];
779
780                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
781
782                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
783                 err = GetLastError();
784                 if (err == ERROR_INSUFFICIENT_BUFFER) {
785                         err = 0;
786                         buffer = malloc(needed);
787                         torture_assert(tctx, buffer, "malloc failed");
788                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
789                                 err = GetLastError();
790                         }
791                 }
792                 if (err) {
793                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
794                                 levels[i], servername, needed, errstr(err));
795                         if (success[i]) {
796                                 torture_fail(tctx, tmp);
797                         } else {
798                                 torture_warning(tctx, tmp);
799                         }
800                 }
801
802                 free(buffer);
803                 buffer = NULL;
804         }
805
806         return TRUE;
807 }
808
809 /****************************************************************************
810 ****************************************************************************/
811
812 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
813                                            LPSTR servername,
814                                            LPSTR architecture)
815 {
816         DWORD levels[]  = { 1 };
817         DWORD success[] = { 1 };
818         DWORD i;
819         LPBYTE buffer = NULL;
820
821         for (i=0; i < ARRAY_SIZE(levels); i++) {
822
823                 DWORD needed = 0;
824                 DWORD err = 0;
825                 char tmp[1024];
826
827                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
828
829                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
830                 err = GetLastError();
831                 if (err == ERROR_INSUFFICIENT_BUFFER) {
832                         err = 0;
833                         buffer = malloc(needed);
834                         torture_assert(tctx, buffer, "malloc failed");
835                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
836                                 err = GetLastError();
837                         }
838                 }
839                 if (err) {
840                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
841                                 levels[i], servername, needed, errstr(err));
842                         if (success[i]) {
843                                 torture_fail(tctx, tmp);
844                         } else {
845                                 torture_warning(tctx, tmp);
846                         }
847                 }
848
849                 free(buffer);
850                 buffer = NULL;
851         }
852
853         return TRUE;
854 }
855
856 /****************************************************************************
857 ****************************************************************************/
858
859 static BOOL test_GetPrinterData(struct torture_context *tctx,
860                                 LPSTR servername,
861                                 LPSTR valuename,
862                                 HANDLE handle,
863                                 DWORD *type_p,
864                                 LPBYTE *buffer_p,
865                                 DWORD *size_p)
866 {
867         LPBYTE buffer = NULL;
868         DWORD needed = 0;
869         DWORD type;
870         DWORD err = 0;
871         char tmp[1024];
872
873         torture_comment(tctx, "Testing GetPrinterData(%s)", valuename);
874
875         err = GetPrinterData(handle, valuename, &type, NULL, 0, &needed);
876         if (err == ERROR_MORE_DATA) {
877                 buffer = (LPBYTE)malloc(needed);
878                 torture_assert(tctx, buffer, "malloc failed");
879                 err = GetPrinterData(handle, valuename, &type, buffer, needed, &needed);
880         }
881         if (err) {
882                 sprintf(tmp, "GetPrinterData(%s) failed on [%s] (buffer size = %d), error: %s\n",
883                         valuename, servername, needed, errstr(err));
884                 torture_fail(tctx, tmp);
885         }
886
887         if (tctx->print) {
888                 print_printer_data("PrinterDriverData", valuename, needed, buffer, type);
889         }
890
891         if (type_p) {
892                 *type_p = type;
893         }
894
895         if (size_p) {
896                 *size_p = needed;
897         }
898
899         if (buffer_p) {
900                 *buffer_p = buffer;
901         } else {
902                 free(buffer);
903         }
904
905         return TRUE;
906 }
907
908 /****************************************************************************
909 ****************************************************************************/
910
911 static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
912                                   LPSTR servername,
913                                   LPSTR keyname,
914                                   LPSTR valuename,
915                                   HANDLE handle,
916                                   DWORD *type_p,
917                                   LPBYTE *buffer_p,
918                                   DWORD *size_p)
919 {
920         LPBYTE buffer = NULL;
921         DWORD needed = 0;
922         DWORD type;
923         DWORD err = 0;
924         char tmp[1024];
925
926         torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)", keyname, valuename);
927
928         err = GetPrinterDataEx(handle, keyname, valuename, &type, NULL, 0, &needed);
929         if (err == ERROR_MORE_DATA) {
930                 buffer = (LPBYTE)malloc(needed);
931                 torture_assert(tctx, buffer, "malloc failed");
932                 err = GetPrinterDataEx(handle, keyname, valuename, &type, buffer, needed, &needed);
933         }
934         if (err) {
935                 sprintf(tmp, "GetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
936                         valuename, servername, needed, errstr(err));
937                 torture_fail(tctx, tmp);
938         }
939
940         if (tctx->print) {
941                 print_printer_data(keyname, valuename, needed, buffer, type);
942         }
943
944         if (type_p) {
945                 *type_p = type;
946         }
947
948         if (size_p) {
949                 *size_p = needed;
950         }
951
952         if (buffer_p) {
953                 *buffer_p = buffer;
954         } else {
955                 free(buffer);
956         }
957
958         return TRUE;
959 }
960
961 /****************************************************************************
962 ****************************************************************************/
963
964 static BOOL test_PrinterData(struct torture_context *tctx,
965                              LPSTR servername,
966                              HANDLE handle)
967 {
968         BOOL ret = TRUE;
969         DWORD i;
970         DWORD type, type_ex;
971         LPBYTE buffer, buffer_ex;
972         DWORD size, size_ex;
973         LPSTR valuenames[] = {
974                 SPLREG_DEFAULT_SPOOL_DIRECTORY,
975                 SPLREG_MAJOR_VERSION,
976                 SPLREG_MINOR_VERSION,
977                 SPLREG_DS_PRESENT,
978                 SPLREG_DNS_MACHINE_NAME,
979                 SPLREG_ARCHITECTURE,
980                 SPLREG_OS_VERSION
981         };
982
983         for (i=0; i < ARRAY_SIZE(valuenames); i++) {
984                 ret &= test_GetPrinterData(tctx, servername, valuenames[i], handle, &type, &buffer, &size);
985                 ret &= test_GetPrinterDataEx(tctx, servername, "random", valuenames[i], handle, &type_ex, &buffer_ex, &size_ex);
986                 torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
987                 torture_assert_int_equal(tctx, size, size_ex, "size mismatch");
988                 torture_assert_mem_equal(tctx, buffer, buffer_ex, size, "buffer mismatch");
989                 free(buffer);
990                 free(buffer_ex);
991         }
992
993         return ret;
994 }
995
996 /****************************************************************************
997 ****************************************************************************/
998
999 int main(int argc, char *argv[])
1000 {
1001         BOOL ret = FALSE;
1002         LPSTR servername;
1003         LPSTR architecture = "Windows NT x86";
1004         HANDLE server_handle;
1005         PRINTER_DEFAULTS defaults_admin, defaults_use;
1006         struct torture_context *tctx;
1007
1008         if (argc < 2) {
1009                 fprintf(stderr, "usage: %s <servername> [print]\n", argv[0]);
1010                 exit(-1);
1011         }
1012
1013         tctx = malloc(sizeof(struct torture_context));
1014         if (!tctx) {
1015                 fprintf(stderr, "out of memory\n");
1016                 exit(-1);
1017         }
1018         memset(tctx, '\0', sizeof(*tctx));
1019
1020         servername = argv[1];
1021
1022         if (argc >= 3) {
1023                 if (strcmp(argv[2], "print") == 0) {
1024                         tctx->print = TRUE;
1025                 }
1026         }
1027
1028         defaults_admin.pDatatype = NULL;
1029         defaults_admin.pDevMode = NULL;
1030         defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
1031
1032         defaults_use.pDatatype = NULL;
1033         defaults_use.pDevMode = NULL;
1034         defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
1035
1036         ret &= test_EnumPrinters(tctx, servername);
1037         ret &= test_EnumDrivers(tctx, servername, architecture);
1038         ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
1039 /*      ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
1040         ret &= test_PrinterData(tctx, servername, server_handle);
1041         ret &= test_EnumForms(tctx, servername, server_handle);
1042         ret &= test_ClosePrinter(tctx, server_handle);
1043         ret &= test_EnumPorts(tctx, servername);
1044         ret &= test_EnumMonitors(tctx, servername);
1045         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
1046         ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
1047         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
1048         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
1049         ret &= test_EachPrinter(tctx, servername, architecture, NULL);
1050
1051         if (!ret) {
1052                 if (tctx->last_reason) {
1053                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
1054                 }
1055                 free(tctx);
1056                 return -1;
1057         }
1058
1059         printf("%s run successfully\n", argv[0]);
1060
1061         free(tctx);
1062         return 0;
1063 }