2d3c5588ad5dab1c1bf9de0966c42ec300d5f2da
[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 static BOOL test_devicemode_equal(struct torture_context *tctx,
737                                   const DEVMODE *d1,
738                                   const DEVMODE *d2)
739 {
740         if (d1 == d2) {
741                 return TRUE;
742         }
743
744         if (!d1 || !d2) {
745                 torture_comment(tctx, "%s\n", __location__);
746                 return FALSE;
747         }
748
749         torture_assert_str_equal(tctx, (const char *)d1->dmDeviceName, (const char *)d2->dmDeviceName, "dmDeviceName mismatch");
750         torture_assert_int_equal(tctx, d1->dmSpecVersion, d2->dmSpecVersion, "dmSpecVersion mismatch");
751         torture_assert_int_equal(tctx, d1->dmDriverVersion, d2->dmDriverVersion, "dmDriverVersion mismatch");
752         torture_assert_int_equal(tctx, d1->dmSize, d2->dmSize, "size mismatch");
753         torture_assert_int_equal(tctx, d1->dmDriverExtra, d2->dmDriverExtra, "dmDriverExtra mismatch");
754         torture_assert_int_equal(tctx, d1->dmFields, d2->dmFields, "dmFields mismatch");
755
756         torture_assert_int_equal(tctx, d1->dmOrientation, d2->dmOrientation, "dmOrientation mismatch");
757         torture_assert_int_equal(tctx, d1->dmPaperSize, d2->dmPaperSize, "dmPaperSize mismatch");
758         torture_assert_int_equal(tctx, d1->dmPaperLength, d2->dmPaperLength, "dmPaperLength mismatch");
759         torture_assert_int_equal(tctx, d1->dmPaperWidth, d2->dmPaperWidth, "dmPaperWidth mismatch");
760         torture_assert_int_equal(tctx, d1->dmScale, d2->dmScale, "dmScale mismatch");
761         torture_assert_int_equal(tctx, d1->dmCopies, d2->dmCopies, "dmCopies mismatch");
762         torture_assert_int_equal(tctx, d1->dmDefaultSource, d2->dmDefaultSource, "dmDefaultSource mismatch");
763         torture_assert_int_equal(tctx, d1->dmPrintQuality, d2->dmPrintQuality, "dmPrintQuality mismatch");
764
765         torture_assert_int_equal(tctx, d1->dmColor, d2->dmColor, "dmColor mismatch");
766         torture_assert_int_equal(tctx, d1->dmDuplex, d2->dmDuplex, "dmDuplex mismatch");
767         torture_assert_int_equal(tctx, d1->dmYResolution, d2->dmYResolution, "dmYResolution mismatch");
768         torture_assert_int_equal(tctx, d1->dmTTOption, d2->dmTTOption, "dmTTOption mismatch");
769         torture_assert_int_equal(tctx, d1->dmCollate, d2->dmCollate, "dmCollate mismatch");
770         torture_assert_str_equal(tctx, (const char *)d1->dmFormName, (const char *)d2->dmFormName, "dmFormName mismatch");
771         torture_assert_int_equal(tctx, d1->dmLogPixels, d2->dmLogPixels, "dmLogPixels mismatch");
772         torture_assert_int_equal(tctx, d1->dmBitsPerPel, d2->dmBitsPerPel, "dmBitsPerPel mismatch");
773         torture_assert_int_equal(tctx, d1->dmPelsWidth, d2->dmPelsWidth, "dmPelsWidth mismatch");
774         torture_assert_int_equal(tctx, d1->dmPelsHeight, d2->dmPelsHeight, "dmPelsHeight mismatch");
775
776         torture_assert_int_equal(tctx, d1->dmDisplayFlags, d2->dmDisplayFlags, "dmDisplayFlags mismatch");
777         /* or dmNup ? */
778         torture_assert_int_equal(tctx, d1->dmDisplayFrequency, d2->dmDisplayFrequency, "dmDisplayFrequency mismatch");
779
780         torture_assert_int_equal(tctx, d1->dmICMMethod, d2->dmICMMethod, "dmICMMethod mismatch");
781         torture_assert_int_equal(tctx, d1->dmICMIntent, d2->dmICMIntent, "dmICMIntent mismatch");
782         torture_assert_int_equal(tctx, d1->dmMediaType, d2->dmMediaType, "dmMediaType mismatch");
783         torture_assert_int_equal(tctx, d1->dmDitherType, d2->dmDitherType, "dmDitherType mismatch");
784         torture_assert_int_equal(tctx, d1->dmReserved1, d2->dmReserved1, "dmReserved1 mismatch");
785         torture_assert_int_equal(tctx, d1->dmReserved2, d2->dmReserved2, "reserved2 mismatch");
786
787         torture_assert_int_equal(tctx, d1->dmPanningWidth, d2->dmPanningWidth, "dmPanningWidth mismatch");
788         torture_assert_int_equal(tctx, d1->dmPanningHeight, d2->dmPanningHeight, "dmPanningHeight mismatch");
789
790         /* torture_assert_mem_equal(tctx, d1 + d1->dmSize, d2 + d2->dmSize, d1->dmDriverExtra, "private extra data mismatch"); */
791
792         return TRUE;
793 }
794
795 static BOOL test_DeviceModes(struct torture_context *tctx,
796                              LPSTR printername,
797                              HANDLE handle)
798 {
799         PPRINTER_INFO_2 info2 = NULL;
800         PPRINTER_INFO_8 info8 = NULL;
801         DWORD needed = 0;
802         DWORD err = 0;
803         char tmp[1024];
804
805         torture_comment(tctx, "Testing DeviceModes");
806
807         torture_comment(tctx, "Testing GetPrinter level %d", 2);
808
809         GetPrinter(handle, 2, NULL, 0, &needed);
810         err = GetLastError();
811         if (err == ERROR_INSUFFICIENT_BUFFER) {
812                 err = 0;
813                 info2 = (PPRINTER_INFO_2)malloc(needed);
814                 torture_assert(tctx, (LPBYTE)info2, "malloc failed");
815                 if (!GetPrinter(handle, 2, (LPBYTE)info2, needed, &needed)) {
816                         err = GetLastError();
817                 }
818         }
819         if (err) {
820                 sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
821                         2, printername, needed, errstr(err));
822                 torture_fail(tctx, tmp);
823         }
824
825         if (tctx->print) {
826                 print_printer_info_2(info2);
827         }
828
829         torture_comment(tctx, "Testing GetPrinter level %d", 8);
830
831         GetPrinter(handle, 8, NULL, 0, &needed);
832         err = GetLastError();
833         if (err == ERROR_INSUFFICIENT_BUFFER) {
834                 err = 0;
835                 info8 = (PPRINTER_INFO_8)malloc(needed);
836                 torture_assert(tctx, (LPBYTE)info8, "malloc failed");
837                 if (!GetPrinter(handle, 8, (LPBYTE)info8, needed, &needed)) {
838                         err = GetLastError();
839                 }
840         }
841         if (err) {
842                 sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
843                         8, printername, needed, errstr(err));
844                 torture_fail(tctx, tmp);
845         }
846
847         if (tctx->print) {
848                 print_printer_info_8(info8);
849         }
850
851         torture_assert(tctx, test_devicemode_equal(tctx, info2->pDevMode, info8->pDevMode), "");
852
853         free(info2);
854         free(info8);
855
856         return TRUE;
857 }
858
859 /****************************************************************************
860 ****************************************************************************/
861
862 static BOOL test_GetJob(struct torture_context *tctx,
863                         LPSTR printername,
864                         HANDLE handle,
865                         DWORD job_id)
866 {
867         DWORD levels[]  = { 1, 2, 3, 4 };
868         DWORD success[] = { 1, 1, 1, 1 };
869         DWORD i;
870         LPBYTE buffer = NULL;
871
872         for (i=0; i < ARRAY_SIZE(levels); i++) {
873
874                 DWORD needed = 0;
875                 DWORD err = 0;
876                 char tmp[1024];
877
878                 torture_comment(tctx, "Testing GetJob(%d) level %d", job_id, levels[i]);
879
880                 if (tctx->samba3 && (levels[i] == 4) || (levels[i] == 3)) {
881                         torture_comment(tctx, "skipping level %d getjob against samba\n", levels[i]);
882                         continue;
883                 }
884
885                 GetJob(handle, job_id, levels[i], NULL, 0, &needed);
886                 err = GetLastError();
887                 if (err == ERROR_INSUFFICIENT_BUFFER) {
888                         err = 0;
889                         buffer = malloc(needed);
890                         torture_assert(tctx, buffer, "malloc failed");
891                         if (!GetJob(handle, job_id, levels[i], buffer, needed, &needed)) {
892                                 err = GetLastError();
893                         }
894                 }
895                 if (err) {
896                         sprintf(tmp, "GetJob failed level %d on [%s] (buffer size = %d), error: %s\n",
897                                 levels[i], printername, needed, errstr(err));
898                         if (success[i]) {
899                                 torture_fail(tctx, tmp);
900                         } else {
901                                 torture_warning(tctx, tmp);
902                         }
903                 }
904
905                 if (tctx->print) {
906                         print_job_info_bylevel(levels[i], buffer, 1);
907                 }
908
909                 free(buffer);
910                 buffer = NULL;
911         }
912
913         return TRUE;
914 }
915
916 /****************************************************************************
917 ****************************************************************************/
918
919 static BOOL test_EachJob(struct torture_context *tctx,
920                          LPSTR printername,
921                          HANDLE handle)
922 {
923         DWORD i;
924         PJOB_INFO_1 buffer = NULL;
925         DWORD needed = 0;
926         DWORD returned = 0;
927         DWORD err = 0;
928         DWORD level = 1;
929         char tmp[1024];
930         BOOL ret = TRUE;
931
932         torture_comment(tctx, "Testing Each PrintJob %d");
933
934         EnumJobs(handle, 0, 100, level, NULL, 0, &needed, &returned);
935         err = GetLastError();
936         if (err == ERROR_INSUFFICIENT_BUFFER) {
937                 err = 0;
938                 buffer = (PJOB_INFO_1)malloc(needed);
939                 torture_assert(tctx, buffer, "malloc failed");
940                 if (!EnumJobs(handle, 0, 100, level, (LPBYTE)buffer, needed, &needed, &returned)) {
941                         err = GetLastError();
942                 }
943         }
944         if (err) {
945                 sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
946                         level, printername, needed, errstr(err));
947                 torture_fail(tctx, tmp);
948         }
949
950         if (tctx->print) {
951                 print_job_info_bylevel(level, (LPBYTE)buffer, returned);
952         }
953
954         for (i=0; i < returned; i++) {
955                 ret = test_GetJob(tctx, printername, handle, buffer[i].JobId);
956         }
957
958         free(buffer);
959
960         return ret;
961
962 }
963
964 /****************************************************************************
965 ****************************************************************************/
966
967 static BOOL test_OnePrinter(struct torture_context *tctx,
968                             LPSTR printername,
969                             LPSTR architecture,
970                             LPPRINTER_DEFAULTS defaults)
971 {
972         HANDLE handle;
973         BOOL ret = TRUE;
974
975         torture_comment(tctx, "Testing Printer %s", printername);
976
977         ret &= test_OpenPrinter(tctx, printername, defaults, &handle);
978         ret &= test_GetPrinter(tctx, printername, handle);
979         ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
980         ret &= test_EnumForms(tctx, printername, handle);
981         ret &= test_EnumJobs(tctx, printername, handle);
982         ret &= test_EachJob(tctx, printername, handle);
983         ret &= test_EnumPrinterKey(tctx, printername, handle, "");
984         ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
985         ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL);
986         ret &= test_DeviceModes(tctx, printername, handle);
987         ret &= test_ClosePrinter(tctx, handle);
988
989         return ret;
990 }
991
992 /****************************************************************************
993 ****************************************************************************/
994
995 static BOOL test_EachPrinter(struct torture_context *tctx,
996                              LPSTR servername,
997                              LPSTR architecture,
998                              LPPRINTER_DEFAULTS defaults)
999 {
1000         DWORD needed = 0;
1001         DWORD returned = 0;
1002         DWORD err = 0;
1003         char tmp[1024];
1004         DWORD i;
1005         DWORD flags = PRINTER_ENUM_NAME;
1006         PPRINTER_INFO_1 buffer = NULL;
1007         BOOL ret = TRUE;
1008
1009         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
1010
1011         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
1012         err = GetLastError();
1013         if (err == ERROR_INSUFFICIENT_BUFFER) {
1014                 err = 0;
1015                 buffer = (PPRINTER_INFO_1)malloc(needed);
1016                 torture_assert(tctx, buffer, "malloc failed");
1017                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
1018                         err = GetLastError();
1019                 }
1020         }
1021         if (err) {
1022                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
1023                         1, servername, needed, errstr(err));
1024                 torture_fail(tctx, tmp);
1025         }
1026
1027         for (i=0; i < returned; i++) {
1028                 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
1029         }
1030
1031         free(buffer);
1032
1033         return ret;
1034 }
1035
1036 /****************************************************************************
1037 ****************************************************************************/
1038
1039 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
1040                                             LPSTR servername,
1041                                             LPSTR architecture)
1042 {
1043         DWORD levels[]  = { 1 };
1044         DWORD success[] = { 1 };
1045         DWORD i;
1046         LPBYTE buffer = NULL;
1047
1048         for (i=0; i < ARRAY_SIZE(levels); i++) {
1049
1050                 DWORD needed = 0;
1051                 DWORD err = 0;
1052                 char tmp[1024];
1053
1054                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
1055
1056                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
1057                 err = GetLastError();
1058                 if (err == ERROR_INSUFFICIENT_BUFFER) {
1059                         err = 0;
1060                         buffer = malloc(needed);
1061                         torture_assert(tctx, buffer, "malloc failed");
1062                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
1063                                 err = GetLastError();
1064                         }
1065                 }
1066                 if (err) {
1067                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
1068                                 levels[i], servername, needed, errstr(err));
1069                         if (success[i]) {
1070                                 torture_fail(tctx, tmp);
1071                         } else {
1072                                 torture_warning(tctx, tmp);
1073                         }
1074                 }
1075
1076                 if (tctx->print) {
1077                         printf("\tPrint Processor Directory\t= %s\n\n", (LPSTR)buffer);
1078                 }
1079
1080                 free(buffer);
1081                 buffer = NULL;
1082         }
1083
1084         return TRUE;
1085 }
1086
1087 /****************************************************************************
1088 ****************************************************************************/
1089
1090 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
1091                                            LPSTR servername,
1092                                            LPSTR architecture)
1093 {
1094         DWORD levels[]  = { 1 };
1095         DWORD success[] = { 1 };
1096         DWORD i;
1097         LPBYTE buffer = NULL;
1098
1099         for (i=0; i < ARRAY_SIZE(levels); i++) {
1100
1101                 DWORD needed = 0;
1102                 DWORD err = 0;
1103                 char tmp[1024];
1104
1105                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
1106
1107                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
1108                 err = GetLastError();
1109                 if (err == ERROR_INSUFFICIENT_BUFFER) {
1110                         err = 0;
1111                         buffer = malloc(needed);
1112                         torture_assert(tctx, buffer, "malloc failed");
1113                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
1114                                 err = GetLastError();
1115                         }
1116                 }
1117                 if (err) {
1118                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
1119                                 levels[i], servername, needed, errstr(err));
1120                         if (success[i]) {
1121                                 torture_fail(tctx, tmp);
1122                         } else {
1123                                 torture_warning(tctx, tmp);
1124                         }
1125                 }
1126
1127                 if (tctx->print) {
1128                         printf("\tPrinter Driver Directory\t= %s\n\n", (LPSTR)buffer);
1129                 }
1130
1131                 free(buffer);
1132                 buffer = NULL;
1133         }
1134
1135         return TRUE;
1136 }
1137
1138 /****************************************************************************
1139 ****************************************************************************/
1140
1141 static BOOL test_GetPrinterData(struct torture_context *tctx,
1142                                 LPSTR servername,
1143                                 LPSTR valuename,
1144                                 HANDLE handle,
1145                                 DWORD *type_p,
1146                                 LPBYTE *buffer_p,
1147                                 DWORD *size_p)
1148 {
1149         LPBYTE buffer = NULL;
1150         DWORD needed = 0;
1151         DWORD type;
1152         DWORD err = 0;
1153         char tmp[1024];
1154
1155         torture_comment(tctx, "Testing GetPrinterData(%s)", valuename);
1156
1157         err = GetPrinterData(handle, valuename, &type, NULL, 0, &needed);
1158         if (err == ERROR_MORE_DATA) {
1159                 buffer = (LPBYTE)malloc(needed);
1160                 torture_assert(tctx, buffer, "malloc failed");
1161                 err = GetPrinterData(handle, valuename, &type, buffer, needed, &needed);
1162         }
1163         if (err) {
1164                 sprintf(tmp, "GetPrinterData(%s) failed on [%s] (buffer size = %d), error: %s\n",
1165                         valuename, servername, needed, errstr(err));
1166                 torture_fail(tctx, tmp);
1167         }
1168
1169         if (tctx->print) {
1170                 print_printer_data("PrinterDriverData", valuename, needed, buffer, type);
1171         }
1172
1173         if (type_p) {
1174                 *type_p = type;
1175         }
1176
1177         if (size_p) {
1178                 *size_p = needed;
1179         }
1180
1181         if (buffer_p) {
1182                 *buffer_p = buffer;
1183         } else {
1184                 free(buffer);
1185         }
1186
1187         return TRUE;
1188 }
1189
1190 /****************************************************************************
1191 ****************************************************************************/
1192
1193 static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
1194                                   LPSTR servername,
1195                                   LPSTR keyname,
1196                                   LPSTR valuename,
1197                                   HANDLE handle,
1198                                   DWORD *type_p,
1199                                   LPBYTE *buffer_p,
1200                                   DWORD *size_p)
1201 {
1202         LPBYTE buffer = NULL;
1203         DWORD needed = 0;
1204         DWORD type;
1205         DWORD err = 0;
1206         char tmp[1024];
1207
1208         torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)", keyname, valuename);
1209
1210         err = GetPrinterDataEx(handle, keyname, valuename, &type, NULL, 0, &needed);
1211         if (err == ERROR_MORE_DATA) {
1212                 buffer = (LPBYTE)malloc(needed);
1213                 torture_assert(tctx, buffer, "malloc failed");
1214                 err = GetPrinterDataEx(handle, keyname, valuename, &type, buffer, needed, &needed);
1215         }
1216         if (err) {
1217                 sprintf(tmp, "GetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
1218                         valuename, servername, needed, errstr(err));
1219                 torture_fail(tctx, tmp);
1220         }
1221
1222         if (tctx->print) {
1223                 print_printer_data(keyname, valuename, needed, buffer, type);
1224         }
1225
1226         if (type_p) {
1227                 *type_p = type;
1228         }
1229
1230         if (size_p) {
1231                 *size_p = needed;
1232         }
1233
1234         if (buffer_p) {
1235                 *buffer_p = buffer;
1236         } else {
1237                 free(buffer);
1238         }
1239
1240         return TRUE;
1241 }
1242
1243 /****************************************************************************
1244 ****************************************************************************/
1245
1246 static BOOL test_PrinterData(struct torture_context *tctx,
1247                              LPSTR servername,
1248                              HANDLE handle)
1249 {
1250         BOOL ret = TRUE;
1251         DWORD i;
1252         DWORD type, type_ex;
1253         LPBYTE buffer, buffer_ex;
1254         DWORD size, size_ex;
1255         LPSTR valuenames[] = {
1256                 SPLREG_DEFAULT_SPOOL_DIRECTORY,
1257                 SPLREG_MAJOR_VERSION,
1258                 SPLREG_MINOR_VERSION,
1259                 SPLREG_DS_PRESENT,
1260                 SPLREG_DNS_MACHINE_NAME,
1261                 SPLREG_ARCHITECTURE,
1262                 SPLREG_OS_VERSION
1263         };
1264
1265         for (i=0; i < ARRAY_SIZE(valuenames); i++) {
1266                 ret &= test_GetPrinterData(tctx, servername, valuenames[i], handle, &type, &buffer, &size);
1267                 ret &= test_GetPrinterDataEx(tctx, servername, "random", valuenames[i], handle, &type_ex, &buffer_ex, &size_ex);
1268                 torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
1269                 torture_assert_int_equal(tctx, size, size_ex, "size mismatch");
1270                 torture_assert_mem_equal(tctx, buffer, buffer_ex, size, "buffer mismatch");
1271                 free(buffer);
1272                 free(buffer_ex);
1273         }
1274
1275         return ret;
1276 }
1277
1278 /****************************************************************************
1279 ****************************************************************************/
1280
1281 const char *get_string_param(const char *str)
1282 {
1283         const char *p;
1284
1285         p = strchr(str, '=');
1286         if (!p) {
1287                 return NULL;
1288         }
1289
1290         return (p+1);
1291 }
1292
1293 /****************************************************************************
1294 ****************************************************************************/
1295
1296 int main(int argc, char *argv[])
1297 {
1298         BOOL ret = FALSE;
1299         LPSTR servername;
1300         LPSTR architecture = "Windows NT x86";
1301         HANDLE server_handle;
1302         PRINTER_DEFAULTS defaults_admin, defaults_use;
1303         struct torture_context *tctx;
1304         int i;
1305
1306         if (argc < 2) {
1307                 fprintf(stderr, "usage: %s <servername> [print] [samba3] [architecture=ARCHITECTURE]\n", argv[0]);
1308                 exit(-1);
1309         }
1310
1311         tctx = malloc(sizeof(struct torture_context));
1312         if (!tctx) {
1313                 fprintf(stderr, "out of memory\n");
1314                 exit(-1);
1315         }
1316         memset(tctx, '\0', sizeof(*tctx));
1317
1318         servername = argv[1];
1319
1320         for (i=1; i < argc; i++) {
1321                 if (strcmp(argv[i], "print") == 0) {
1322                         tctx->print = TRUE;
1323                 }
1324                 if (strcmp(argv[i], "samba3") == 0) {
1325                         tctx->samba3 = TRUE;
1326                 }
1327                 if (strncmp(argv[i], "architecture", strlen("architecture")) == 0) {
1328                         architecture = get_string_param(argv[i]);
1329                 }
1330         }
1331
1332         printf("Running testsuite with architecture: %s\n", architecture);
1333
1334         defaults_admin.pDatatype = NULL;
1335         defaults_admin.pDevMode = NULL;
1336         defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
1337
1338         defaults_use.pDatatype = NULL;
1339         defaults_use.pDevMode = NULL;
1340         defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
1341
1342         if ((servername[0] == '\\') && (servername[1] == '\\')) {
1343                 LPSTR p = servername+2;
1344                 LPSTR p2;
1345                 if ((p2 = strchr(p, '\\')) != NULL) {
1346                         ret = test_OnePrinter(tctx, servername, architecture, NULL);
1347                         goto done;
1348                 }
1349         }
1350
1351         ret &= test_EnumPrinters(tctx, servername);
1352         ret &= test_EnumDrivers(tctx, servername, architecture);
1353         ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
1354 /*      ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
1355         ret &= test_PrinterData(tctx, servername, server_handle);
1356         ret &= test_EnumForms(tctx, servername, server_handle);
1357         ret &= test_ClosePrinter(tctx, server_handle);
1358         ret &= test_EnumPorts(tctx, servername);
1359         ret &= test_EnumMonitors(tctx, servername);
1360         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
1361         ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
1362         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
1363         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
1364         ret &= test_EachPrinter(tctx, servername, architecture, NULL);
1365
1366  done:
1367         if (!ret) {
1368                 if (tctx->last_reason) {
1369                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
1370                 }
1371                 free(tctx);
1372                 return -1;
1373         }
1374
1375         printf("%s run successfully\n", argv[0]);
1376
1377         free(tctx);
1378         return 0;
1379 }