d0129ef7fec6e96fea09ef58764202308abca67d
[mdw/samba.git] / testprogs / win32 / spoolss / testspoolss.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 "testspoolss.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_EnumPrinterData(struct torture_context *tctx,
686                                  LPSTR servername,
687                                  HANDLE handle)
688 {
689         DWORD err = 0;
690         LPTSTR value_name;
691         LPBYTE data;
692         DWORD index = 0;
693         DWORD type;
694         DWORD value_offered = 0, value_needed;
695         DWORD data_offered = 0, data_needed;
696         char tmp[1024];
697
698         torture_comment(tctx, "Testing EnumPrinterData(%d) (value offered: %d, data_offered: %d)\n",
699                 index, value_offered, data_offered);
700
701         err = EnumPrinterData(handle, 0, NULL, 0, &value_needed, NULL, NULL, 0, &data_needed);
702         if (err) {
703                 sprintf(tmp, "EnumPrinterData(%d) failed on [%s] (value size = %d, data size = %d), error: %s\n",
704                         index, servername, value_offered, data_offered, errstr(err));
705                 torture_fail(tctx, tmp);
706         }
707
708         value_name = malloc(value_needed);
709         torture_assert(tctx, value_name, "malloc failed");
710         data = malloc(data_needed);
711         torture_assert(tctx, data, "malloc failed");
712
713         value_offered = value_needed;
714         data_offered = data_needed;
715
716         do {
717
718                 value_needed = 0;
719                 data_needed = 0;
720
721                 torture_comment(tctx, "Testing EnumPrinterData(%d) (value offered: %d, data_offered: %d)\n",
722                         index, value_offered, data_offered);
723
724                 err = EnumPrinterData(handle, index++, value_name, value_offered, &value_needed, &type, data, data_offered, &data_needed);
725                 if (err == ERROR_NO_MORE_ITEMS) {
726                         break;
727                 }
728                 if (err) {
729                         sprintf(tmp, "EnumPrinterData(%d) failed on [%s] (value size = %d, data size = %d), error: %s\n",
730                                 index, servername, value_offered, data_offered, errstr(err));
731                         torture_fail(tctx, tmp);
732                 }
733
734                 if (tctx->print) {
735                         print_printer_data(NULL, value_name, data_needed, data, type);
736                 }
737
738         } while (err != ERROR_NO_MORE_ITEMS);
739
740         free(value_name);
741         free(data);
742
743         return TRUE;
744 }
745
746 /****************************************************************************
747 ****************************************************************************/
748
749 static BOOL test_EnumPrinterDataEx(struct torture_context *tctx,
750                                    LPSTR servername,
751                                    LPSTR keyname,
752                                    HANDLE handle,
753                                    LPBYTE *buffer_p,
754                                    DWORD *returned_p)
755 {
756         LPBYTE buffer = NULL;
757         DWORD needed = 0;
758         DWORD returned = 0;
759         DWORD err = 0;
760         char tmp[1024];
761
762         torture_comment(tctx, "Testing EnumPrinterDataEx(%s)", keyname);
763
764         err = EnumPrinterDataEx(handle, keyname, NULL, 0, &needed, &returned);
765         if (err == ERROR_MORE_DATA) {
766                 buffer = malloc(needed);
767                 torture_assert(tctx, buffer, "malloc failed");
768                 err = EnumPrinterDataEx(handle, keyname, buffer, needed, &needed, &returned);
769         }
770         if (err) {
771                 sprintf(tmp, "EnumPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
772                         keyname, servername, needed, errstr(err));
773                 torture_fail(tctx, tmp);
774         }
775
776         if (tctx->print) {
777                 DWORD i;
778                 LPPRINTER_ENUM_VALUES v = (LPPRINTER_ENUM_VALUES)buffer;
779                 for (i=0; i < returned; i++) {
780                         print_printer_enum_values(&v[i]);
781                 }
782         }
783
784         if (returned_p) {
785                 *returned_p = returned;
786         }
787
788         if (buffer_p) {
789                 *buffer_p = buffer;
790         } else {
791                 free(buffer);
792         }
793
794         return TRUE;
795 }
796
797 /****************************************************************************
798 ****************************************************************************/
799
800 static BOOL test_devicemode_equal(struct torture_context *tctx,
801                                   const DEVMODE *d1,
802                                   const DEVMODE *d2)
803 {
804         if (d1 == d2) {
805                 return TRUE;
806         }
807
808         if (!d1 || !d2) {
809                 torture_comment(tctx, "%s\n", __location__);
810                 return FALSE;
811         }
812
813         torture_assert_str_equal(tctx, (const char *)d1->dmDeviceName, (const char *)d2->dmDeviceName, "dmDeviceName mismatch");
814         torture_assert_int_equal(tctx, d1->dmSpecVersion, d2->dmSpecVersion, "dmSpecVersion mismatch");
815         torture_assert_int_equal(tctx, d1->dmDriverVersion, d2->dmDriverVersion, "dmDriverVersion mismatch");
816         torture_assert_int_equal(tctx, d1->dmSize, d2->dmSize, "size mismatch");
817         torture_assert_int_equal(tctx, d1->dmDriverExtra, d2->dmDriverExtra, "dmDriverExtra mismatch");
818         torture_assert_int_equal(tctx, d1->dmFields, d2->dmFields, "dmFields mismatch");
819
820         torture_assert_int_equal(tctx, d1->dmOrientation, d2->dmOrientation, "dmOrientation mismatch");
821         torture_assert_int_equal(tctx, d1->dmPaperSize, d2->dmPaperSize, "dmPaperSize mismatch");
822         torture_assert_int_equal(tctx, d1->dmPaperLength, d2->dmPaperLength, "dmPaperLength mismatch");
823         torture_assert_int_equal(tctx, d1->dmPaperWidth, d2->dmPaperWidth, "dmPaperWidth mismatch");
824         torture_assert_int_equal(tctx, d1->dmScale, d2->dmScale, "dmScale mismatch");
825         torture_assert_int_equal(tctx, d1->dmCopies, d2->dmCopies, "dmCopies mismatch");
826         torture_assert_int_equal(tctx, d1->dmDefaultSource, d2->dmDefaultSource, "dmDefaultSource mismatch");
827         torture_assert_int_equal(tctx, d1->dmPrintQuality, d2->dmPrintQuality, "dmPrintQuality mismatch");
828
829         torture_assert_int_equal(tctx, d1->dmColor, d2->dmColor, "dmColor mismatch");
830         torture_assert_int_equal(tctx, d1->dmDuplex, d2->dmDuplex, "dmDuplex mismatch");
831         torture_assert_int_equal(tctx, d1->dmYResolution, d2->dmYResolution, "dmYResolution mismatch");
832         torture_assert_int_equal(tctx, d1->dmTTOption, d2->dmTTOption, "dmTTOption mismatch");
833         torture_assert_int_equal(tctx, d1->dmCollate, d2->dmCollate, "dmCollate mismatch");
834         torture_assert_str_equal(tctx, (const char *)d1->dmFormName, (const char *)d2->dmFormName, "dmFormName mismatch");
835         torture_assert_int_equal(tctx, d1->dmLogPixels, d2->dmLogPixels, "dmLogPixels mismatch");
836         torture_assert_int_equal(tctx, d1->dmBitsPerPel, d2->dmBitsPerPel, "dmBitsPerPel mismatch");
837         torture_assert_int_equal(tctx, d1->dmPelsWidth, d2->dmPelsWidth, "dmPelsWidth mismatch");
838         torture_assert_int_equal(tctx, d1->dmPelsHeight, d2->dmPelsHeight, "dmPelsHeight mismatch");
839
840         torture_assert_int_equal(tctx, d1->dmDisplayFlags, d2->dmDisplayFlags, "dmDisplayFlags mismatch");
841         /* or dmNup ? */
842         torture_assert_int_equal(tctx, d1->dmDisplayFrequency, d2->dmDisplayFrequency, "dmDisplayFrequency mismatch");
843
844         torture_assert_int_equal(tctx, d1->dmICMMethod, d2->dmICMMethod, "dmICMMethod mismatch");
845         torture_assert_int_equal(tctx, d1->dmICMIntent, d2->dmICMIntent, "dmICMIntent mismatch");
846         torture_assert_int_equal(tctx, d1->dmMediaType, d2->dmMediaType, "dmMediaType mismatch");
847         torture_assert_int_equal(tctx, d1->dmDitherType, d2->dmDitherType, "dmDitherType mismatch");
848         torture_assert_int_equal(tctx, d1->dmReserved1, d2->dmReserved1, "dmReserved1 mismatch");
849         torture_assert_int_equal(tctx, d1->dmReserved2, d2->dmReserved2, "reserved2 mismatch");
850
851         torture_assert_int_equal(tctx, d1->dmPanningWidth, d2->dmPanningWidth, "dmPanningWidth mismatch");
852         torture_assert_int_equal(tctx, d1->dmPanningHeight, d2->dmPanningHeight, "dmPanningHeight mismatch");
853
854         /* torture_assert_mem_equal(tctx, d1 + d1->dmSize, d2 + d2->dmSize, d1->dmDriverExtra, "private extra data mismatch"); */
855
856         return TRUE;
857 }
858
859 /****************************************************************************
860 ****************************************************************************/
861
862 static BOOL test_DeviceModes(struct torture_context *tctx,
863                              LPSTR printername,
864                              HANDLE handle)
865 {
866         PPRINTER_INFO_2 info2 = NULL;
867         PPRINTER_INFO_8 info8 = NULL;
868         DWORD needed = 0;
869         DWORD err = 0;
870         char tmp[1024];
871
872         torture_comment(tctx, "Testing DeviceModes");
873
874         torture_comment(tctx, "Testing GetPrinter level %d", 2);
875
876         GetPrinter(handle, 2, NULL, 0, &needed);
877         err = GetLastError();
878         if (err == ERROR_INSUFFICIENT_BUFFER) {
879                 err = 0;
880                 info2 = (PPRINTER_INFO_2)malloc(needed);
881                 torture_assert(tctx, (LPBYTE)info2, "malloc failed");
882                 if (!GetPrinter(handle, 2, (LPBYTE)info2, needed, &needed)) {
883                         err = GetLastError();
884                 }
885         }
886         if (err) {
887                 sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
888                         2, printername, needed, errstr(err));
889                 torture_fail(tctx, tmp);
890         }
891
892         if (tctx->print) {
893                 print_printer_info_2(info2);
894         }
895
896         torture_comment(tctx, "Testing GetPrinter level %d", 8);
897
898         GetPrinter(handle, 8, NULL, 0, &needed);
899         err = GetLastError();
900         if (err == ERROR_INSUFFICIENT_BUFFER) {
901                 err = 0;
902                 info8 = (PPRINTER_INFO_8)malloc(needed);
903                 torture_assert(tctx, (LPBYTE)info8, "malloc failed");
904                 if (!GetPrinter(handle, 8, (LPBYTE)info8, needed, &needed)) {
905                         err = GetLastError();
906                 }
907         }
908         if (err) {
909                 sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
910                         8, printername, needed, errstr(err));
911                 torture_fail(tctx, tmp);
912         }
913
914         if (tctx->print) {
915                 print_printer_info_8(info8);
916         }
917
918         torture_assert(tctx, test_devicemode_equal(tctx, info2->pDevMode, info8->pDevMode), "");
919
920         free(info2);
921         free(info8);
922
923         return TRUE;
924 }
925
926 /****************************************************************************
927 ****************************************************************************/
928
929 static BOOL test_GetJob(struct torture_context *tctx,
930                         LPSTR printername,
931                         HANDLE handle,
932                         DWORD job_id)
933 {
934         DWORD levels[]  = { 1, 2, 3, 4 };
935         DWORD success[] = { 1, 1, 1, 1 };
936         DWORD i;
937         LPBYTE buffer = NULL;
938
939         for (i=0; i < ARRAY_SIZE(levels); i++) {
940
941                 DWORD needed = 0;
942                 DWORD err = 0;
943                 char tmp[1024];
944
945                 torture_comment(tctx, "Testing GetJob(%d) level %d", job_id, levels[i]);
946
947                 if (tctx->samba3 && (levels[i] == 4) || (levels[i] == 3)) {
948                         torture_comment(tctx, "skipping level %d getjob against samba\n", levels[i]);
949                         continue;
950                 }
951
952                 GetJob(handle, job_id, levels[i], NULL, 0, &needed);
953                 err = GetLastError();
954                 if (err == ERROR_INSUFFICIENT_BUFFER) {
955                         err = 0;
956                         buffer = malloc(needed);
957                         torture_assert(tctx, buffer, "malloc failed");
958                         if (!GetJob(handle, job_id, levels[i], buffer, needed, &needed)) {
959                                 err = GetLastError();
960                         }
961                 }
962                 if (err) {
963                         sprintf(tmp, "GetJob failed level %d on [%s] (buffer size = %d), error: %s\n",
964                                 levels[i], printername, needed, errstr(err));
965                         if (success[i]) {
966                                 torture_fail(tctx, tmp);
967                         } else {
968                                 torture_warning(tctx, tmp);
969                         }
970                 }
971
972                 if (tctx->print) {
973                         print_job_info_bylevel(levels[i], buffer, 1);
974                 }
975
976                 free(buffer);
977                 buffer = NULL;
978         }
979
980         return TRUE;
981 }
982
983 /****************************************************************************
984 ****************************************************************************/
985
986 static BOOL test_EachJob(struct torture_context *tctx,
987                          LPSTR printername,
988                          HANDLE handle)
989 {
990         DWORD i;
991         PJOB_INFO_1 buffer = NULL;
992         DWORD needed = 0;
993         DWORD returned = 0;
994         DWORD err = 0;
995         DWORD level = 1;
996         char tmp[1024];
997         BOOL ret = TRUE;
998
999         torture_comment(tctx, "Testing Each PrintJob %d");
1000
1001         EnumJobs(handle, 0, 100, level, NULL, 0, &needed, &returned);
1002         err = GetLastError();
1003         if (err == ERROR_INSUFFICIENT_BUFFER) {
1004                 err = 0;
1005                 buffer = (PJOB_INFO_1)malloc(needed);
1006                 torture_assert(tctx, buffer, "malloc failed");
1007                 if (!EnumJobs(handle, 0, 100, level, (LPBYTE)buffer, needed, &needed, &returned)) {
1008                         err = GetLastError();
1009                 }
1010         }
1011         if (err) {
1012                 sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
1013                         level, printername, needed, errstr(err));
1014                 torture_fail(tctx, tmp);
1015         }
1016
1017         if (tctx->print) {
1018                 print_job_info_bylevel(level, (LPBYTE)buffer, returned);
1019         }
1020
1021         for (i=0; i < returned; i++) {
1022                 ret = test_GetJob(tctx, printername, handle, buffer[i].JobId);
1023         }
1024
1025         free(buffer);
1026
1027         return ret;
1028
1029 }
1030
1031 /****************************************************************************
1032 ****************************************************************************/
1033
1034 static BOOL test_OnePrinter(struct torture_context *tctx,
1035                             LPSTR printername,
1036                             LPSTR architecture,
1037                             LPPRINTER_DEFAULTS defaults)
1038 {
1039         HANDLE handle;
1040         BOOL ret = TRUE;
1041
1042         torture_comment(tctx, "Testing Printer %s", printername);
1043
1044         ret &= test_OpenPrinter(tctx, printername, defaults, &handle);
1045         ret &= test_GetPrinter(tctx, printername, handle);
1046         ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
1047         ret &= test_EnumForms(tctx, printername, handle);
1048         ret &= test_EnumJobs(tctx, printername, handle);
1049         ret &= test_EachJob(tctx, printername, handle);
1050         ret &= test_EnumPrinterKey(tctx, printername, handle, "");
1051         ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
1052         ret &= test_EnumPrinterData(tctx, printername, handle);
1053         ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL);
1054         ret &= test_DeviceModes(tctx, printername, handle);
1055 #if 0
1056         /* dont run these at the moment, behaviour is PrinterData API calls (not
1057          * dcerpc calls) is almost unpredictable - gd */
1058         ret &= test_PrinterData(tctx, printername, handle);
1059         ret &= test_PrinterDataW(tctx, printername, handle);
1060 #endif
1061         ret &= test_ClosePrinter(tctx, handle);
1062
1063         return ret;
1064 }
1065
1066 /****************************************************************************
1067 ****************************************************************************/
1068
1069 static BOOL test_EachPrinter(struct torture_context *tctx,
1070                              LPSTR servername,
1071                              LPSTR architecture,
1072                              LPPRINTER_DEFAULTS defaults)
1073 {
1074         DWORD needed = 0;
1075         DWORD returned = 0;
1076         DWORD err = 0;
1077         char tmp[1024];
1078         DWORD i;
1079         DWORD flags = PRINTER_ENUM_NAME;
1080         PPRINTER_INFO_1 buffer = NULL;
1081         BOOL ret = TRUE;
1082
1083         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
1084
1085         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
1086         err = GetLastError();
1087         if (err == ERROR_INSUFFICIENT_BUFFER) {
1088                 err = 0;
1089                 buffer = (PPRINTER_INFO_1)malloc(needed);
1090                 torture_assert(tctx, buffer, "malloc failed");
1091                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
1092                         err = GetLastError();
1093                 }
1094         }
1095         if (err) {
1096                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
1097                         1, servername, needed, errstr(err));
1098                 torture_fail(tctx, tmp);
1099         }
1100
1101         for (i=0; i < returned; i++) {
1102                 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
1103         }
1104
1105         free(buffer);
1106
1107         return ret;
1108 }
1109
1110 /****************************************************************************
1111 ****************************************************************************/
1112
1113 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
1114                                             LPSTR servername,
1115                                             LPSTR architecture)
1116 {
1117         DWORD levels[]  = { 1 };
1118         DWORD success[] = { 1 };
1119         DWORD i;
1120         LPBYTE buffer = NULL;
1121
1122         for (i=0; i < ARRAY_SIZE(levels); i++) {
1123
1124                 DWORD needed = 0;
1125                 DWORD err = 0;
1126                 char tmp[1024];
1127
1128                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
1129
1130                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
1131                 err = GetLastError();
1132                 if (err == ERROR_INSUFFICIENT_BUFFER) {
1133                         err = 0;
1134                         buffer = malloc(needed);
1135                         torture_assert(tctx, buffer, "malloc failed");
1136                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
1137                                 err = GetLastError();
1138                         }
1139                 }
1140                 if (err) {
1141                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
1142                                 levels[i], servername, needed, errstr(err));
1143                         if (success[i]) {
1144                                 torture_fail(tctx, tmp);
1145                         } else {
1146                                 torture_warning(tctx, tmp);
1147                         }
1148                 }
1149
1150                 if (tctx->print) {
1151                         printf("\tPrint Processor Directory\t= %s\n\n", (LPSTR)buffer);
1152                 }
1153
1154                 free(buffer);
1155                 buffer = NULL;
1156         }
1157
1158         return TRUE;
1159 }
1160
1161 /****************************************************************************
1162 ****************************************************************************/
1163
1164 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
1165                                            LPSTR servername,
1166                                            LPSTR architecture)
1167 {
1168         DWORD levels[]  = { 1 };
1169         DWORD success[] = { 1 };
1170         DWORD i;
1171         LPBYTE buffer = NULL;
1172
1173         for (i=0; i < ARRAY_SIZE(levels); i++) {
1174
1175                 DWORD needed = 0;
1176                 DWORD err = 0;
1177                 char tmp[1024];
1178
1179                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
1180
1181                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
1182                 err = GetLastError();
1183                 if (err == ERROR_INSUFFICIENT_BUFFER) {
1184                         err = 0;
1185                         buffer = malloc(needed);
1186                         torture_assert(tctx, buffer, "malloc failed");
1187                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
1188                                 err = GetLastError();
1189                         }
1190                 }
1191                 if (err) {
1192                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
1193                                 levels[i], servername, needed, errstr(err));
1194                         if (success[i]) {
1195                                 torture_fail(tctx, tmp);
1196                         } else {
1197                                 torture_warning(tctx, tmp);
1198                         }
1199                 }
1200
1201                 if (tctx->print) {
1202                         printf("\tPrinter Driver Directory\t= %s\n\n", (LPSTR)buffer);
1203                 }
1204
1205                 free(buffer);
1206                 buffer = NULL;
1207         }
1208
1209         return TRUE;
1210 }
1211
1212 /****************************************************************************
1213 ****************************************************************************/
1214
1215 static BOOL test_GetPrinterData(struct torture_context *tctx,
1216                                 LPSTR servername,
1217                                 LPSTR valuename,
1218                                 HANDLE handle,
1219                                 DWORD *type_p,
1220                                 LPBYTE *buffer_p,
1221                                 DWORD *size_p)
1222 {
1223         LPBYTE buffer = NULL;
1224         DWORD needed = 0;
1225         DWORD type;
1226         DWORD err = 0;
1227         char tmp[1024];
1228
1229         torture_comment(tctx, "Testing GetPrinterData(%s)", valuename);
1230
1231         err = GetPrinterData(handle, valuename, &type, NULL, 0, &needed);
1232         if (err == ERROR_MORE_DATA) {
1233                 buffer = (LPBYTE)malloc(needed);
1234                 torture_assert(tctx, buffer, "malloc failed");
1235                 err = GetPrinterData(handle, valuename, &type, buffer, needed, &needed);
1236         }
1237         if (err) {
1238                 sprintf(tmp, "GetPrinterData(%s) failed on [%s] (buffer size = %d), error: %s\n",
1239                         valuename, servername, needed, errstr(err));
1240                 torture_fail(tctx, tmp);
1241         }
1242
1243         if (tctx->print) {
1244                 print_printer_data("PrinterDriverData", valuename, needed, buffer, type);
1245         }
1246
1247         if (type_p) {
1248                 *type_p = type;
1249         }
1250
1251         if (size_p) {
1252                 *size_p = needed;
1253         }
1254
1255         if (buffer_p) {
1256                 *buffer_p = buffer;
1257         } else {
1258                 free(buffer);
1259         }
1260
1261         return TRUE;
1262 }
1263
1264 /****************************************************************************
1265 ****************************************************************************/
1266
1267 static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
1268                                   LPSTR servername,
1269                                   LPSTR keyname,
1270                                   LPSTR valuename,
1271                                   HANDLE handle,
1272                                   DWORD *type_p,
1273                                   LPBYTE *buffer_p,
1274                                   DWORD *size_p)
1275 {
1276         LPBYTE buffer = NULL;
1277         DWORD needed = 0;
1278         DWORD type;
1279         DWORD err = 0;
1280         char tmp[1024];
1281
1282         torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)", keyname, valuename);
1283
1284         err = GetPrinterDataEx(handle, keyname, valuename, &type, NULL, 0, &needed);
1285         if (err == ERROR_MORE_DATA) {
1286                 buffer = (LPBYTE)malloc(needed);
1287                 torture_assert(tctx, buffer, "malloc failed");
1288                 err = GetPrinterDataEx(handle, keyname, valuename, &type, buffer, needed, &needed);
1289         }
1290         if (err) {
1291                 sprintf(tmp, "GetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
1292                         valuename, servername, needed, errstr(err));
1293                 torture_fail(tctx, tmp);
1294         }
1295
1296         if (tctx->print) {
1297                 print_printer_data(keyname, valuename, needed, buffer, type);
1298         }
1299
1300         if (type_p) {
1301                 *type_p = type;
1302         }
1303
1304         if (size_p) {
1305                 *size_p = needed;
1306         }
1307
1308         if (buffer_p) {
1309                 *buffer_p = buffer;
1310         } else {
1311                 free(buffer);
1312         }
1313
1314         return TRUE;
1315 }
1316
1317 /****************************************************************************
1318 ****************************************************************************/
1319
1320 static BOOL test_GetPrinterDataExW(struct torture_context *tctx,
1321                                    LPSTR servername,
1322                                    LPCWSTR keyname,
1323                                    LPCWSTR valuename,
1324                                    HANDLE handle,
1325                                    DWORD *type_p,
1326                                    LPBYTE *buffer_p,
1327                                    DWORD *size_p)
1328 {
1329         LPBYTE buffer = NULL;
1330         DWORD needed = 0;
1331         DWORD type;
1332         DWORD err = 0;
1333         char tmp[1024];
1334
1335         torture_comment(tctx, "Testing GetPrinterDataExW(%ls - %ls)", keyname, valuename);
1336
1337         err = GetPrinterDataExW(handle, keyname, valuename, &type, NULL, 0, &needed);
1338         if (err == ERROR_MORE_DATA) {
1339                 buffer = (LPBYTE)malloc(needed);
1340                 torture_assert(tctx, buffer, "malloc failed");
1341                 err = GetPrinterDataExW(handle, keyname, valuename, &type, buffer, needed, &needed);
1342         }
1343         if (err) {
1344                 sprintf(tmp, "GetPrinterDataExW(%ls) failed on [%s] (buffer size = %d), error: %s\n",
1345                         valuename, servername, needed, errstr(err));
1346                 torture_fail(tctx, tmp);
1347         }
1348
1349         if (tctx->print) {
1350                 print_printer_dataw(keyname, valuename, needed, buffer, type);
1351         }
1352
1353         if (type_p) {
1354                 *type_p = type;
1355         }
1356
1357         if (size_p) {
1358                 *size_p = needed;
1359         }
1360
1361         if (buffer_p) {
1362                 *buffer_p = buffer;
1363         } else {
1364                 free(buffer);
1365         }
1366
1367         return TRUE;
1368 }
1369
1370
1371 /****************************************************************************
1372 ****************************************************************************/
1373
1374 static BOOL test_DeletePrinterDataEx(struct torture_context *tctx,
1375                                      LPSTR servername,
1376                                      LPSTR keyname,
1377                                      LPSTR valuename,
1378                                      HANDLE handle)
1379 {
1380         DWORD err = 0;
1381         char tmp[1024];
1382
1383         torture_comment(tctx, "Testing DeletePrinterDataEx(%s - %s)", keyname, valuename);
1384
1385         err = DeletePrinterDataEx(handle, keyname, valuename);
1386         if (err) {
1387                 sprintf(tmp, "DeletePrinterDataEx(%s - %s) failed on [%s], error: %s\n",
1388                         keyname, valuename, servername, errstr(err));
1389                 torture_fail(tctx, tmp);
1390         }
1391
1392         return TRUE;
1393 }
1394
1395 /****************************************************************************
1396 ****************************************************************************/
1397
1398 static BOOL test_DeletePrinterDataExW(struct torture_context *tctx,
1399                                       LPSTR servername,
1400                                       LPCWSTR keyname,
1401                                       LPCWSTR valuename,
1402                                       HANDLE handle)
1403 {
1404         DWORD err = 0;
1405         char tmp[1024];
1406
1407         torture_comment(tctx, "Testing DeletePrinterDataExW(%ls - %ls)", keyname, valuename);
1408
1409         err = DeletePrinterDataExW(handle, keyname, valuename);
1410         if (err) {
1411                 sprintf(tmp, "DeletePrinterDataExW(%ls - %ls) failed on [%s], error: %s\n",
1412                         keyname, valuename, servername, errstr(err));
1413                 torture_fail(tctx, tmp);
1414         }
1415
1416         return TRUE;
1417 }
1418
1419
1420 /****************************************************************************
1421 ****************************************************************************/
1422
1423 static BOOL test_DeletePrinterKey(struct torture_context *tctx,
1424                                   LPSTR servername,
1425                                   LPSTR keyname,
1426                                   HANDLE handle)
1427 {
1428         DWORD err = 0;
1429         char tmp[1024];
1430
1431         torture_comment(tctx, "Testing DeletePrinterKey(%s)", keyname);
1432
1433         err = DeletePrinterKey(handle, keyname);
1434         if (err) {
1435                 sprintf(tmp, "DeletePrinterKey(%s) failed on [%s], error: %s\n",
1436                         keyname, servername, errstr(err));
1437                 torture_fail(tctx, tmp);
1438         }
1439
1440         return TRUE;
1441 }
1442
1443 /****************************************************************************
1444 ****************************************************************************/
1445
1446 static BOOL test_DeletePrinterKeyW(struct torture_context *tctx,
1447                                    LPSTR servername,
1448                                    LPCWSTR keyname,
1449                                    HANDLE handle)
1450 {
1451         DWORD err = 0;
1452         char tmp[1024];
1453
1454         torture_comment(tctx, "Testing DeletePrinterKeyW(%ls)", keyname);
1455
1456         err = DeletePrinterKeyW(handle, keyname);
1457         if (err) {
1458                 sprintf(tmp, "DeletePrinterKeyW(%ls) failed on [%s], error: %s\n",
1459                         keyname, servername, errstr(err));
1460                 torture_fail(tctx, tmp);
1461         }
1462
1463         return TRUE;
1464 }
1465
1466 /****************************************************************************
1467 ****************************************************************************/
1468
1469 static BOOL test_SetPrinterDataEx(struct torture_context *tctx,
1470                                   LPSTR servername,
1471                                   LPSTR keyname,
1472                                   LPSTR valuename,
1473                                   HANDLE handle,
1474                                   DWORD type,
1475                                   LPBYTE buffer,
1476                                   DWORD offered)
1477 {
1478         DWORD err = 0;
1479         char tmp[1024];
1480
1481         torture_comment(tctx, "Testing SetPrinterDataEx(%s - %s)", keyname, valuename);
1482
1483         err = SetPrinterDataEx(handle, keyname, valuename, type, buffer, offered);
1484         if (err) {
1485                 sprintf(tmp, "SetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
1486                         valuename, servername, offered, errstr(err));
1487                 torture_fail(tctx, tmp);
1488         }
1489
1490         return TRUE;
1491 }
1492
1493 /****************************************************************************
1494 ****************************************************************************/
1495
1496 static BOOL test_SetPrinterDataExW(struct torture_context *tctx,
1497                                    LPCSTR servername,
1498                                    LPCWSTR keyname,
1499                                    LPCWSTR valuename,
1500                                    HANDLE handle,
1501                                    DWORD type,
1502                                    LPBYTE buffer,
1503                                    DWORD offered)
1504 {
1505         DWORD err = 0;
1506         char tmp[1024];
1507
1508         torture_comment(tctx, "Testing SetPrinterDataExW(%ls - %ls)", keyname, valuename);
1509
1510         err = SetPrinterDataExW(handle, keyname, valuename, type, buffer, offered);
1511         if (err) {
1512                 sprintf(tmp, "SetPrinterDataExW(%ls) failed on [%s] (buffer size = %d), error: %s\n",
1513                         valuename, servername, offered, errstr(err));
1514                 torture_fail(tctx, tmp);
1515         }
1516
1517         return TRUE;
1518 }
1519
1520
1521 /****************************************************************************
1522 ****************************************************************************/
1523
1524 static BOOL test_PrinterData_Server(struct torture_context *tctx,
1525                                     LPSTR servername,
1526                                     HANDLE handle)
1527 {
1528         BOOL ret = TRUE;
1529         DWORD i;
1530         DWORD type, type_ex;
1531         LPBYTE buffer, buffer_ex;
1532         DWORD size, size_ex;
1533         LPSTR valuenames[] = {
1534                 SPLREG_DEFAULT_SPOOL_DIRECTORY,
1535                 SPLREG_MAJOR_VERSION,
1536                 SPLREG_MINOR_VERSION,
1537                 SPLREG_DS_PRESENT,
1538                 SPLREG_DNS_MACHINE_NAME,
1539                 SPLREG_ARCHITECTURE,
1540                 SPLREG_OS_VERSION
1541         };
1542
1543         for (i=0; i < ARRAY_SIZE(valuenames); i++) {
1544                 ret &= test_GetPrinterData(tctx, servername, valuenames[i], handle, &type, &buffer, &size);
1545                 ret &= test_GetPrinterDataEx(tctx, servername, "random", valuenames[i], handle, &type_ex, &buffer_ex, &size_ex);
1546                 torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
1547                 torture_assert_int_equal(tctx, size, size_ex, "size mismatch");
1548                 torture_assert_mem_equal(tctx, buffer, buffer_ex, size, "buffer mismatch");
1549                 free(buffer);
1550                 free(buffer_ex);
1551         }
1552
1553         return ret;
1554 }
1555
1556 /****************************************************************************
1557 ****************************************************************************/
1558
1559 static BOOL PrinterDataEqual(struct torture_context *tctx,
1560                              DWORD type1, DWORD type2,
1561                              DWORD size1, DWORD size2,
1562                              LPBYTE buffer1, LPBYTE buffer2)
1563 {
1564         torture_assert_int_equal(tctx, type1, type2, "type mismatch");
1565         torture_assert_int_equal(tctx, size1, size2, "size mismatch");
1566         torture_assert_mem_equal(tctx, buffer1, buffer2, size1, "buffer mismatch");
1567
1568         return TRUE;
1569 }
1570
1571 /****************************************************************************
1572 ****************************************************************************/
1573
1574 static BOOL test_PrinterData(struct torture_context *tctx,
1575                              LPSTR printername,
1576                              HANDLE handle)
1577 {
1578         char tmp[1024];
1579         LPSTR keyname = "torture_key";
1580         LPSTR valuename = "torture_value";
1581         BOOL ret = TRUE;
1582         DWORD types[] = {
1583                 REG_SZ,
1584                 REG_DWORD,
1585                 REG_BINARY
1586         };
1587         DWORD value = 12345678;
1588         LPSTR str = "abcdefghijklmnopqrstuvwxzy";
1589         DWORD t, s;
1590
1591         for (t=0; t < ARRAY_SIZE(types); t++) {
1592         for (s=0; s < strlen(str); s++) {
1593
1594                 DWORD type, type_ex;
1595                 LPBYTE buffer, buffer_ex;
1596                 DWORD size, size_ex;
1597
1598                 if (types[t] == REG_DWORD) {
1599                         s = 0xffff;
1600                 }
1601
1602                 switch (types[t]) {
1603                 case REG_BINARY:
1604                         buffer = malloc(s);
1605                         memcpy(buffer, str, s);
1606                         size = s;
1607                         break;
1608                 case REG_DWORD:
1609                         buffer = malloc(4);
1610                         memcpy(buffer, &value, 4);
1611                         size = 4;
1612                         break;
1613                 case REG_SZ:
1614                         buffer = malloc(s);
1615                         memcpy(buffer, str, s);
1616                         size = s;
1617                         break;
1618                 default:
1619                         sprintf(tmp, "type %d untested\n", types[t]);
1620                         torture_fail(tctx, tmp);
1621                         break;
1622                 }
1623
1624                 type = types[t];
1625
1626                 torture_comment(tctx, "Testing PrinterData (type: %s, size: 0x%08x)", reg_type_str(type), size);
1627
1628                 torture_assert(tctx,
1629                         test_SetPrinterDataEx(tctx, printername, keyname, valuename, handle, type, buffer, size),
1630                         "failed to call SetPrinterDataEx");
1631                 torture_assert(tctx,
1632                         test_GetPrinterDataEx(tctx, printername, keyname, valuename, handle, &type_ex, &buffer_ex, &size_ex),
1633                         "failed to call GetPrinterDataEx");
1634
1635                 if (!PrinterDataEqual(tctx, type_ex, type, size_ex, size, buffer_ex, buffer)) {
1636                         torture_warning(tctx, "GetPrinterDataEx does not return the same info as we set with SetPrinterDataEx");
1637                         ret = FALSE;
1638                 }
1639                 ret &= test_DeletePrinterDataEx(tctx, printername, keyname, valuename, handle);
1640                 ret &= test_DeletePrinterKey(tctx, printername, keyname, handle);
1641
1642                 free(buffer);
1643                 free(buffer_ex);
1644         }
1645         }
1646
1647         return ret;
1648 }
1649
1650 /****************************************************************************
1651 ****************************************************************************/
1652
1653 static BOOL test_PrinterDataW(struct torture_context *tctx,
1654                               LPSTR printername,
1655                               HANDLE handle)
1656 {
1657         char tmp[1024];
1658         LPCWSTR keyname = L"torture_key";
1659         LPCWSTR valuename = L"torture_value";
1660         BOOL ret = TRUE;
1661         DWORD types[] = {
1662                 REG_SZ,
1663                 REG_DWORD,
1664                 REG_BINARY
1665         };
1666         DWORD value = 12345678;
1667         LPSTR str = "abcdefghijklmnopqrstuvwxzy";
1668         DWORD t, s;
1669
1670         for (t=0; t < ARRAY_SIZE(types); t++) {
1671         for (s=0; s < strlen(str); s++) {
1672
1673                 DWORD type, type_ex;
1674                 LPBYTE buffer, buffer_ex;
1675                 DWORD size, size_ex;
1676
1677                 if (types[t] == REG_DWORD) {
1678                         s = 0xffff;
1679                 }
1680
1681                 switch (types[t]) {
1682                 case REG_BINARY:
1683                         buffer = malloc(s);
1684                         memcpy(buffer, str, s);
1685                         size = s;
1686                         break;
1687                 case REG_DWORD:
1688                         buffer = malloc(4);
1689                         memcpy(buffer, &value, 4);
1690                         size = 4;
1691                         break;
1692                 case REG_SZ:
1693                         buffer = malloc(s);
1694                         memcpy(buffer, str, s);
1695                         size = s;
1696                         break;
1697                 default:
1698                         sprintf(tmp, "type %d untested\n", types[t]);
1699                         torture_fail(tctx, tmp);
1700                         break;
1701                 }
1702
1703                 type = types[t];
1704
1705                 torture_comment(tctx, "Testing PrinterDataW (type: %s, size: 0x%08x)", reg_type_str(type), size);
1706
1707                 torture_assert(tctx,
1708                         test_SetPrinterDataExW(tctx, printername, keyname, valuename, handle, type, buffer, size),
1709                         "failed to call SetPrinterDataExW");
1710                 torture_assert(tctx,
1711                         test_GetPrinterDataExW(tctx, printername, keyname, valuename, handle, &type_ex, &buffer_ex, &size_ex),
1712                         "failed to call GetPrinterDataExW");
1713
1714                 if (!PrinterDataEqual(tctx, type_ex, type, size_ex, size, buffer_ex, buffer)) {
1715                         torture_warning(tctx, "GetPrinterDataExW does not return the same info as we set with SetPrinterDataExW");
1716                         ret = FALSE;
1717                 }
1718                 ret &= test_DeletePrinterDataExW(tctx, printername, keyname, valuename, handle);
1719                 ret &= test_DeletePrinterKeyW(tctx, printername, keyname, handle);
1720
1721                 free(buffer);
1722                 free(buffer_ex);
1723         }
1724         }
1725
1726         return ret;
1727 }
1728
1729 /****************************************************************************
1730 ****************************************************************************/
1731
1732 const char *get_string_param(const char *str)
1733 {
1734         const char *p;
1735
1736         p = strchr(str, '=');
1737         if (!p) {
1738                 return NULL;
1739         }
1740
1741         return (p+1);
1742 }
1743
1744 /****************************************************************************
1745 ****************************************************************************/
1746
1747 int main(int argc, char *argv[])
1748 {
1749         BOOL ret = FALSE;
1750         LPSTR servername;
1751         LPSTR architecture = "Windows NT x86";
1752         HANDLE server_handle;
1753         PRINTER_DEFAULTS defaults_admin, defaults_use;
1754         struct torture_context *tctx;
1755         int i;
1756
1757         if (argc < 2) {
1758                 fprintf(stderr, "usage: %s <name> [print] [samba3] [architecture=ARCHITECTURE]\n\n", argv[0]);
1759                 fprintf(stderr, "\t<name>           can be a server or printer name URI\n");
1760                 fprintf(stderr, "\t[print]          will print all data that has been retrieved\n");
1761                 fprintf(stderr, "\t                 from the printserver\n");
1762                 fprintf(stderr, "\t[samba3]         will skip some tests samba servers are known\n");
1763                 fprintf(stderr, "\t                 not to have implemented\n");
1764                 fprintf(stderr, "\t[architecture=X] allows to define a specific\n");
1765                 fprintf(stderr, "\t                 architecture to test with. choose between:\n");
1766                 fprintf(stderr, "\t                 \"Windows NT x86\" or \"Windows x64\"\n");
1767                 exit(-1);
1768         }
1769
1770         tctx = malloc(sizeof(struct torture_context));
1771         if (!tctx) {
1772                 fprintf(stderr, "out of memory\n");
1773                 exit(-1);
1774         }
1775         memset(tctx, '\0', sizeof(*tctx));
1776
1777         servername = argv[1];
1778
1779         for (i=1; i < argc; i++) {
1780                 if (strcmp(argv[i], "print") == 0) {
1781                         tctx->print = TRUE;
1782                 }
1783                 if (strcmp(argv[i], "samba3") == 0) {
1784                         tctx->samba3 = TRUE;
1785                 }
1786                 if (strncmp(argv[i], "architecture", strlen("architecture")) == 0) {
1787                         architecture = get_string_param(argv[i]);
1788                 }
1789         }
1790
1791         printf("Running testsuite with architecture: %s\n", architecture);
1792
1793         defaults_admin.pDatatype = NULL;
1794         defaults_admin.pDevMode = NULL;
1795         defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
1796
1797         defaults_use.pDatatype = NULL;
1798         defaults_use.pDevMode = NULL;
1799         defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
1800
1801         if ((servername[0] == '\\') && (servername[1] == '\\')) {
1802                 LPSTR p = servername+2;
1803                 LPSTR p2;
1804                 if ((p2 = strchr(p, '\\')) != NULL) {
1805                         ret = test_OnePrinter(tctx, servername, architecture, &defaults_admin);
1806                         goto done;
1807                 }
1808         }
1809
1810         ret &= test_EnumPrinters(tctx, servername);
1811         ret &= test_EnumDrivers(tctx, servername, architecture);
1812         ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
1813 /*      ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
1814         ret &= test_PrinterData_Server(tctx, servername, server_handle);
1815         ret &= test_EnumForms(tctx, servername, server_handle);
1816         ret &= test_ClosePrinter(tctx, server_handle);
1817         ret &= test_EnumPorts(tctx, servername);
1818         ret &= test_EnumMonitors(tctx, servername);
1819         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
1820         ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
1821         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
1822         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
1823         ret &= test_EachPrinter(tctx, servername, architecture, &defaults_admin);
1824
1825  done:
1826         if (!ret) {
1827                 if (tctx->last_reason) {
1828                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
1829                 }
1830                 free(tctx);
1831                 return -1;
1832         }
1833
1834         printf("%s run successfully\n", argv[0]);
1835
1836         free(tctx);
1837         return 0;
1838 }