testprogs: add tests for GetForm.
[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                 free(buffer);
161                 buffer = NULL;
162         }
163
164         return TRUE;
165 }
166
167 /****************************************************************************
168 ****************************************************************************/
169
170 static BOOL test_GetForm(struct torture_context *tctx,
171                          LPSTR servername,
172                          HANDLE handle,
173                          LPSTR formname)
174 {
175         DWORD levels[]  = { 1, 2 };
176         DWORD success[] = { 1, 0 };
177         DWORD i;
178         LPBYTE buffer = NULL;
179
180         for (i=0; i < ARRAY_SIZE(levels); i++) {
181
182                 DWORD needed = 0;
183                 DWORD err = 0;
184                 char tmp[1024];
185
186                 torture_comment(tctx, "Testing GetForm(%s) level %d", formname, levels[i]);
187
188                 GetForm(handle, formname, levels[i], NULL, 0, &needed);
189                 err = GetLastError();
190                 if (err == ERROR_INSUFFICIENT_BUFFER) {
191                         err = 0;
192                         buffer = malloc(needed);
193                         torture_assert(tctx, buffer, "malloc failed");
194                         if (!GetForm(handle, formname, levels[i], buffer, needed, &needed)) {
195                                 err = GetLastError();
196                         }
197                 }
198                 if (err) {
199                         sprintf(tmp, "GetForm failed level %d on [%s] (buffer size = %d), error: %s\n",
200                                 levels[i], servername, needed, errstr(err));
201                         if (success[i]) {
202                                 torture_fail(tctx, tmp);
203                         } else {
204                                 torture_warning(tctx, tmp);
205                         }
206                 }
207
208                 free(buffer);
209                 buffer = NULL;
210         }
211
212         return TRUE;
213 }
214
215 /****************************************************************************
216 ****************************************************************************/
217
218 static BOOL test_EnumForms(struct torture_context *tctx,
219                            LPSTR servername,
220                            HANDLE handle)
221 {
222         DWORD levels[]  = { 1, 2 };
223         DWORD success[] = { 1, 0 };
224         DWORD i;
225         LPBYTE buffer = NULL;
226
227         for (i=0; i < ARRAY_SIZE(levels); i++) {
228
229                 DWORD needed = 0;
230                 DWORD returned = 0;
231                 DWORD err = 0;
232                 char tmp[1024];
233
234                 torture_comment(tctx, "Testing EnumForms level %d", levels[i]);
235
236                 EnumForms(handle, levels[i], NULL, 0, &needed, &returned);
237                 err = GetLastError();
238                 if (err == ERROR_INSUFFICIENT_BUFFER) {
239                         err = 0;
240                         buffer = malloc(needed);
241                         torture_assert(tctx, buffer, "malloc failed");
242                         if (!EnumForms(handle, levels[i], buffer, needed, &needed, &returned)) {
243                                 err = GetLastError();
244                         }
245                 }
246                 if (err) {
247                         sprintf(tmp, "EnumForms failed level %d on [%s] (buffer size = %d), error: %s\n",
248                                 levels[i], servername, needed, errstr(err));
249                         if (success[i]) {
250                                 torture_fail(tctx, tmp);
251                         } else {
252                                 torture_warning(tctx, tmp);
253                         }
254                 }
255
256                 free(buffer);
257                 buffer = NULL;
258         }
259
260         return TRUE;
261 }
262
263 /****************************************************************************
264 ****************************************************************************/
265
266 static BOOL test_EnumPorts(struct torture_context *tctx,
267                            LPSTR servername)
268 {
269         DWORD levels[]  = { 1, 2 };
270         DWORD success[] = { 1, 1 };
271         DWORD i;
272         LPBYTE buffer = NULL;
273
274         for (i=0; i < ARRAY_SIZE(levels); i++) {
275
276                 DWORD needed = 0;
277                 DWORD returned = 0;
278                 DWORD err = 0;
279                 char tmp[1024];
280
281                 torture_comment(tctx, "Testing EnumPorts level %d", levels[i]);
282
283                 EnumPorts(servername, levels[i], NULL, 0, &needed, &returned);
284                 err = GetLastError();
285                 if (err == ERROR_INSUFFICIENT_BUFFER) {
286                         err = 0;
287                         buffer = malloc(needed);
288                         torture_assert(tctx, buffer, "malloc failed");
289                         if (!EnumPorts(servername, levels[i], buffer, needed, &needed, &returned)) {
290                                 err = GetLastError();
291                         }
292                 }
293                 if (err) {
294                         sprintf(tmp, "EnumPorts failed level %d on [%s] (buffer size = %d), error: %s\n",
295                                 levels[i], servername, needed, errstr(err));
296                         if (success[i]) {
297                                 torture_fail(tctx, tmp);
298                         } else {
299                                 torture_warning(tctx, tmp);
300                         }
301                 }
302
303                 free(buffer);
304                 buffer = NULL;
305         }
306
307         return TRUE;
308 }
309
310 /****************************************************************************
311 ****************************************************************************/
312
313 static BOOL test_EnumMonitors(struct torture_context *tctx,
314                               LPSTR servername)
315 {
316         DWORD levels[]  = { 1, 2 };
317         DWORD success[] = { 1, 1 };
318         DWORD i;
319         LPBYTE buffer = NULL;
320
321         for (i=0; i < ARRAY_SIZE(levels); i++) {
322
323                 DWORD needed = 0;
324                 DWORD returned = 0;
325                 DWORD err = 0;
326                 char tmp[1024];
327
328                 torture_comment(tctx, "Testing EnumMonitors level %d", levels[i]);
329
330                 EnumMonitors(servername, levels[i], NULL, 0, &needed, &returned);
331                 err = GetLastError();
332                 if (err == ERROR_INSUFFICIENT_BUFFER) {
333                         err = 0;
334                         buffer = malloc(needed);
335                         torture_assert(tctx, buffer, "malloc failed");
336                         if (!EnumMonitors(servername, levels[i], buffer, needed, &needed, &returned)) {
337                                 err = GetLastError();
338                         }
339                 }
340                 if (err) {
341                         sprintf(tmp, "EnumMonitors failed level %d on [%s] (buffer size = %d), error: %s\n",
342                                 levels[i], servername, needed, errstr(err));
343                         if (success[i]) {
344                                 torture_fail(tctx, tmp);
345                         } else {
346                                 torture_warning(tctx, tmp);
347                         }
348                 }
349
350                 free(buffer);
351                 buffer = NULL;
352         }
353
354         return TRUE;
355 }
356
357 /****************************************************************************
358 ****************************************************************************/
359
360 static BOOL test_EnumPrintProcessors(struct torture_context *tctx,
361                                      LPSTR servername,
362                                      LPSTR architecture)
363 {
364         DWORD levels[]  = { 1 };
365         DWORD success[] = { 1 };
366         DWORD i;
367         LPBYTE buffer = NULL;
368
369         for (i=0; i < ARRAY_SIZE(levels); i++) {
370
371                 DWORD needed = 0;
372                 DWORD returned = 0;
373                 DWORD err = 0;
374                 char tmp[1024];
375
376                 torture_comment(tctx, "Testing EnumPrintProcessors level %d", levels[i]);
377
378                 EnumPrintProcessors(servername, architecture, levels[i], NULL, 0, &needed, &returned);
379                 err = GetLastError();
380                 if (err == ERROR_INSUFFICIENT_BUFFER) {
381                         err = 0;
382                         buffer = malloc(needed);
383                         torture_assert(tctx, buffer, "malloc failed");
384                         if (!EnumPrintProcessors(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
385                                 err = GetLastError();
386                         }
387                 }
388                 if (err) {
389                         sprintf(tmp, "EnumPrintProcessors failed level %d on [%s] (buffer size = %d), error: %s\n",
390                                 levels[i], servername, needed, errstr(err));
391                         if (success[i]) {
392                                 torture_fail(tctx, tmp);
393                         } else {
394                                 torture_warning(tctx, tmp);
395                         }
396                 }
397
398                 free(buffer);
399                 buffer = NULL;
400         }
401
402         return TRUE;
403 }
404
405 /****************************************************************************
406 ****************************************************************************/
407
408 static BOOL test_EnumPrintProcessorDatatypes(struct torture_context *tctx,
409                                              LPSTR servername)
410 {
411         DWORD levels[]  = { 1 };
412         DWORD success[] = { 1 };
413         DWORD i;
414         LPBYTE buffer = NULL;
415
416         for (i=0; i < ARRAY_SIZE(levels); i++) {
417
418                 DWORD needed = 0;
419                 DWORD returned = 0;
420                 DWORD err = 0;
421                 char tmp[1024];
422
423                 torture_comment(tctx, "Testing EnumPrintProcessorDatatypes level %d", levels[i]);
424
425                 EnumPrintProcessorDatatypes(servername, "winprint", levels[i], NULL, 0, &needed, &returned);
426                 err = GetLastError();
427                 if (err == ERROR_INSUFFICIENT_BUFFER) {
428                         err = 0;
429                         buffer = malloc(needed);
430                         torture_assert(tctx, buffer, "malloc failed");
431                         if (!EnumPrintProcessorDatatypes(servername, "winprint", levels[i], buffer, needed, &needed, &returned)) {
432                                 err = GetLastError();
433                         }
434                 }
435                 if (err) {
436                         sprintf(tmp, "EnumPrintProcessorDatatypes failed level %d on [%s] (buffer size = %d), error: %s\n",
437                                 levels[i], servername, needed, errstr(err));
438                         if (success[i]) {
439                                 torture_fail(tctx, tmp);
440                         } else {
441                                 torture_warning(tctx, tmp);
442                         }
443                 }
444
445                 free(buffer);
446                 buffer = NULL;
447         }
448
449         return TRUE;
450 }
451
452 /****************************************************************************
453 ****************************************************************************/
454
455 static BOOL test_EnumPrinterKey(struct torture_context *tctx,
456                                 LPSTR servername,
457                                 HANDLE handle,
458                                 LPCSTR key)
459 {
460         LPSTR buffer = NULL;
461         DWORD needed = 0;
462         DWORD err = 0;
463         char tmp[1024];
464
465         torture_comment(tctx, "Testing EnumPrinterKey(%s)", key);
466
467         err = EnumPrinterKey(handle, key, NULL, 0, &needed);
468         if (err == ERROR_MORE_DATA) {
469                 buffer = (LPTSTR)malloc(needed);
470                 torture_assert(tctx, buffer, "malloc failed");
471                 err = EnumPrinterKey(handle, key, buffer, needed, &needed);
472         }
473         if (err) {
474                 sprintf(tmp, "EnumPrinterKey(%s) failed on [%s] (buffer size = %d), error: %s\n",
475                         key, servername, needed, errstr(err));
476                 torture_fail(tctx, tmp);
477         }
478
479         if (tctx->print) {
480                 print_printer_keys(buffer);
481         }
482
483         free(buffer);
484
485         return TRUE;
486 }
487
488 /****************************************************************************
489 ****************************************************************************/
490
491 static BOOL test_GetPrinter(struct torture_context *tctx,
492                             LPSTR printername,
493                             HANDLE handle)
494 {
495         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 7, 8 };
496         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
497         DWORD i;
498         LPBYTE buffer = NULL;
499
500         for (i=0; i < ARRAY_SIZE(levels); i++) {
501
502                 DWORD needed = 0;
503                 DWORD err = 0;
504                 char tmp[1024];
505
506                 torture_comment(tctx, "Testing GetPrinter level %d", levels[i]);
507
508                 GetPrinter(handle, levels[i], NULL, 0, &needed);
509                 err = GetLastError();
510                 if (err == ERROR_INSUFFICIENT_BUFFER) {
511                         err = 0;
512                         buffer = malloc(needed);
513                         torture_assert(tctx, buffer, "malloc failed");
514                         if (!GetPrinter(handle, levels[i], buffer, needed, &needed)) {
515                                 err = GetLastError();
516                         }
517                 }
518                 if (err) {
519                         sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
520                                 levels[i], printername, needed, errstr(err));
521                         if (success[i]) {
522                                 torture_fail(tctx, tmp);
523                         } else {
524                                 torture_warning(tctx, tmp);
525                         }
526                 }
527
528                 free(buffer);
529                 buffer = NULL;
530         }
531
532         return TRUE;
533 }
534
535 /****************************************************************************
536 ****************************************************************************/
537
538 static BOOL test_GetPrinterDriver(struct torture_context *tctx,
539                                   LPSTR printername,
540                                   LPSTR architecture,
541                                   HANDLE handle)
542 {
543         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 8 };
544         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1 };
545         DWORD i;
546         LPBYTE buffer = NULL;
547
548         for (i=0; i < ARRAY_SIZE(levels); i++) {
549
550                 DWORD needed = 0;
551                 DWORD err = 0;
552                 char tmp[1024];
553
554                 torture_comment(tctx, "Testing GetPrinterDriver level %d", levels[i]);
555
556                 GetPrinterDriver(handle, architecture, levels[i], NULL, 0, &needed);
557                 err = GetLastError();
558                 if (err == ERROR_INSUFFICIENT_BUFFER) {
559                         err = 0;
560                         buffer = malloc(needed);
561                         torture_assert(tctx, buffer, "malloc failed");
562                         if (!GetPrinterDriver(handle, architecture, levels[i], buffer, needed, &needed)) {
563                                 err = GetLastError();
564                         }
565                 }
566                 if (err) {
567                         sprintf(tmp, "GetPrinterDriver failed level %d on [%s] (buffer size = %d), error: %s\n",
568                                 levels[i], printername, needed, errstr(err));
569                         if (success[i]) {
570                                 torture_fail(tctx, tmp);
571                         } else {
572                                 torture_warning(tctx, tmp);
573                         }
574                 }
575
576                 free(buffer);
577                 buffer = NULL;
578         }
579
580         return TRUE;
581 }
582
583
584 /****************************************************************************
585 ****************************************************************************/
586
587 static BOOL test_EnumJobs(struct torture_context *tctx,
588                           LPSTR printername,
589                           HANDLE handle)
590 {
591         DWORD levels[]  = { 1, 2, 3, 4 };
592         DWORD success[] = { 1, 1, 1, 1 };
593         DWORD i;
594         LPBYTE buffer = NULL;
595
596         for (i=0; i < ARRAY_SIZE(levels); i++) {
597
598                 DWORD needed = 0;
599                 DWORD returned = 0;
600                 DWORD err = 0;
601                 char tmp[1024];
602
603                 torture_comment(tctx, "Testing EnumJobs level %d", levels[i]);
604
605                 EnumJobs(handle, 0, 100, levels[i], NULL, 0, &needed, &returned);
606                 err = GetLastError();
607                 if (err == ERROR_INSUFFICIENT_BUFFER) {
608                         err = 0;
609                         buffer = malloc(needed);
610                         torture_assert(tctx, buffer, "malloc failed");
611                         if (!EnumJobs(handle, 0, 100, levels[i], buffer, needed, &needed, &returned)) {
612                                 err = GetLastError();
613                         }
614                 }
615                 if (err) {
616                         sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
617                                 levels[i], printername, needed, errstr(err));
618                         if (success[i]) {
619                                 torture_fail(tctx, tmp);
620                         } else {
621                                 torture_warning(tctx, tmp);
622                         }
623                 }
624
625                 free(buffer);
626                 buffer = NULL;
627         }
628
629         return TRUE;
630 }
631
632 /****************************************************************************
633 ****************************************************************************/
634
635 static BOOL test_OnePrinter(struct torture_context *tctx,
636                             LPSTR printername,
637                             LPSTR architecture,
638                             LPPRINTER_DEFAULTS defaults)
639 {
640         HANDLE handle;
641         BOOL ret = TRUE;
642
643         torture_comment(tctx, "Testing Printer %s", printername);
644
645         ret &= test_OpenPrinter(tctx, printername, defaults, &handle);
646         ret &= test_GetPrinter(tctx, printername, handle);
647         ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
648         ret &= test_EnumForms(tctx, printername, handle);
649         ret &= test_EnumJobs(tctx, printername, handle);
650         ret &= test_EnumPrinterKey(tctx, printername, handle, "");
651         ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
652         ret &= test_ClosePrinter(tctx, handle);
653
654         return ret;
655 }
656
657 /****************************************************************************
658 ****************************************************************************/
659
660 static BOOL test_EachPrinter(struct torture_context *tctx,
661                              LPSTR servername,
662                              LPSTR architecture,
663                              LPPRINTER_DEFAULTS defaults)
664 {
665         DWORD needed = 0;
666         DWORD returned = 0;
667         DWORD err = 0;
668         char tmp[1024];
669         DWORD i;
670         DWORD flags = PRINTER_ENUM_NAME;
671         PPRINTER_INFO_1 buffer = NULL;
672         BOOL ret = TRUE;
673
674         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
675
676         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
677         err = GetLastError();
678         if (err == ERROR_INSUFFICIENT_BUFFER) {
679                 err = 0;
680                 buffer = (PPRINTER_INFO_1)malloc(needed);
681                 torture_assert(tctx, buffer, "malloc failed");
682                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
683                         err = GetLastError();
684                 }
685         }
686         if (err) {
687                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
688                         1, servername, needed, errstr(err));
689                 torture_fail(tctx, tmp);
690         }
691
692         for (i=0; i < returned; i++) {
693                 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
694         }
695
696         free(buffer);
697
698         return ret;
699 }
700
701 /****************************************************************************
702 ****************************************************************************/
703
704 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
705                                             LPSTR servername,
706                                             LPSTR architecture)
707 {
708         DWORD levels[]  = { 1 };
709         DWORD success[] = { 1 };
710         DWORD i;
711         LPBYTE buffer = NULL;
712
713         for (i=0; i < ARRAY_SIZE(levels); i++) {
714
715                 DWORD needed = 0;
716                 DWORD err = 0;
717                 char tmp[1024];
718
719                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
720
721                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
722                 err = GetLastError();
723                 if (err == ERROR_INSUFFICIENT_BUFFER) {
724                         err = 0;
725                         buffer = malloc(needed);
726                         torture_assert(tctx, buffer, "malloc failed");
727                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
728                                 err = GetLastError();
729                         }
730                 }
731                 if (err) {
732                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
733                                 levels[i], servername, needed, errstr(err));
734                         if (success[i]) {
735                                 torture_fail(tctx, tmp);
736                         } else {
737                                 torture_warning(tctx, tmp);
738                         }
739                 }
740
741                 free(buffer);
742                 buffer = NULL;
743         }
744
745         return TRUE;
746 }
747
748 /****************************************************************************
749 ****************************************************************************/
750
751 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
752                                            LPSTR servername,
753                                            LPSTR architecture)
754 {
755         DWORD levels[]  = { 1 };
756         DWORD success[] = { 1 };
757         DWORD i;
758         LPBYTE buffer = NULL;
759
760         for (i=0; i < ARRAY_SIZE(levels); i++) {
761
762                 DWORD needed = 0;
763                 DWORD err = 0;
764                 char tmp[1024];
765
766                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
767
768                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
769                 err = GetLastError();
770                 if (err == ERROR_INSUFFICIENT_BUFFER) {
771                         err = 0;
772                         buffer = malloc(needed);
773                         torture_assert(tctx, buffer, "malloc failed");
774                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
775                                 err = GetLastError();
776                         }
777                 }
778                 if (err) {
779                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
780                                 levels[i], servername, needed, errstr(err));
781                         if (success[i]) {
782                                 torture_fail(tctx, tmp);
783                         } else {
784                                 torture_warning(tctx, tmp);
785                         }
786                 }
787
788                 free(buffer);
789                 buffer = NULL;
790         }
791
792         return TRUE;
793 }
794
795
796 /****************************************************************************
797 ****************************************************************************/
798
799 int main(int argc, char *argv[])
800 {
801         BOOL ret = FALSE;
802         LPSTR servername;
803         LPSTR architecture = "Windows NT x86";
804         HANDLE server_handle;
805         PRINTER_DEFAULTS defaults_admin, defaults_use;
806         struct torture_context *tctx;
807
808         if (argc < 2) {
809                 fprintf(stderr, "usage: %s <servername> [print]\n", argv[0]);
810                 exit(-1);
811         }
812
813         tctx = malloc(sizeof(struct torture_context));
814         if (!tctx) {
815                 fprintf(stderr, "out of memory\n");
816                 exit(-1);
817         }
818         memset(tctx, '\0', sizeof(*tctx));
819
820         servername = argv[1];
821
822         if (argc >= 3) {
823                 if (strcmp(argv[2], "print") == 0) {
824                         tctx->print = TRUE;
825                 }
826         }
827
828         defaults_admin.pDatatype = NULL;
829         defaults_admin.pDevMode = NULL;
830         defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
831
832         defaults_use.pDatatype = NULL;
833         defaults_use.pDevMode = NULL;
834         defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
835
836         ret &= test_EnumPrinters(tctx, servername);
837         ret &= test_EnumDrivers(tctx, servername, architecture);
838         ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
839 /*      ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
840         ret &= test_EnumForms(tctx, servername, server_handle);
841         ret &= test_ClosePrinter(tctx, server_handle);
842         ret &= test_EnumPorts(tctx, servername);
843         ret &= test_EnumMonitors(tctx, servername);
844         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
845         ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
846         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
847         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
848         ret &= test_EachPrinter(tctx, servername, architecture, NULL);
849
850         if (!ret) {
851                 if (tctx->last_reason) {
852                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
853                 }
854                 free(tctx);
855                 return -1;
856         }
857
858         printf("%s run successfully\n", argv[0]);
859
860         free(tctx);
861         return 0;
862 }