testprogs: print form info levels in EnumForms(),GetForm() spoolss tests.
[ira/wip.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                 if (tctx->print) {
213                         print_form_info_bylevel(levels[i], buffer, 1);
214                 }
215
216                 free(buffer);
217                 buffer = NULL;
218         }
219
220         return TRUE;
221 }
222
223 /****************************************************************************
224 ****************************************************************************/
225
226 static BOOL test_EnumForms(struct torture_context *tctx,
227                            LPSTR servername,
228                            HANDLE handle)
229 {
230         DWORD levels[]  = { 1, 2 };
231         DWORD success[] = { 1, 0 };
232         DWORD i;
233         LPBYTE buffer = NULL;
234
235         for (i=0; i < ARRAY_SIZE(levels); i++) {
236
237                 DWORD needed = 0;
238                 DWORD returned = 0;
239                 DWORD err = 0;
240                 char tmp[1024];
241
242                 torture_comment(tctx, "Testing EnumForms level %d", levels[i]);
243
244                 EnumForms(handle, levels[i], NULL, 0, &needed, &returned);
245                 err = GetLastError();
246                 if (err == ERROR_INSUFFICIENT_BUFFER) {
247                         err = 0;
248                         buffer = malloc(needed);
249                         torture_assert(tctx, buffer, "malloc failed");
250                         if (!EnumForms(handle, levels[i], buffer, needed, &needed, &returned)) {
251                                 err = GetLastError();
252                         }
253                 }
254                 if (err) {
255                         sprintf(tmp, "EnumForms failed level %d on [%s] (buffer size = %d), error: %s\n",
256                                 levels[i], servername, needed, errstr(err));
257                         if (success[i]) {
258                                 torture_fail(tctx, tmp);
259                         } else {
260                                 torture_warning(tctx, tmp);
261                         }
262                 }
263
264                 if (tctx->print) {
265                         print_form_info_bylevel(levels[i], buffer, returned);
266                 }
267
268                 free(buffer);
269                 buffer = NULL;
270         }
271
272         return TRUE;
273 }
274
275 /****************************************************************************
276 ****************************************************************************/
277
278 static BOOL test_EnumPorts(struct torture_context *tctx,
279                            LPSTR servername)
280 {
281         DWORD levels[]  = { 1, 2 };
282         DWORD success[] = { 1, 1 };
283         DWORD i;
284         LPBYTE buffer = NULL;
285
286         for (i=0; i < ARRAY_SIZE(levels); i++) {
287
288                 DWORD needed = 0;
289                 DWORD returned = 0;
290                 DWORD err = 0;
291                 char tmp[1024];
292
293                 torture_comment(tctx, "Testing EnumPorts level %d", levels[i]);
294
295                 EnumPorts(servername, levels[i], NULL, 0, &needed, &returned);
296                 err = GetLastError();
297                 if (err == ERROR_INSUFFICIENT_BUFFER) {
298                         err = 0;
299                         buffer = malloc(needed);
300                         torture_assert(tctx, buffer, "malloc failed");
301                         if (!EnumPorts(servername, levels[i], buffer, needed, &needed, &returned)) {
302                                 err = GetLastError();
303                         }
304                 }
305                 if (err) {
306                         sprintf(tmp, "EnumPorts failed level %d on [%s] (buffer size = %d), error: %s\n",
307                                 levels[i], servername, needed, errstr(err));
308                         if (success[i]) {
309                                 torture_fail(tctx, tmp);
310                         } else {
311                                 torture_warning(tctx, tmp);
312                         }
313                 }
314
315                 free(buffer);
316                 buffer = NULL;
317         }
318
319         return TRUE;
320 }
321
322 /****************************************************************************
323 ****************************************************************************/
324
325 static BOOL test_EnumMonitors(struct torture_context *tctx,
326                               LPSTR servername)
327 {
328         DWORD levels[]  = { 1, 2 };
329         DWORD success[] = { 1, 1 };
330         DWORD i;
331         LPBYTE buffer = NULL;
332
333         for (i=0; i < ARRAY_SIZE(levels); i++) {
334
335                 DWORD needed = 0;
336                 DWORD returned = 0;
337                 DWORD err = 0;
338                 char tmp[1024];
339
340                 torture_comment(tctx, "Testing EnumMonitors level %d", levels[i]);
341
342                 EnumMonitors(servername, levels[i], NULL, 0, &needed, &returned);
343                 err = GetLastError();
344                 if (err == ERROR_INSUFFICIENT_BUFFER) {
345                         err = 0;
346                         buffer = malloc(needed);
347                         torture_assert(tctx, buffer, "malloc failed");
348                         if (!EnumMonitors(servername, levels[i], buffer, needed, &needed, &returned)) {
349                                 err = GetLastError();
350                         }
351                 }
352                 if (err) {
353                         sprintf(tmp, "EnumMonitors failed level %d on [%s] (buffer size = %d), error: %s\n",
354                                 levels[i], servername, needed, errstr(err));
355                         if (success[i]) {
356                                 torture_fail(tctx, tmp);
357                         } else {
358                                 torture_warning(tctx, tmp);
359                         }
360                 }
361
362                 free(buffer);
363                 buffer = NULL;
364         }
365
366         return TRUE;
367 }
368
369 /****************************************************************************
370 ****************************************************************************/
371
372 static BOOL test_EnumPrintProcessors(struct torture_context *tctx,
373                                      LPSTR servername,
374                                      LPSTR architecture)
375 {
376         DWORD levels[]  = { 1 };
377         DWORD success[] = { 1 };
378         DWORD i;
379         LPBYTE buffer = NULL;
380
381         for (i=0; i < ARRAY_SIZE(levels); i++) {
382
383                 DWORD needed = 0;
384                 DWORD returned = 0;
385                 DWORD err = 0;
386                 char tmp[1024];
387
388                 torture_comment(tctx, "Testing EnumPrintProcessors level %d", levels[i]);
389
390                 EnumPrintProcessors(servername, architecture, levels[i], NULL, 0, &needed, &returned);
391                 err = GetLastError();
392                 if (err == ERROR_INSUFFICIENT_BUFFER) {
393                         err = 0;
394                         buffer = malloc(needed);
395                         torture_assert(tctx, buffer, "malloc failed");
396                         if (!EnumPrintProcessors(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
397                                 err = GetLastError();
398                         }
399                 }
400                 if (err) {
401                         sprintf(tmp, "EnumPrintProcessors failed level %d on [%s] (buffer size = %d), error: %s\n",
402                                 levels[i], servername, needed, errstr(err));
403                         if (success[i]) {
404                                 torture_fail(tctx, tmp);
405                         } else {
406                                 torture_warning(tctx, tmp);
407                         }
408                 }
409
410                 free(buffer);
411                 buffer = NULL;
412         }
413
414         return TRUE;
415 }
416
417 /****************************************************************************
418 ****************************************************************************/
419
420 static BOOL test_EnumPrintProcessorDatatypes(struct torture_context *tctx,
421                                              LPSTR servername)
422 {
423         DWORD levels[]  = { 1 };
424         DWORD success[] = { 1 };
425         DWORD i;
426         LPBYTE buffer = NULL;
427
428         for (i=0; i < ARRAY_SIZE(levels); i++) {
429
430                 DWORD needed = 0;
431                 DWORD returned = 0;
432                 DWORD err = 0;
433                 char tmp[1024];
434
435                 torture_comment(tctx, "Testing EnumPrintProcessorDatatypes level %d", levels[i]);
436
437                 EnumPrintProcessorDatatypes(servername, "winprint", levels[i], NULL, 0, &needed, &returned);
438                 err = GetLastError();
439                 if (err == ERROR_INSUFFICIENT_BUFFER) {
440                         err = 0;
441                         buffer = malloc(needed);
442                         torture_assert(tctx, buffer, "malloc failed");
443                         if (!EnumPrintProcessorDatatypes(servername, "winprint", levels[i], buffer, needed, &needed, &returned)) {
444                                 err = GetLastError();
445                         }
446                 }
447                 if (err) {
448                         sprintf(tmp, "EnumPrintProcessorDatatypes failed level %d on [%s] (buffer size = %d), error: %s\n",
449                                 levels[i], servername, needed, errstr(err));
450                         if (success[i]) {
451                                 torture_fail(tctx, tmp);
452                         } else {
453                                 torture_warning(tctx, tmp);
454                         }
455                 }
456
457                 free(buffer);
458                 buffer = NULL;
459         }
460
461         return TRUE;
462 }
463
464 /****************************************************************************
465 ****************************************************************************/
466
467 static BOOL test_EnumPrinterKey(struct torture_context *tctx,
468                                 LPSTR servername,
469                                 HANDLE handle,
470                                 LPCSTR key)
471 {
472         LPSTR buffer = NULL;
473         DWORD needed = 0;
474         DWORD err = 0;
475         char tmp[1024];
476
477         torture_comment(tctx, "Testing EnumPrinterKey(%s)", key);
478
479         err = EnumPrinterKey(handle, key, NULL, 0, &needed);
480         if (err == ERROR_MORE_DATA) {
481                 buffer = (LPTSTR)malloc(needed);
482                 torture_assert(tctx, buffer, "malloc failed");
483                 err = EnumPrinterKey(handle, key, buffer, needed, &needed);
484         }
485         if (err) {
486                 sprintf(tmp, "EnumPrinterKey(%s) failed on [%s] (buffer size = %d), error: %s\n",
487                         key, servername, needed, errstr(err));
488                 torture_fail(tctx, tmp);
489         }
490
491         if (tctx->print) {
492                 print_printer_keys(buffer);
493         }
494
495         free(buffer);
496
497         return TRUE;
498 }
499
500 /****************************************************************************
501 ****************************************************************************/
502
503 static BOOL test_GetPrinter(struct torture_context *tctx,
504                             LPSTR printername,
505                             HANDLE handle)
506 {
507         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 7, 8 };
508         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
509         DWORD i;
510         LPBYTE buffer = NULL;
511
512         for (i=0; i < ARRAY_SIZE(levels); i++) {
513
514                 DWORD needed = 0;
515                 DWORD err = 0;
516                 char tmp[1024];
517
518                 torture_comment(tctx, "Testing GetPrinter level %d", levels[i]);
519
520                 GetPrinter(handle, levels[i], NULL, 0, &needed);
521                 err = GetLastError();
522                 if (err == ERROR_INSUFFICIENT_BUFFER) {
523                         err = 0;
524                         buffer = malloc(needed);
525                         torture_assert(tctx, buffer, "malloc failed");
526                         if (!GetPrinter(handle, levels[i], buffer, needed, &needed)) {
527                                 err = GetLastError();
528                         }
529                 }
530                 if (err) {
531                         sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
532                                 levels[i], printername, needed, errstr(err));
533                         if (success[i]) {
534                                 torture_fail(tctx, tmp);
535                         } else {
536                                 torture_warning(tctx, tmp);
537                         }
538                 }
539
540                 if (tctx->print) {
541                         print_printer_info_bylevel(levels[i], buffer, 1);
542                 }
543
544                 free(buffer);
545                 buffer = NULL;
546         }
547
548         return TRUE;
549 }
550
551 /****************************************************************************
552 ****************************************************************************/
553
554 static BOOL test_GetPrinterDriver(struct torture_context *tctx,
555                                   LPSTR printername,
556                                   LPSTR architecture,
557                                   HANDLE handle)
558 {
559         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 8 };
560         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1 };
561         DWORD i;
562         LPBYTE buffer = NULL;
563
564         for (i=0; i < ARRAY_SIZE(levels); i++) {
565
566                 DWORD needed = 0;
567                 DWORD err = 0;
568                 char tmp[1024];
569
570                 torture_comment(tctx, "Testing GetPrinterDriver level %d", levels[i]);
571
572                 GetPrinterDriver(handle, architecture, levels[i], NULL, 0, &needed);
573                 err = GetLastError();
574                 if (err == ERROR_INSUFFICIENT_BUFFER) {
575                         err = 0;
576                         buffer = malloc(needed);
577                         torture_assert(tctx, buffer, "malloc failed");
578                         if (!GetPrinterDriver(handle, architecture, levels[i], buffer, needed, &needed)) {
579                                 err = GetLastError();
580                         }
581                 }
582                 if (err) {
583                         sprintf(tmp, "GetPrinterDriver failed level %d on [%s] (buffer size = %d), error: %s\n",
584                                 levels[i], printername, needed, errstr(err));
585                         if (success[i]) {
586                                 torture_fail(tctx, tmp);
587                         } else {
588                                 torture_warning(tctx, tmp);
589                         }
590                 }
591
592                 if (tctx->print) {
593                         print_driver_info_bylevel(levels[i], buffer, 1);
594                 }
595
596                 free(buffer);
597                 buffer = NULL;
598         }
599
600         return TRUE;
601 }
602
603
604 /****************************************************************************
605 ****************************************************************************/
606
607 static BOOL test_EnumJobs(struct torture_context *tctx,
608                           LPSTR printername,
609                           HANDLE handle)
610 {
611         DWORD levels[]  = { 1, 2, 3, 4 };
612         DWORD success[] = { 1, 1, 1, 1 };
613         DWORD i;
614         LPBYTE buffer = NULL;
615
616         for (i=0; i < ARRAY_SIZE(levels); i++) {
617
618                 DWORD needed = 0;
619                 DWORD returned = 0;
620                 DWORD err = 0;
621                 char tmp[1024];
622
623                 torture_comment(tctx, "Testing EnumJobs level %d", levels[i]);
624
625                 EnumJobs(handle, 0, 100, levels[i], NULL, 0, &needed, &returned);
626                 err = GetLastError();
627                 if (err == ERROR_INSUFFICIENT_BUFFER) {
628                         err = 0;
629                         buffer = malloc(needed);
630                         torture_assert(tctx, buffer, "malloc failed");
631                         if (!EnumJobs(handle, 0, 100, levels[i], buffer, needed, &needed, &returned)) {
632                                 err = GetLastError();
633                         }
634                 }
635                 if (err) {
636                         sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
637                                 levels[i], printername, needed, errstr(err));
638                         if (success[i]) {
639                                 torture_fail(tctx, tmp);
640                         } else {
641                                 torture_warning(tctx, tmp);
642                         }
643                 }
644
645                 free(buffer);
646                 buffer = NULL;
647         }
648
649         return TRUE;
650 }
651
652 /****************************************************************************
653 ****************************************************************************/
654
655 static BOOL test_EnumPrinterDataEx(struct torture_context *tctx,
656                                    LPSTR servername,
657                                    LPSTR keyname,
658                                    HANDLE handle,
659                                    LPBYTE *buffer_p,
660                                    DWORD *returned_p)
661 {
662         LPBYTE buffer = NULL;
663         DWORD needed = 0;
664         DWORD returned = 0;
665         DWORD err = 0;
666         char tmp[1024];
667
668         torture_comment(tctx, "Testing EnumPrinterDataEx(%s)", keyname);
669
670         err = EnumPrinterDataEx(handle, keyname, NULL, 0, &needed, &returned);
671         if (err == ERROR_MORE_DATA) {
672                 buffer = malloc(needed);
673                 torture_assert(tctx, buffer, "malloc failed");
674                 err = EnumPrinterDataEx(handle, keyname, buffer, needed, &needed, &returned);
675         }
676         if (err) {
677                 sprintf(tmp, "EnumPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
678                         keyname, servername, needed, errstr(err));
679                 torture_fail(tctx, tmp);
680         }
681
682         if (tctx->print) {
683                 DWORD i;
684                 LPPRINTER_ENUM_VALUES v = (LPPRINTER_ENUM_VALUES)buffer;
685                 for (i=0; i < returned; i++) {
686                         print_printer_enum_values(&v[i]);
687                 }
688         }
689
690         if (returned_p) {
691                 *returned_p = returned;
692         }
693
694         if (buffer_p) {
695                 *buffer_p = buffer;
696         } else {
697                 free(buffer);
698         }
699
700         return TRUE;
701 }
702
703
704 /****************************************************************************
705 ****************************************************************************/
706
707 static BOOL test_OnePrinter(struct torture_context *tctx,
708                             LPSTR printername,
709                             LPSTR architecture,
710                             LPPRINTER_DEFAULTS defaults)
711 {
712         HANDLE handle;
713         BOOL ret = TRUE;
714
715         torture_comment(tctx, "Testing Printer %s", printername);
716
717         ret &= test_OpenPrinter(tctx, printername, defaults, &handle);
718         ret &= test_GetPrinter(tctx, printername, handle);
719         ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
720         ret &= test_EnumForms(tctx, printername, handle);
721         ret &= test_EnumJobs(tctx, printername, handle);
722         ret &= test_EnumPrinterKey(tctx, printername, handle, "");
723         ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
724         ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL);
725         ret &= test_ClosePrinter(tctx, handle);
726
727         return ret;
728 }
729
730 /****************************************************************************
731 ****************************************************************************/
732
733 static BOOL test_EachPrinter(struct torture_context *tctx,
734                              LPSTR servername,
735                              LPSTR architecture,
736                              LPPRINTER_DEFAULTS defaults)
737 {
738         DWORD needed = 0;
739         DWORD returned = 0;
740         DWORD err = 0;
741         char tmp[1024];
742         DWORD i;
743         DWORD flags = PRINTER_ENUM_NAME;
744         PPRINTER_INFO_1 buffer = NULL;
745         BOOL ret = TRUE;
746
747         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
748
749         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
750         err = GetLastError();
751         if (err == ERROR_INSUFFICIENT_BUFFER) {
752                 err = 0;
753                 buffer = (PPRINTER_INFO_1)malloc(needed);
754                 torture_assert(tctx, buffer, "malloc failed");
755                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
756                         err = GetLastError();
757                 }
758         }
759         if (err) {
760                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
761                         1, servername, needed, errstr(err));
762                 torture_fail(tctx, tmp);
763         }
764
765         for (i=0; i < returned; i++) {
766                 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
767         }
768
769         free(buffer);
770
771         return ret;
772 }
773
774 /****************************************************************************
775 ****************************************************************************/
776
777 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
778                                             LPSTR servername,
779                                             LPSTR architecture)
780 {
781         DWORD levels[]  = { 1 };
782         DWORD success[] = { 1 };
783         DWORD i;
784         LPBYTE buffer = NULL;
785
786         for (i=0; i < ARRAY_SIZE(levels); i++) {
787
788                 DWORD needed = 0;
789                 DWORD err = 0;
790                 char tmp[1024];
791
792                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
793
794                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
795                 err = GetLastError();
796                 if (err == ERROR_INSUFFICIENT_BUFFER) {
797                         err = 0;
798                         buffer = malloc(needed);
799                         torture_assert(tctx, buffer, "malloc failed");
800                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
801                                 err = GetLastError();
802                         }
803                 }
804                 if (err) {
805                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
806                                 levels[i], servername, needed, errstr(err));
807                         if (success[i]) {
808                                 torture_fail(tctx, tmp);
809                         } else {
810                                 torture_warning(tctx, tmp);
811                         }
812                 }
813
814                 free(buffer);
815                 buffer = NULL;
816         }
817
818         return TRUE;
819 }
820
821 /****************************************************************************
822 ****************************************************************************/
823
824 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
825                                            LPSTR servername,
826                                            LPSTR architecture)
827 {
828         DWORD levels[]  = { 1 };
829         DWORD success[] = { 1 };
830         DWORD i;
831         LPBYTE buffer = NULL;
832
833         for (i=0; i < ARRAY_SIZE(levels); i++) {
834
835                 DWORD needed = 0;
836                 DWORD err = 0;
837                 char tmp[1024];
838
839                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
840
841                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
842                 err = GetLastError();
843                 if (err == ERROR_INSUFFICIENT_BUFFER) {
844                         err = 0;
845                         buffer = malloc(needed);
846                         torture_assert(tctx, buffer, "malloc failed");
847                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
848                                 err = GetLastError();
849                         }
850                 }
851                 if (err) {
852                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
853                                 levels[i], servername, needed, errstr(err));
854                         if (success[i]) {
855                                 torture_fail(tctx, tmp);
856                         } else {
857                                 torture_warning(tctx, tmp);
858                         }
859                 }
860
861                 free(buffer);
862                 buffer = NULL;
863         }
864
865         return TRUE;
866 }
867
868 /****************************************************************************
869 ****************************************************************************/
870
871 static BOOL test_GetPrinterData(struct torture_context *tctx,
872                                 LPSTR servername,
873                                 LPSTR valuename,
874                                 HANDLE handle,
875                                 DWORD *type_p,
876                                 LPBYTE *buffer_p,
877                                 DWORD *size_p)
878 {
879         LPBYTE buffer = NULL;
880         DWORD needed = 0;
881         DWORD type;
882         DWORD err = 0;
883         char tmp[1024];
884
885         torture_comment(tctx, "Testing GetPrinterData(%s)", valuename);
886
887         err = GetPrinterData(handle, valuename, &type, NULL, 0, &needed);
888         if (err == ERROR_MORE_DATA) {
889                 buffer = (LPBYTE)malloc(needed);
890                 torture_assert(tctx, buffer, "malloc failed");
891                 err = GetPrinterData(handle, valuename, &type, buffer, needed, &needed);
892         }
893         if (err) {
894                 sprintf(tmp, "GetPrinterData(%s) failed on [%s] (buffer size = %d), error: %s\n",
895                         valuename, servername, needed, errstr(err));
896                 torture_fail(tctx, tmp);
897         }
898
899         if (tctx->print) {
900                 print_printer_data("PrinterDriverData", valuename, needed, buffer, type);
901         }
902
903         if (type_p) {
904                 *type_p = type;
905         }
906
907         if (size_p) {
908                 *size_p = needed;
909         }
910
911         if (buffer_p) {
912                 *buffer_p = buffer;
913         } else {
914                 free(buffer);
915         }
916
917         return TRUE;
918 }
919
920 /****************************************************************************
921 ****************************************************************************/
922
923 static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
924                                   LPSTR servername,
925                                   LPSTR keyname,
926                                   LPSTR valuename,
927                                   HANDLE handle,
928                                   DWORD *type_p,
929                                   LPBYTE *buffer_p,
930                                   DWORD *size_p)
931 {
932         LPBYTE buffer = NULL;
933         DWORD needed = 0;
934         DWORD type;
935         DWORD err = 0;
936         char tmp[1024];
937
938         torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)", keyname, valuename);
939
940         err = GetPrinterDataEx(handle, keyname, valuename, &type, NULL, 0, &needed);
941         if (err == ERROR_MORE_DATA) {
942                 buffer = (LPBYTE)malloc(needed);
943                 torture_assert(tctx, buffer, "malloc failed");
944                 err = GetPrinterDataEx(handle, keyname, valuename, &type, buffer, needed, &needed);
945         }
946         if (err) {
947                 sprintf(tmp, "GetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
948                         valuename, servername, needed, errstr(err));
949                 torture_fail(tctx, tmp);
950         }
951
952         if (tctx->print) {
953                 print_printer_data(keyname, valuename, needed, buffer, type);
954         }
955
956         if (type_p) {
957                 *type_p = type;
958         }
959
960         if (size_p) {
961                 *size_p = needed;
962         }
963
964         if (buffer_p) {
965                 *buffer_p = buffer;
966         } else {
967                 free(buffer);
968         }
969
970         return TRUE;
971 }
972
973 /****************************************************************************
974 ****************************************************************************/
975
976 static BOOL test_PrinterData(struct torture_context *tctx,
977                              LPSTR servername,
978                              HANDLE handle)
979 {
980         BOOL ret = TRUE;
981         DWORD i;
982         DWORD type, type_ex;
983         LPBYTE buffer, buffer_ex;
984         DWORD size, size_ex;
985         LPSTR valuenames[] = {
986                 SPLREG_DEFAULT_SPOOL_DIRECTORY,
987                 SPLREG_MAJOR_VERSION,
988                 SPLREG_MINOR_VERSION,
989                 SPLREG_DS_PRESENT,
990                 SPLREG_DNS_MACHINE_NAME,
991                 SPLREG_ARCHITECTURE,
992                 SPLREG_OS_VERSION
993         };
994
995         for (i=0; i < ARRAY_SIZE(valuenames); i++) {
996                 ret &= test_GetPrinterData(tctx, servername, valuenames[i], handle, &type, &buffer, &size);
997                 ret &= test_GetPrinterDataEx(tctx, servername, "random", valuenames[i], handle, &type_ex, &buffer_ex, &size_ex);
998                 torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
999                 torture_assert_int_equal(tctx, size, size_ex, "size mismatch");
1000                 torture_assert_mem_equal(tctx, buffer, buffer_ex, size, "buffer mismatch");
1001                 free(buffer);
1002                 free(buffer_ex);
1003         }
1004
1005         return ret;
1006 }
1007
1008 /****************************************************************************
1009 ****************************************************************************/
1010
1011 int main(int argc, char *argv[])
1012 {
1013         BOOL ret = FALSE;
1014         LPSTR servername;
1015         LPSTR architecture = "Windows NT x86";
1016         HANDLE server_handle;
1017         PRINTER_DEFAULTS defaults_admin, defaults_use;
1018         struct torture_context *tctx;
1019
1020         if (argc < 2) {
1021                 fprintf(stderr, "usage: %s <servername> [print]\n", argv[0]);
1022                 exit(-1);
1023         }
1024
1025         tctx = malloc(sizeof(struct torture_context));
1026         if (!tctx) {
1027                 fprintf(stderr, "out of memory\n");
1028                 exit(-1);
1029         }
1030         memset(tctx, '\0', sizeof(*tctx));
1031
1032         servername = argv[1];
1033
1034         if (argc >= 3) {
1035                 if (strcmp(argv[2], "print") == 0) {
1036                         tctx->print = TRUE;
1037                 }
1038         }
1039
1040         defaults_admin.pDatatype = NULL;
1041         defaults_admin.pDevMode = NULL;
1042         defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
1043
1044         defaults_use.pDatatype = NULL;
1045         defaults_use.pDevMode = NULL;
1046         defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
1047
1048         ret &= test_EnumPrinters(tctx, servername);
1049         ret &= test_EnumDrivers(tctx, servername, architecture);
1050         ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
1051 /*      ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
1052         ret &= test_PrinterData(tctx, servername, server_handle);
1053         ret &= test_EnumForms(tctx, servername, server_handle);
1054         ret &= test_ClosePrinter(tctx, server_handle);
1055         ret &= test_EnumPorts(tctx, servername);
1056         ret &= test_EnumMonitors(tctx, servername);
1057         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
1058         ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
1059         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
1060         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
1061         ret &= test_EachPrinter(tctx, servername, architecture, NULL);
1062
1063         if (!ret) {
1064                 if (tctx->last_reason) {
1065                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
1066                 }
1067                 free(tctx);
1068                 return -1;
1069         }
1070
1071         printf("%s run successfully\n", argv[0]);
1072
1073         free(tctx);
1074         return 0;
1075 }