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