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