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