testprogs: pass down architecture in spoolss test.
[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                              HANDLE handle)
34 {
35         torture_comment(tctx, "Testing OpenPrinter(%s)", printername);
36
37         if (!OpenPrinter(printername, handle, NULL)) {
38                 char tmp[1024];
39                 sprintf(tmp, "failed to open printer %s, error was: 0x%08x\n",
40                         printername, GetLastError());
41                 torture_fail(tctx, tmp);
42         }
43
44         return TRUE;
45 }
46
47 /****************************************************************************
48 ****************************************************************************/
49
50 static BOOL test_ClosePrinter(struct torture_context *tctx,
51                               HANDLE handle)
52 {
53         torture_comment(tctx, "Testing ClosePrinter");
54
55         if (!ClosePrinter(handle)) {
56                 char tmp[1024];
57                 sprintf(tmp, "failed to close printer, error was: %s\n",
58                         errstr(GetLastError()));
59                 torture_fail(tctx, tmp);
60         }
61
62         return TRUE;
63 }
64
65
66 /****************************************************************************
67 ****************************************************************************/
68
69 static BOOL test_EnumPrinters(struct torture_context *tctx,
70                               LPSTR servername)
71 {
72         DWORD levels[]  = { 1, 2, 5 };
73         DWORD success[] = { 1, 1, 1 };
74         DWORD i;
75         DWORD flags = PRINTER_ENUM_NAME;
76         LPBYTE buffer = NULL;
77
78         for (i=0; i < ARRAY_SIZE(levels); i++) {
79
80                 DWORD needed = 0;
81                 DWORD returned = 0;
82                 DWORD err = 0;
83                 char tmp[1024];
84
85                 torture_comment(tctx, "Testing EnumPrinters level %d", levels[i]);
86
87                 EnumPrinters(flags, servername, levels[i], NULL, 0, &needed, &returned);
88                 err = GetLastError();
89                 if (err == ERROR_INSUFFICIENT_BUFFER) {
90                         err = 0;
91                         buffer = malloc(needed);
92                         torture_assert(tctx, buffer, "malloc failed");
93                         if (!EnumPrinters(flags, servername, levels[i], buffer, needed, &needed, &returned)) {
94                                 err = GetLastError();
95                         }
96                 }
97                 if (err) {
98                         sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
99                                 levels[i], servername, needed, errstr(err));
100                         if (success[i]) {
101                                 torture_fail(tctx, tmp);
102                         } else {
103                                 torture_warning(tctx, tmp);
104                         }
105                 }
106
107                 free(buffer);
108                 buffer = NULL;
109         }
110
111         return TRUE;
112 }
113
114 /****************************************************************************
115 ****************************************************************************/
116
117 static BOOL test_EnumDrivers(struct torture_context *tctx,
118                              LPSTR servername,
119                              LPSTR architecture)
120 {
121         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 8 };
122         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1 };
123         DWORD i;
124         LPBYTE buffer = NULL;
125
126         for (i=0; i < ARRAY_SIZE(levels); i++) {
127
128                 DWORD needed = 0;
129                 DWORD returned = 0;
130                 DWORD err = 0;
131                 char tmp[1024];
132
133                 torture_comment(tctx, "Testing EnumPrinterDrivers level %d", levels[i]);
134
135                 EnumPrinterDrivers(servername, architecture, levels[i], NULL, 0, &needed, &returned);
136                 err = GetLastError();
137                 if (err == ERROR_INSUFFICIENT_BUFFER) {
138                         err = 0;
139                         buffer = malloc(needed);
140                         torture_assert(tctx, buffer, "malloc failed");
141                         if (!EnumPrinterDrivers(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
142                                 err = GetLastError();
143                         }
144                 }
145                 if (err) {
146                         sprintf(tmp, "EnumPrinterDrivers failed level %d on [%s] (buffer size = %d), error: %s\n",
147                                 levels[i], servername, needed, errstr(err));
148                         if (success[i]) {
149                                 torture_fail(tctx, tmp);
150                         } else {
151                                 torture_warning(tctx, tmp);
152                         }
153                 }
154
155                 free(buffer);
156                 buffer = NULL;
157         }
158
159         return TRUE;
160 }
161
162 /****************************************************************************
163 ****************************************************************************/
164
165 static BOOL test_EnumForms(struct torture_context *tctx,
166                            LPSTR servername,
167                            HANDLE handle)
168 {
169         DWORD levels[]  = { 1, 2 };
170         DWORD success[] = { 1, 0 };
171         DWORD i;
172         LPBYTE buffer = NULL;
173
174         for (i=0; i < ARRAY_SIZE(levels); i++) {
175
176                 DWORD needed = 0;
177                 DWORD returned = 0;
178                 DWORD err = 0;
179                 char tmp[1024];
180
181                 torture_comment(tctx, "Testing EnumForms level %d", levels[i]);
182
183                 EnumForms(handle, levels[i], NULL, 0, &needed, &returned);
184                 err = GetLastError();
185                 if (err == ERROR_INSUFFICIENT_BUFFER) {
186                         err = 0;
187                         buffer = malloc(needed);
188                         torture_assert(tctx, buffer, "malloc failed");
189                         if (!EnumForms(handle, levels[i], buffer, needed, &needed, &returned)) {
190                                 err = GetLastError();
191                         }
192                 }
193                 if (err) {
194                         sprintf(tmp, "EnumForms failed level %d on [%s] (buffer size = %d), error: %s\n",
195                                 levels[i], servername, needed, errstr(err));
196                         if (success[i]) {
197                                 torture_fail(tctx, tmp);
198                         } else {
199                                 torture_warning(tctx, tmp);
200                         }
201                 }
202
203                 free(buffer);
204                 buffer = NULL;
205         }
206
207         return TRUE;
208 }
209
210 /****************************************************************************
211 ****************************************************************************/
212
213 static BOOL test_EnumPorts(struct torture_context *tctx,
214                            LPSTR servername)
215 {
216         DWORD levels[]  = { 1, 2 };
217         DWORD success[] = { 1, 1 };
218         DWORD i;
219         LPBYTE buffer = NULL;
220
221         for (i=0; i < ARRAY_SIZE(levels); i++) {
222
223                 DWORD needed = 0;
224                 DWORD returned = 0;
225                 DWORD err = 0;
226                 char tmp[1024];
227
228                 torture_comment(tctx, "Testing EnumPorts level %d", levels[i]);
229
230                 EnumPorts(servername, levels[i], NULL, 0, &needed, &returned);
231                 err = GetLastError();
232                 if (err == ERROR_INSUFFICIENT_BUFFER) {
233                         err = 0;
234                         buffer = malloc(needed);
235                         torture_assert(tctx, buffer, "malloc failed");
236                         if (!EnumPorts(servername, levels[i], buffer, needed, &needed, &returned)) {
237                                 err = GetLastError();
238                         }
239                 }
240                 if (err) {
241                         sprintf(tmp, "EnumPorts failed level %d on [%s] (buffer size = %d), error: %s\n",
242                                 levels[i], servername, needed, errstr(err));
243                         if (success[i]) {
244                                 torture_fail(tctx, tmp);
245                         } else {
246                                 torture_warning(tctx, tmp);
247                         }
248                 }
249
250                 free(buffer);
251                 buffer = NULL;
252         }
253
254         return TRUE;
255 }
256
257 /****************************************************************************
258 ****************************************************************************/
259
260 static BOOL test_EnumMonitors(struct torture_context *tctx,
261                               LPSTR servername)
262 {
263         DWORD levels[]  = { 1, 2 };
264         DWORD success[] = { 1, 1 };
265         DWORD i;
266         LPBYTE buffer = NULL;
267
268         for (i=0; i < ARRAY_SIZE(levels); i++) {
269
270                 DWORD needed = 0;
271                 DWORD returned = 0;
272                 DWORD err = 0;
273                 char tmp[1024];
274
275                 torture_comment(tctx, "Testing EnumMonitors level %d", levels[i]);
276
277                 EnumMonitors(servername, levels[i], NULL, 0, &needed, &returned);
278                 err = GetLastError();
279                 if (err == ERROR_INSUFFICIENT_BUFFER) {
280                         err = 0;
281                         buffer = malloc(needed);
282                         torture_assert(tctx, buffer, "malloc failed");
283                         if (!EnumMonitors(servername, levels[i], buffer, needed, &needed, &returned)) {
284                                 err = GetLastError();
285                         }
286                 }
287                 if (err) {
288                         sprintf(tmp, "EnumMonitors failed level %d on [%s] (buffer size = %d), error: %s\n",
289                                 levels[i], servername, needed, errstr(err));
290                         if (success[i]) {
291                                 torture_fail(tctx, tmp);
292                         } else {
293                                 torture_warning(tctx, tmp);
294                         }
295                 }
296
297                 free(buffer);
298                 buffer = NULL;
299         }
300
301         return TRUE;
302 }
303
304 /****************************************************************************
305 ****************************************************************************/
306
307 static BOOL test_EnumPrintProcessors(struct torture_context *tctx,
308                                      LPSTR servername,
309                                      LPSTR architecture)
310 {
311         DWORD levels[]  = { 1 };
312         DWORD success[] = { 1 };
313         DWORD i;
314         LPBYTE buffer = NULL;
315
316         for (i=0; i < ARRAY_SIZE(levels); i++) {
317
318                 DWORD needed = 0;
319                 DWORD returned = 0;
320                 DWORD err = 0;
321                 char tmp[1024];
322
323                 torture_comment(tctx, "Testing EnumPrintProcessors level %d", levels[i]);
324
325                 EnumPrintProcessors(servername, architecture, levels[i], NULL, 0, &needed, &returned);
326                 err = GetLastError();
327                 if (err == ERROR_INSUFFICIENT_BUFFER) {
328                         err = 0;
329                         buffer = malloc(needed);
330                         torture_assert(tctx, buffer, "malloc failed");
331                         if (!EnumPrintProcessors(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
332                                 err = GetLastError();
333                         }
334                 }
335                 if (err) {
336                         sprintf(tmp, "EnumPrintProcessors failed level %d on [%s] (buffer size = %d), error: %s\n",
337                                 levels[i], servername, needed, errstr(err));
338                         if (success[i]) {
339                                 torture_fail(tctx, tmp);
340                         } else {
341                                 torture_warning(tctx, tmp);
342                         }
343                 }
344
345                 free(buffer);
346                 buffer = NULL;
347         }
348
349         return TRUE;
350 }
351
352 /****************************************************************************
353 ****************************************************************************/
354
355 static BOOL test_EnumPrintProcessorDatatypes(struct torture_context *tctx,
356                                              LPSTR servername,
357                                              LPSTR architecture)
358 {
359         DWORD levels[]  = { 1 };
360         DWORD success[] = { 1 };
361         DWORD i;
362         LPBYTE buffer = NULL;
363
364         for (i=0; i < ARRAY_SIZE(levels); i++) {
365
366                 DWORD needed = 0;
367                 DWORD returned = 0;
368                 DWORD err = 0;
369                 char tmp[1024];
370
371                 torture_comment(tctx, "Testing EnumPrintProcessorDatatypes level %d", levels[i]);
372
373                 EnumPrintProcessorDatatypes(servername, architecture, levels[i], NULL, 0, &needed, &returned);
374                 err = GetLastError();
375                 if (err == ERROR_INSUFFICIENT_BUFFER) {
376                         err = 0;
377                         buffer = malloc(needed);
378                         torture_assert(tctx, buffer, "malloc failed");
379                         if (!EnumPrintProcessorDatatypes(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
380                                 err = GetLastError();
381                         }
382                 }
383                 if (err) {
384                         sprintf(tmp, "EnumPrintProcessorDatatypes failed level %d on [%s] (buffer size = %d), error: %s\n",
385                                 levels[i], servername, needed, errstr(err));
386                         if (success[i]) {
387                                 torture_fail(tctx, tmp);
388                         } else {
389                                 torture_warning(tctx, tmp);
390                         }
391                 }
392
393                 free(buffer);
394                 buffer = NULL;
395         }
396
397         return TRUE;
398 }
399
400 /****************************************************************************
401 ****************************************************************************/
402
403 static BOOL test_GetPrinter(struct torture_context *tctx,
404                             LPSTR printername,
405                             HANDLE handle)
406 {
407         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 7, 8 };
408         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
409         DWORD i;
410         LPBYTE buffer = NULL;
411
412         for (i=0; i < ARRAY_SIZE(levels); i++) {
413
414                 DWORD needed = 0;
415                 DWORD err = 0;
416                 char tmp[1024];
417
418                 torture_comment(tctx, "Testing GetPrinter level %d", levels[i]);
419
420                 GetPrinter(handle, levels[i], NULL, 0, &needed);
421                 err = GetLastError();
422                 if (err == ERROR_INSUFFICIENT_BUFFER) {
423                         err = 0;
424                         buffer = malloc(needed);
425                         torture_assert(tctx, buffer, "malloc failed");
426                         if (!GetPrinter(handle, levels[i], buffer, needed, &needed)) {
427                                 err = GetLastError();
428                         }
429                 }
430                 if (err) {
431                         sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
432                                 levels[i], printername, needed, errstr(err));
433                         if (success[i]) {
434                                 torture_fail(tctx, tmp);
435                         } else {
436                                 torture_warning(tctx, tmp);
437                         }
438                 }
439
440                 free(buffer);
441                 buffer = NULL;
442         }
443
444         return TRUE;
445 }
446
447 /****************************************************************************
448 ****************************************************************************/
449
450 static BOOL test_GetPrinterDriver(struct torture_context *tctx,
451                                   LPSTR printername,
452                                   LPSTR architecture,
453                                   HANDLE handle)
454 {
455         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 8, 101};
456         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
457         DWORD i;
458         LPBYTE buffer = NULL;
459
460         for (i=0; i < ARRAY_SIZE(levels); i++) {
461
462                 DWORD needed = 0;
463                 DWORD err = 0;
464                 char tmp[1024];
465
466                 torture_comment(tctx, "Testing GetPrinterDriver level %d", levels[i]);
467
468                 GetPrinterDriver(handle, architecture, levels[i], NULL, 0, &needed);
469                 err = GetLastError();
470                 if (err == ERROR_INSUFFICIENT_BUFFER) {
471                         err = 0;
472                         buffer = malloc(needed);
473                         torture_assert(tctx, buffer, "malloc failed");
474                         if (!GetPrinterDriver(handle, architecture, levels[i], buffer, needed, &needed)) {
475                                 err = GetLastError();
476                         }
477                 }
478                 if (err) {
479                         sprintf(tmp, "GetPrinterDriver failed level %d on [%s] (buffer size = %d), error: %s\n",
480                                 levels[i], printername, needed, errstr(err));
481                         if (success[i]) {
482                                 torture_fail(tctx, tmp);
483                         } else {
484                                 torture_warning(tctx, tmp);
485                         }
486                 }
487
488                 free(buffer);
489                 buffer = NULL;
490         }
491
492         return TRUE;
493 }
494
495
496 /****************************************************************************
497 ****************************************************************************/
498
499 static BOOL test_EnumJobs(struct torture_context *tctx,
500                           LPSTR printername,
501                           HANDLE handle)
502 {
503         DWORD levels[]  = { 1, 2, 3, 4 };
504         DWORD success[] = { 1, 1, 1, 1 };
505         DWORD i;
506         LPBYTE buffer = NULL;
507
508         for (i=0; i < ARRAY_SIZE(levels); i++) {
509
510                 DWORD needed = 0;
511                 DWORD returned = 0;
512                 DWORD err = 0;
513                 char tmp[1024];
514
515                 torture_comment(tctx, "Testing EnumJobs level %d", levels[i]);
516
517                 EnumJobs(handle, 0, 100, levels[i], NULL, 0, &needed, &returned);
518                 err = GetLastError();
519                 if (err == ERROR_INSUFFICIENT_BUFFER) {
520                         err = 0;
521                         buffer = malloc(needed);
522                         torture_assert(tctx, buffer, "malloc failed");
523                         if (!EnumJobs(handle, 0, 100, levels[i], buffer, needed, &needed, &returned)) {
524                                 err = GetLastError();
525                         }
526                 }
527                 if (err) {
528                         sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
529                                 levels[i], printername, needed, errstr(err));
530                         if (success[i]) {
531                                 torture_fail(tctx, tmp);
532                         } else {
533                                 torture_warning(tctx, tmp);
534                         }
535                 }
536
537                 free(buffer);
538                 buffer = NULL;
539         }
540
541         return TRUE;
542 }
543
544 /****************************************************************************
545 ****************************************************************************/
546
547 static BOOL test_OnePrinter(struct torture_context *tctx,
548                             LPSTR printername,
549                             LPSTR architecture)
550 {
551         HANDLE handle;
552         BOOL ret = TRUE;
553
554         torture_comment(tctx, "Testing Printer %s", printername);
555
556         ret &= test_OpenPrinter(tctx, printername, &handle);
557         ret &= test_GetPrinter(tctx, printername, handle);
558         ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
559         ret &= test_EnumForms(tctx, printername, handle);
560         ret &= test_EnumJobs(tctx, printername, handle);
561         ret &= test_ClosePrinter(tctx, handle);
562
563         return ret;
564 }
565
566 /****************************************************************************
567 ****************************************************************************/
568
569 static BOOL test_OneDriver(struct torture_context *tctx,
570                            LPSTR printername,
571                            LPSTR drivername)
572 {
573         return TRUE;
574 }
575
576 /****************************************************************************
577 ****************************************************************************/
578
579 static BOOL test_EachDriver(struct torture_context *tctx,
580                             LPSTR servername)
581 {
582         return TRUE;
583 }
584
585 /****************************************************************************
586 ****************************************************************************/
587
588 static BOOL test_EachPrinter(struct torture_context *tctx,
589                              LPSTR servername,
590                              LPSTR architecture)
591 {
592         DWORD needed = 0;
593         DWORD returned = 0;
594         DWORD err = 0;
595         char tmp[1024];
596         DWORD i;
597         DWORD flags = PRINTER_ENUM_NAME;
598         PPRINTER_INFO_1 buffer = NULL;
599
600         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
601
602         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
603         err = GetLastError();
604         if (err == ERROR_INSUFFICIENT_BUFFER) {
605                 err = 0;
606                 buffer = (PPRINTER_INFO_1)malloc(needed);
607                 torture_assert(tctx, buffer, "malloc failed");
608                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
609                         err = GetLastError();
610                 }
611         }
612         if (err) {
613                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
614                         1, servername, needed, errstr(err));
615                 torture_fail(tctx, tmp);
616         }
617
618         for (i=0; i < returned; i++) {
619                 torture_assert(tctx, test_OnePrinter(tctx, buffer[i].pName, architecture),
620                         "failed to test one printer");
621         }
622
623         free(buffer);
624
625         return TRUE;
626 }
627
628 /****************************************************************************
629 ****************************************************************************/
630
631 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
632                                             LPSTR servername,
633                                             LPSTR architecture)
634 {
635         DWORD levels[]  = { 1 };
636         DWORD success[] = { 1 };
637         DWORD i;
638         LPBYTE buffer = NULL;
639
640         for (i=0; i < ARRAY_SIZE(levels); i++) {
641
642                 DWORD needed = 0;
643                 DWORD err = 0;
644                 char tmp[1024];
645
646                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
647
648                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
649                 err = GetLastError();
650                 if (err == ERROR_INSUFFICIENT_BUFFER) {
651                         err = 0;
652                         buffer = malloc(needed);
653                         torture_assert(tctx, buffer, "malloc failed");
654                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
655                                 err = GetLastError();
656                         }
657                 }
658                 if (err) {
659                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
660                                 levels[i], servername, needed, errstr(err));
661                         if (success[i]) {
662                                 torture_fail(tctx, tmp);
663                         } else {
664                                 torture_warning(tctx, tmp);
665                         }
666                 }
667
668                 free(buffer);
669                 buffer = NULL;
670         }
671
672         return TRUE;
673 }
674
675 /****************************************************************************
676 ****************************************************************************/
677
678 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
679                                            LPSTR servername,
680                                            LPSTR architecture)
681 {
682         DWORD levels[]  = { 1 };
683         DWORD success[] = { 1 };
684         DWORD i;
685         LPBYTE buffer = NULL;
686
687         for (i=0; i < ARRAY_SIZE(levels); i++) {
688
689                 DWORD needed = 0;
690                 DWORD err = 0;
691                 char tmp[1024];
692
693                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
694
695                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
696                 err = GetLastError();
697                 if (err == ERROR_INSUFFICIENT_BUFFER) {
698                         err = 0;
699                         buffer = malloc(needed);
700                         torture_assert(tctx, buffer, "malloc failed");
701                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
702                                 err = GetLastError();
703                         }
704                 }
705                 if (err) {
706                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
707                                 levels[i], servername, needed, errstr(err));
708                         if (success[i]) {
709                                 torture_fail(tctx, tmp);
710                         } else {
711                                 torture_warning(tctx, tmp);
712                         }
713                 }
714
715                 free(buffer);
716                 buffer = NULL;
717         }
718
719         return TRUE;
720 }
721
722
723 /****************************************************************************
724 ****************************************************************************/
725
726 int main(int argc, char *argv[])
727 {
728         BOOL ret = FALSE;
729         LPSTR servername;
730         LPSTR architecture = "Windows NT x86";
731         HANDLE handle;
732         struct torture_context *tctx;
733
734         if (argc < 2) {
735                 fprintf(stderr, "usage: %s <servername> [print]\n", argv[0]);
736                 exit(-1);
737         }
738
739         tctx = malloc(sizeof(struct torture_context));
740         if (!tctx) {
741                 fprintf(stderr, "out of memory\n");
742                 exit(-1);
743         }
744         memset(tctx, '\0', sizeof(*tctx));
745
746         servername = argv[1];
747
748         if (argc >= 3) {
749                 if (strcmp(argv[2], "print") == 0) {
750                         tctx->print = TRUE;
751                 }
752         }
753
754         ret &= test_EnumPrinters(tctx, servername);
755         ret &= test_EnumDrivers(tctx, servername, architecture);
756         ret &= test_OpenPrinter(tctx, servername, &handle);
757         ret &= test_EnumForms(tctx, servername, handle);
758         ret &= test_ClosePrinter(tctx, handle);
759         ret &= test_EnumPorts(tctx, servername);
760         ret &= test_EnumMonitors(tctx, servername);
761         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
762         ret &= test_EnumPrintProcessorDatatypes(tctx, servername, architecture);
763         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
764         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
765         ret &= test_EachPrinter(tctx, servername, architecture);
766         ret &= test_EachDriver(tctx, servername);
767
768         if (!ret) {
769                 if (tctx->last_reason) {
770                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
771                 }
772                 free(tctx);
773                 return -1;
774         }
775
776         printf("%s run successfully\n", argv[0]);
777
778         free(tctx);
779         return 0;
780 }