testprogs: fix boolean return code of test_PrinterData.
[samba.git] / testprogs / win32 / spoolss / spoolss.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for spoolss rpc operations
4
5    Copyright (C) Guenther Deschner 2009-2010
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 /****************************************************************************
22 ****************************************************************************/
23
24 #include "spoolss.h"
25 #include "string.h"
26 #include "torture.h"
27
28 /****************************************************************************
29 ****************************************************************************/
30
31 static BOOL test_OpenPrinter(struct torture_context *tctx,
32                              LPSTR printername,
33                              LPPRINTER_DEFAULTS defaults,
34                              LPHANDLE handle)
35 {
36         torture_comment(tctx, "Testing OpenPrinter(%s)", printername);
37
38         if (!OpenPrinter(printername, handle, defaults)) {
39                 char tmp[1024];
40                 sprintf(tmp, "failed to open printer %s, error was: 0x%08x\n",
41                         printername, GetLastError());
42                 torture_fail(tctx, tmp);
43         }
44
45         return TRUE;
46 }
47
48 /****************************************************************************
49 ****************************************************************************/
50
51 static BOOL test_ClosePrinter(struct torture_context *tctx,
52                               HANDLE handle)
53 {
54         torture_comment(tctx, "Testing ClosePrinter");
55
56         if (!ClosePrinter(handle)) {
57                 char tmp[1024];
58                 sprintf(tmp, "failed to close printer, error was: %s\n",
59                         errstr(GetLastError()));
60                 torture_fail(tctx, tmp);
61         }
62
63         return TRUE;
64 }
65
66
67 /****************************************************************************
68 ****************************************************************************/
69
70 static BOOL test_EnumPrinters(struct torture_context *tctx,
71                               LPSTR servername)
72 {
73         DWORD levels[]  = { 1, 2, 5 };
74         DWORD success[] = { 1, 1, 1 };
75         DWORD i;
76         DWORD flags = PRINTER_ENUM_NAME;
77         LPBYTE buffer = NULL;
78
79         for (i=0; i < ARRAY_SIZE(levels); i++) {
80
81                 DWORD needed = 0;
82                 DWORD returned = 0;
83                 DWORD err = 0;
84                 char tmp[1024];
85
86                 torture_comment(tctx, "Testing EnumPrinters level %d", levels[i]);
87
88                 EnumPrinters(flags, servername, levels[i], NULL, 0, &needed, &returned);
89                 err = GetLastError();
90                 if (err == ERROR_INSUFFICIENT_BUFFER) {
91                         err = 0;
92                         buffer = malloc(needed);
93                         torture_assert(tctx, buffer, "malloc failed");
94                         if (!EnumPrinters(flags, servername, levels[i], buffer, needed, &needed, &returned)) {
95                                 err = GetLastError();
96                         }
97                 }
98                 if (err) {
99                         sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
100                                 levels[i], servername, needed, errstr(err));
101                         if (success[i]) {
102                                 torture_fail(tctx, tmp);
103                         } else {
104                                 torture_warning(tctx, tmp);
105                         }
106                 }
107
108                 if (tctx->print) {
109                         print_printer_info_bylevel(levels[i], buffer, returned);
110                 }
111
112                 free(buffer);
113                 buffer = NULL;
114         }
115
116         return TRUE;
117 }
118
119 /****************************************************************************
120 ****************************************************************************/
121
122 static BOOL test_EnumDrivers(struct torture_context *tctx,
123                              LPSTR servername,
124                              LPSTR architecture)
125 {
126         DWORD levels[]  = { 1, 2, 3, 4, 5, 6 };
127         DWORD success[] = { 1, 1, 1, 1, 1, 1 };
128         DWORD i;
129         LPBYTE buffer = NULL;
130
131         for (i=0; i < ARRAY_SIZE(levels); i++) {
132
133                 DWORD needed = 0;
134                 DWORD returned = 0;
135                 DWORD err = 0;
136                 char tmp[1024];
137
138                 torture_comment(tctx, "Testing EnumPrinterDrivers level %d", levels[i]);
139
140                 EnumPrinterDrivers(servername, architecture, levels[i], NULL, 0, &needed, &returned);
141                 err = GetLastError();
142                 if (err == ERROR_INSUFFICIENT_BUFFER) {
143                         err = 0;
144                         buffer = malloc(needed);
145                         torture_assert(tctx, buffer, "malloc failed");
146                         if (!EnumPrinterDrivers(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
147                                 err = GetLastError();
148                         }
149                 }
150                 if (err) {
151                         sprintf(tmp, "EnumPrinterDrivers failed level %d on [%s] (buffer size = %d), error: %s\n",
152                                 levels[i], servername, needed, errstr(err));
153                         if (success[i]) {
154                                 torture_fail(tctx, tmp);
155                         } else {
156                                 torture_warning(tctx, tmp);
157                         }
158                 }
159
160                 if (tctx->print) {
161                         print_driver_info_bylevel(levels[i], buffer, returned);
162                 }
163
164                 free(buffer);
165                 buffer = NULL;
166         }
167
168         return TRUE;
169 }
170
171 /****************************************************************************
172 ****************************************************************************/
173
174 static BOOL test_GetForm(struct torture_context *tctx,
175                          LPSTR servername,
176                          HANDLE handle,
177                          LPSTR formname)
178 {
179         DWORD levels[]  = { 1, 2 };
180         DWORD success[] = { 1, 0 };
181         DWORD i;
182         LPBYTE buffer = NULL;
183
184         for (i=0; i < ARRAY_SIZE(levels); i++) {
185
186                 DWORD needed = 0;
187                 DWORD err = 0;
188                 char tmp[1024];
189
190                 torture_comment(tctx, "Testing GetForm(%s) level %d", formname, levels[i]);
191
192                 GetForm(handle, formname, levels[i], NULL, 0, &needed);
193                 err = GetLastError();
194                 if (err == ERROR_INSUFFICIENT_BUFFER) {
195                         err = 0;
196                         buffer = malloc(needed);
197                         torture_assert(tctx, buffer, "malloc failed");
198                         if (!GetForm(handle, formname, levels[i], buffer, needed, &needed)) {
199                                 err = GetLastError();
200                         }
201                 }
202                 if (err) {
203                         sprintf(tmp, "GetForm failed level %d on [%s] (buffer size = %d), error: %s\n",
204                                 levels[i], servername, needed, errstr(err));
205                         if (success[i]) {
206                                 torture_fail(tctx, tmp);
207                         } else {
208                                 torture_warning(tctx, tmp);
209                         }
210                 }
211
212                 if (tctx->print) {
213                         print_form_info_bylevel(levels[i], buffer, 1);
214                 }
215
216                 free(buffer);
217                 buffer = NULL;
218         }
219
220         return TRUE;
221 }
222
223 /****************************************************************************
224 ****************************************************************************/
225
226 static BOOL test_EnumForms(struct torture_context *tctx,
227                            LPSTR servername,
228                            HANDLE handle)
229 {
230         DWORD levels[]  = { 1, 2 };
231         DWORD success[] = { 1, 1 };
232         DWORD i;
233         LPBYTE buffer = NULL;
234
235         for (i=0; i < ARRAY_SIZE(levels); i++) {
236
237                 DWORD needed = 0;
238                 DWORD returned = 0;
239                 DWORD err = 0;
240                 char tmp[1024];
241
242                 torture_comment(tctx, "Testing EnumForms level %d", levels[i]);
243
244                 if (tctx->samba3 && levels[i] == 2) {
245                         torture_comment(tctx, "skipping level %d enum against samba\n", levels[i]);
246                         continue;
247                 }
248
249                 EnumForms(handle, levels[i], NULL, 0, &needed, &returned);
250                 err = GetLastError();
251                 if (err == ERROR_INSUFFICIENT_BUFFER) {
252                         err = 0;
253                         buffer = malloc(needed);
254                         torture_assert(tctx, buffer, "malloc failed");
255                         if (!EnumForms(handle, levels[i], buffer, needed, &needed, &returned)) {
256                                 err = GetLastError();
257                         }
258                 }
259                 if (err) {
260                         sprintf(tmp, "EnumForms failed level %d on [%s] (buffer size = %d), error: %s\n",
261                                 levels[i], servername, needed, errstr(err));
262                         if (success[i]) {
263                                 torture_fail(tctx, tmp);
264                         } else {
265                                 torture_warning(tctx, tmp);
266                         }
267                 }
268
269                 if (tctx->print) {
270                         print_form_info_bylevel(levels[i], buffer, returned);
271                 }
272
273                 free(buffer);
274                 buffer = NULL;
275         }
276
277         return TRUE;
278 }
279
280 /****************************************************************************
281 ****************************************************************************/
282
283 static BOOL test_EnumPorts(struct torture_context *tctx,
284                            LPSTR servername)
285 {
286         DWORD levels[]  = { 1, 2 };
287         DWORD success[] = { 1, 1 };
288         DWORD i;
289         LPBYTE buffer = NULL;
290
291         for (i=0; i < ARRAY_SIZE(levels); i++) {
292
293                 DWORD needed = 0;
294                 DWORD returned = 0;
295                 DWORD err = 0;
296                 char tmp[1024];
297
298                 torture_comment(tctx, "Testing EnumPorts level %d", levels[i]);
299
300                 EnumPorts(servername, levels[i], NULL, 0, &needed, &returned);
301                 err = GetLastError();
302                 if (err == ERROR_INSUFFICIENT_BUFFER) {
303                         err = 0;
304                         buffer = malloc(needed);
305                         torture_assert(tctx, buffer, "malloc failed");
306                         if (!EnumPorts(servername, levels[i], buffer, needed, &needed, &returned)) {
307                                 err = GetLastError();
308                         }
309                 }
310                 if (err) {
311                         sprintf(tmp, "EnumPorts failed level %d on [%s] (buffer size = %d), error: %s\n",
312                                 levels[i], servername, needed, errstr(err));
313                         if (success[i]) {
314                                 torture_fail(tctx, tmp);
315                         } else {
316                                 torture_warning(tctx, tmp);
317                         }
318                 }
319
320                 if (tctx->print) {
321                         print_port_info_bylevel(levels[i], buffer, returned);
322                 }
323
324                 free(buffer);
325                 buffer = NULL;
326         }
327
328         return TRUE;
329 }
330
331 /****************************************************************************
332 ****************************************************************************/
333
334 static BOOL test_EnumMonitors(struct torture_context *tctx,
335                               LPSTR servername)
336 {
337         DWORD levels[]  = { 1, 2 };
338         DWORD success[] = { 1, 1 };
339         DWORD i;
340         LPBYTE buffer = NULL;
341
342         for (i=0; i < ARRAY_SIZE(levels); i++) {
343
344                 DWORD needed = 0;
345                 DWORD returned = 0;
346                 DWORD err = 0;
347                 char tmp[1024];
348
349                 torture_comment(tctx, "Testing EnumMonitors level %d", levels[i]);
350
351                 EnumMonitors(servername, levels[i], NULL, 0, &needed, &returned);
352                 err = GetLastError();
353                 if (err == ERROR_INSUFFICIENT_BUFFER) {
354                         err = 0;
355                         buffer = malloc(needed);
356                         torture_assert(tctx, buffer, "malloc failed");
357                         if (!EnumMonitors(servername, levels[i], buffer, needed, &needed, &returned)) {
358                                 err = GetLastError();
359                         }
360                 }
361                 if (err) {
362                         sprintf(tmp, "EnumMonitors failed level %d on [%s] (buffer size = %d), error: %s\n",
363                                 levels[i], servername, needed, errstr(err));
364                         if (success[i]) {
365                                 torture_fail(tctx, tmp);
366                         } else {
367                                 torture_warning(tctx, tmp);
368                         }
369                 }
370
371                 if (tctx->print) {
372                         print_monitor_info_bylevel(levels[i], buffer, returned);
373                 }
374
375                 free(buffer);
376                 buffer = NULL;
377         }
378
379         return TRUE;
380 }
381
382 /****************************************************************************
383 ****************************************************************************/
384
385 static BOOL test_EnumPrintProcessors(struct torture_context *tctx,
386                                      LPSTR servername,
387                                      LPSTR architecture)
388 {
389         DWORD levels[]  = { 1 };
390         DWORD success[] = { 1 };
391         DWORD i;
392         LPBYTE buffer = NULL;
393
394         for (i=0; i < ARRAY_SIZE(levels); i++) {
395
396                 DWORD needed = 0;
397                 DWORD returned = 0;
398                 DWORD err = 0;
399                 char tmp[1024];
400
401                 torture_comment(tctx, "Testing EnumPrintProcessors level %d", levels[i]);
402
403                 EnumPrintProcessors(servername, architecture, levels[i], NULL, 0, &needed, &returned);
404                 err = GetLastError();
405                 if (err == ERROR_INSUFFICIENT_BUFFER) {
406                         err = 0;
407                         buffer = malloc(needed);
408                         torture_assert(tctx, buffer, "malloc failed");
409                         if (!EnumPrintProcessors(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
410                                 err = GetLastError();
411                         }
412                 }
413                 if (err) {
414                         sprintf(tmp, "EnumPrintProcessors failed level %d on [%s] (buffer size = %d), error: %s\n",
415                                 levels[i], servername, needed, errstr(err));
416                         if (success[i]) {
417                                 torture_fail(tctx, tmp);
418                         } else {
419                                 torture_warning(tctx, tmp);
420                         }
421                 }
422
423                 if (tctx->print) {
424                         print_printprocessor_info_bylevel(levels[i], buffer, returned);
425                 }
426
427                 free(buffer);
428                 buffer = NULL;
429         }
430
431         return TRUE;
432 }
433
434 /****************************************************************************
435 ****************************************************************************/
436
437 static BOOL test_EnumPrintProcessorDatatypes(struct torture_context *tctx,
438                                              LPSTR servername)
439 {
440         DWORD levels[]  = { 1 };
441         DWORD success[] = { 1 };
442         DWORD i;
443         LPBYTE buffer = NULL;
444
445         for (i=0; i < ARRAY_SIZE(levels); i++) {
446
447                 DWORD needed = 0;
448                 DWORD returned = 0;
449                 DWORD err = 0;
450                 char tmp[1024];
451
452                 torture_comment(tctx, "Testing EnumPrintProcessorDatatypes level %d", levels[i]);
453
454                 EnumPrintProcessorDatatypes(servername, "winprint", levels[i], NULL, 0, &needed, &returned);
455                 err = GetLastError();
456                 if (err == ERROR_INSUFFICIENT_BUFFER) {
457                         err = 0;
458                         buffer = malloc(needed);
459                         torture_assert(tctx, buffer, "malloc failed");
460                         if (!EnumPrintProcessorDatatypes(servername, "winprint", levels[i], buffer, needed, &needed, &returned)) {
461                                 err = GetLastError();
462                         }
463                 }
464                 if (err) {
465                         sprintf(tmp, "EnumPrintProcessorDatatypes failed level %d on [%s] (buffer size = %d), error: %s\n",
466                                 levels[i], servername, needed, errstr(err));
467                         if (success[i]) {
468                                 torture_fail(tctx, tmp);
469                         } else {
470                                 torture_warning(tctx, tmp);
471                         }
472                 }
473
474                 if (tctx->print) {
475                         print_datatypes_info_bylevel(levels[i], buffer, returned);
476                 }
477
478                 free(buffer);
479                 buffer = NULL;
480         }
481
482         return TRUE;
483 }
484
485 /****************************************************************************
486 ****************************************************************************/
487
488 static BOOL test_EnumPrinterKey(struct torture_context *tctx,
489                                 LPSTR servername,
490                                 HANDLE handle,
491                                 LPCSTR key)
492 {
493         LPSTR buffer = NULL;
494         DWORD needed = 0;
495         DWORD err = 0;
496         char tmp[1024];
497
498         torture_comment(tctx, "Testing EnumPrinterKey(%s)", key);
499
500         err = EnumPrinterKey(handle, key, NULL, 0, &needed);
501         if (err == ERROR_MORE_DATA) {
502                 buffer = (LPTSTR)malloc(needed);
503                 torture_assert(tctx, buffer, "malloc failed");
504                 err = EnumPrinterKey(handle, key, buffer, needed, &needed);
505         }
506         if (err) {
507                 sprintf(tmp, "EnumPrinterKey(%s) failed on [%s] (buffer size = %d), error: %s\n",
508                         key, servername, needed, errstr(err));
509                 torture_fail(tctx, tmp);
510         }
511
512         if (tctx->print) {
513                 print_printer_keys(buffer);
514         }
515
516         free(buffer);
517
518         return TRUE;
519 }
520
521 /****************************************************************************
522 ****************************************************************************/
523
524 static BOOL test_GetPrinter(struct torture_context *tctx,
525                             LPSTR printername,
526                             HANDLE handle)
527 {
528         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 7, 8 };
529         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
530         DWORD i;
531         LPBYTE buffer = NULL;
532
533         for (i=0; i < ARRAY_SIZE(levels); i++) {
534
535                 DWORD needed = 0;
536                 DWORD err = 0;
537                 char tmp[1024];
538
539                 torture_comment(tctx, "Testing GetPrinter level %d", levels[i]);
540
541                 GetPrinter(handle, levels[i], NULL, 0, &needed);
542                 err = GetLastError();
543                 if (err == ERROR_INSUFFICIENT_BUFFER) {
544                         err = 0;
545                         buffer = malloc(needed);
546                         torture_assert(tctx, buffer, "malloc failed");
547                         if (!GetPrinter(handle, levels[i], buffer, needed, &needed)) {
548                                 err = GetLastError();
549                         }
550                 }
551                 if (err) {
552                         sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
553                                 levels[i], printername, needed, errstr(err));
554                         if (success[i]) {
555                                 torture_fail(tctx, tmp);
556                         } else {
557                                 torture_warning(tctx, tmp);
558                         }
559                 }
560
561                 if (tctx->print) {
562                         print_printer_info_bylevel(levels[i], buffer, 1);
563                 }
564
565                 free(buffer);
566                 buffer = NULL;
567         }
568
569         return TRUE;
570 }
571
572 /****************************************************************************
573 ****************************************************************************/
574
575 static BOOL test_GetPrinterDriver(struct torture_context *tctx,
576                                   LPSTR printername,
577                                   LPSTR architecture,
578                                   HANDLE handle)
579 {
580         DWORD levels[]  = { 1, 2, 3, 4, 5, 6, 8 };
581         DWORD success[] = { 1, 1, 1, 1, 1, 1, 1 };
582         DWORD i;
583         LPBYTE buffer = NULL;
584
585         for (i=0; i < ARRAY_SIZE(levels); i++) {
586
587                 DWORD needed = 0;
588                 DWORD err = 0;
589                 char tmp[1024];
590
591                 torture_comment(tctx, "Testing GetPrinterDriver level %d", levels[i]);
592
593                 GetPrinterDriver(handle, architecture, levels[i], NULL, 0, &needed);
594                 err = GetLastError();
595                 if (err == ERROR_INSUFFICIENT_BUFFER) {
596                         err = 0;
597                         buffer = malloc(needed);
598                         torture_assert(tctx, buffer, "malloc failed");
599                         if (!GetPrinterDriver(handle, architecture, levels[i], buffer, needed, &needed)) {
600                                 err = GetLastError();
601                         }
602                 }
603                 if (err) {
604                         sprintf(tmp, "GetPrinterDriver failed level %d on [%s] (buffer size = %d), error: %s\n",
605                                 levels[i], printername, needed, errstr(err));
606                         if (success[i]) {
607                                 torture_fail(tctx, tmp);
608                         } else {
609                                 torture_warning(tctx, tmp);
610                         }
611                 }
612
613                 if (tctx->print) {
614                         print_driver_info_bylevel(levels[i], buffer, 1);
615                 }
616
617                 free(buffer);
618                 buffer = NULL;
619         }
620
621         return TRUE;
622 }
623
624
625 /****************************************************************************
626 ****************************************************************************/
627
628 static BOOL test_EnumJobs(struct torture_context *tctx,
629                           LPSTR printername,
630                           HANDLE handle)
631 {
632         DWORD levels[]  = { 1, 2, 3, 4 };
633         DWORD success[] = { 1, 1, 1, 1 };
634         DWORD i;
635         LPBYTE buffer = NULL;
636
637         for (i=0; i < ARRAY_SIZE(levels); i++) {
638
639                 DWORD needed = 0;
640                 DWORD returned = 0;
641                 DWORD err = 0;
642                 char tmp[1024];
643
644                 torture_comment(tctx, "Testing EnumJobs level %d", levels[i]);
645
646                 if (tctx->samba3 && levels[i] == 4) {
647                         torture_comment(tctx, "skipping level %d enum against samba\n", levels[i]);
648                         continue;
649                 }
650
651                 EnumJobs(handle, 0, 100, levels[i], NULL, 0, &needed, &returned);
652                 err = GetLastError();
653                 if (err == ERROR_INSUFFICIENT_BUFFER) {
654                         err = 0;
655                         buffer = malloc(needed);
656                         torture_assert(tctx, buffer, "malloc failed");
657                         if (!EnumJobs(handle, 0, 100, levels[i], buffer, needed, &needed, &returned)) {
658                                 err = GetLastError();
659                         }
660                 }
661                 if (err) {
662                         sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
663                                 levels[i], printername, needed, errstr(err));
664                         if (success[i]) {
665                                 torture_fail(tctx, tmp);
666                         } else {
667                                 torture_warning(tctx, tmp);
668                         }
669                 }
670
671                 if (tctx->print) {
672                         print_job_info_bylevel(levels[i], buffer, returned);
673                 }
674
675                 free(buffer);
676                 buffer = NULL;
677         }
678
679         return TRUE;
680 }
681
682 /****************************************************************************
683 ****************************************************************************/
684
685 static BOOL test_EnumPrinterDataEx(struct torture_context *tctx,
686                                    LPSTR servername,
687                                    LPSTR keyname,
688                                    HANDLE handle,
689                                    LPBYTE *buffer_p,
690                                    DWORD *returned_p)
691 {
692         LPBYTE buffer = NULL;
693         DWORD needed = 0;
694         DWORD returned = 0;
695         DWORD err = 0;
696         char tmp[1024];
697
698         torture_comment(tctx, "Testing EnumPrinterDataEx(%s)", keyname);
699
700         err = EnumPrinterDataEx(handle, keyname, NULL, 0, &needed, &returned);
701         if (err == ERROR_MORE_DATA) {
702                 buffer = malloc(needed);
703                 torture_assert(tctx, buffer, "malloc failed");
704                 err = EnumPrinterDataEx(handle, keyname, buffer, needed, &needed, &returned);
705         }
706         if (err) {
707                 sprintf(tmp, "EnumPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
708                         keyname, servername, needed, errstr(err));
709                 torture_fail(tctx, tmp);
710         }
711
712         if (tctx->print) {
713                 DWORD i;
714                 LPPRINTER_ENUM_VALUES v = (LPPRINTER_ENUM_VALUES)buffer;
715                 for (i=0; i < returned; i++) {
716                         print_printer_enum_values(&v[i]);
717                 }
718         }
719
720         if (returned_p) {
721                 *returned_p = returned;
722         }
723
724         if (buffer_p) {
725                 *buffer_p = buffer;
726         } else {
727                 free(buffer);
728         }
729
730         return TRUE;
731 }
732
733 /****************************************************************************
734 ****************************************************************************/
735
736 static BOOL test_devicemode_equal(struct torture_context *tctx,
737                                   const DEVMODE *d1,
738                                   const DEVMODE *d2)
739 {
740         if (d1 == d2) {
741                 return TRUE;
742         }
743
744         if (!d1 || !d2) {
745                 torture_comment(tctx, "%s\n", __location__);
746                 return FALSE;
747         }
748
749         torture_assert_str_equal(tctx, (const char *)d1->dmDeviceName, (const char *)d2->dmDeviceName, "dmDeviceName mismatch");
750         torture_assert_int_equal(tctx, d1->dmSpecVersion, d2->dmSpecVersion, "dmSpecVersion mismatch");
751         torture_assert_int_equal(tctx, d1->dmDriverVersion, d2->dmDriverVersion, "dmDriverVersion mismatch");
752         torture_assert_int_equal(tctx, d1->dmSize, d2->dmSize, "size mismatch");
753         torture_assert_int_equal(tctx, d1->dmDriverExtra, d2->dmDriverExtra, "dmDriverExtra mismatch");
754         torture_assert_int_equal(tctx, d1->dmFields, d2->dmFields, "dmFields mismatch");
755
756         torture_assert_int_equal(tctx, d1->dmOrientation, d2->dmOrientation, "dmOrientation mismatch");
757         torture_assert_int_equal(tctx, d1->dmPaperSize, d2->dmPaperSize, "dmPaperSize mismatch");
758         torture_assert_int_equal(tctx, d1->dmPaperLength, d2->dmPaperLength, "dmPaperLength mismatch");
759         torture_assert_int_equal(tctx, d1->dmPaperWidth, d2->dmPaperWidth, "dmPaperWidth mismatch");
760         torture_assert_int_equal(tctx, d1->dmScale, d2->dmScale, "dmScale mismatch");
761         torture_assert_int_equal(tctx, d1->dmCopies, d2->dmCopies, "dmCopies mismatch");
762         torture_assert_int_equal(tctx, d1->dmDefaultSource, d2->dmDefaultSource, "dmDefaultSource mismatch");
763         torture_assert_int_equal(tctx, d1->dmPrintQuality, d2->dmPrintQuality, "dmPrintQuality mismatch");
764
765         torture_assert_int_equal(tctx, d1->dmColor, d2->dmColor, "dmColor mismatch");
766         torture_assert_int_equal(tctx, d1->dmDuplex, d2->dmDuplex, "dmDuplex mismatch");
767         torture_assert_int_equal(tctx, d1->dmYResolution, d2->dmYResolution, "dmYResolution mismatch");
768         torture_assert_int_equal(tctx, d1->dmTTOption, d2->dmTTOption, "dmTTOption mismatch");
769         torture_assert_int_equal(tctx, d1->dmCollate, d2->dmCollate, "dmCollate mismatch");
770         torture_assert_str_equal(tctx, (const char *)d1->dmFormName, (const char *)d2->dmFormName, "dmFormName mismatch");
771         torture_assert_int_equal(tctx, d1->dmLogPixels, d2->dmLogPixels, "dmLogPixels mismatch");
772         torture_assert_int_equal(tctx, d1->dmBitsPerPel, d2->dmBitsPerPel, "dmBitsPerPel mismatch");
773         torture_assert_int_equal(tctx, d1->dmPelsWidth, d2->dmPelsWidth, "dmPelsWidth mismatch");
774         torture_assert_int_equal(tctx, d1->dmPelsHeight, d2->dmPelsHeight, "dmPelsHeight mismatch");
775
776         torture_assert_int_equal(tctx, d1->dmDisplayFlags, d2->dmDisplayFlags, "dmDisplayFlags mismatch");
777         /* or dmNup ? */
778         torture_assert_int_equal(tctx, d1->dmDisplayFrequency, d2->dmDisplayFrequency, "dmDisplayFrequency mismatch");
779
780         torture_assert_int_equal(tctx, d1->dmICMMethod, d2->dmICMMethod, "dmICMMethod mismatch");
781         torture_assert_int_equal(tctx, d1->dmICMIntent, d2->dmICMIntent, "dmICMIntent mismatch");
782         torture_assert_int_equal(tctx, d1->dmMediaType, d2->dmMediaType, "dmMediaType mismatch");
783         torture_assert_int_equal(tctx, d1->dmDitherType, d2->dmDitherType, "dmDitherType mismatch");
784         torture_assert_int_equal(tctx, d1->dmReserved1, d2->dmReserved1, "dmReserved1 mismatch");
785         torture_assert_int_equal(tctx, d1->dmReserved2, d2->dmReserved2, "reserved2 mismatch");
786
787         torture_assert_int_equal(tctx, d1->dmPanningWidth, d2->dmPanningWidth, "dmPanningWidth mismatch");
788         torture_assert_int_equal(tctx, d1->dmPanningHeight, d2->dmPanningHeight, "dmPanningHeight mismatch");
789
790         /* torture_assert_mem_equal(tctx, d1 + d1->dmSize, d2 + d2->dmSize, d1->dmDriverExtra, "private extra data mismatch"); */
791
792         return TRUE;
793 }
794
795 /****************************************************************************
796 ****************************************************************************/
797
798 static BOOL test_DeviceModes(struct torture_context *tctx,
799                              LPSTR printername,
800                              HANDLE handle)
801 {
802         PPRINTER_INFO_2 info2 = NULL;
803         PPRINTER_INFO_8 info8 = NULL;
804         DWORD needed = 0;
805         DWORD err = 0;
806         char tmp[1024];
807
808         torture_comment(tctx, "Testing DeviceModes");
809
810         torture_comment(tctx, "Testing GetPrinter level %d", 2);
811
812         GetPrinter(handle, 2, NULL, 0, &needed);
813         err = GetLastError();
814         if (err == ERROR_INSUFFICIENT_BUFFER) {
815                 err = 0;
816                 info2 = (PPRINTER_INFO_2)malloc(needed);
817                 torture_assert(tctx, (LPBYTE)info2, "malloc failed");
818                 if (!GetPrinter(handle, 2, (LPBYTE)info2, needed, &needed)) {
819                         err = GetLastError();
820                 }
821         }
822         if (err) {
823                 sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
824                         2, printername, needed, errstr(err));
825                 torture_fail(tctx, tmp);
826         }
827
828         if (tctx->print) {
829                 print_printer_info_2(info2);
830         }
831
832         torture_comment(tctx, "Testing GetPrinter level %d", 8);
833
834         GetPrinter(handle, 8, NULL, 0, &needed);
835         err = GetLastError();
836         if (err == ERROR_INSUFFICIENT_BUFFER) {
837                 err = 0;
838                 info8 = (PPRINTER_INFO_8)malloc(needed);
839                 torture_assert(tctx, (LPBYTE)info8, "malloc failed");
840                 if (!GetPrinter(handle, 8, (LPBYTE)info8, needed, &needed)) {
841                         err = GetLastError();
842                 }
843         }
844         if (err) {
845                 sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
846                         8, printername, needed, errstr(err));
847                 torture_fail(tctx, tmp);
848         }
849
850         if (tctx->print) {
851                 print_printer_info_8(info8);
852         }
853
854         torture_assert(tctx, test_devicemode_equal(tctx, info2->pDevMode, info8->pDevMode), "");
855
856         free(info2);
857         free(info8);
858
859         return TRUE;
860 }
861
862 /****************************************************************************
863 ****************************************************************************/
864
865 static BOOL test_GetJob(struct torture_context *tctx,
866                         LPSTR printername,
867                         HANDLE handle,
868                         DWORD job_id)
869 {
870         DWORD levels[]  = { 1, 2, 3, 4 };
871         DWORD success[] = { 1, 1, 1, 1 };
872         DWORD i;
873         LPBYTE buffer = NULL;
874
875         for (i=0; i < ARRAY_SIZE(levels); i++) {
876
877                 DWORD needed = 0;
878                 DWORD err = 0;
879                 char tmp[1024];
880
881                 torture_comment(tctx, "Testing GetJob(%d) level %d", job_id, levels[i]);
882
883                 if (tctx->samba3 && (levels[i] == 4) || (levels[i] == 3)) {
884                         torture_comment(tctx, "skipping level %d getjob against samba\n", levels[i]);
885                         continue;
886                 }
887
888                 GetJob(handle, job_id, levels[i], NULL, 0, &needed);
889                 err = GetLastError();
890                 if (err == ERROR_INSUFFICIENT_BUFFER) {
891                         err = 0;
892                         buffer = malloc(needed);
893                         torture_assert(tctx, buffer, "malloc failed");
894                         if (!GetJob(handle, job_id, levels[i], buffer, needed, &needed)) {
895                                 err = GetLastError();
896                         }
897                 }
898                 if (err) {
899                         sprintf(tmp, "GetJob failed level %d on [%s] (buffer size = %d), error: %s\n",
900                                 levels[i], printername, needed, errstr(err));
901                         if (success[i]) {
902                                 torture_fail(tctx, tmp);
903                         } else {
904                                 torture_warning(tctx, tmp);
905                         }
906                 }
907
908                 if (tctx->print) {
909                         print_job_info_bylevel(levels[i], buffer, 1);
910                 }
911
912                 free(buffer);
913                 buffer = NULL;
914         }
915
916         return TRUE;
917 }
918
919 /****************************************************************************
920 ****************************************************************************/
921
922 static BOOL test_EachJob(struct torture_context *tctx,
923                          LPSTR printername,
924                          HANDLE handle)
925 {
926         DWORD i;
927         PJOB_INFO_1 buffer = NULL;
928         DWORD needed = 0;
929         DWORD returned = 0;
930         DWORD err = 0;
931         DWORD level = 1;
932         char tmp[1024];
933         BOOL ret = TRUE;
934
935         torture_comment(tctx, "Testing Each PrintJob %d");
936
937         EnumJobs(handle, 0, 100, level, NULL, 0, &needed, &returned);
938         err = GetLastError();
939         if (err == ERROR_INSUFFICIENT_BUFFER) {
940                 err = 0;
941                 buffer = (PJOB_INFO_1)malloc(needed);
942                 torture_assert(tctx, buffer, "malloc failed");
943                 if (!EnumJobs(handle, 0, 100, level, (LPBYTE)buffer, needed, &needed, &returned)) {
944                         err = GetLastError();
945                 }
946         }
947         if (err) {
948                 sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
949                         level, printername, needed, errstr(err));
950                 torture_fail(tctx, tmp);
951         }
952
953         if (tctx->print) {
954                 print_job_info_bylevel(level, (LPBYTE)buffer, returned);
955         }
956
957         for (i=0; i < returned; i++) {
958                 ret = test_GetJob(tctx, printername, handle, buffer[i].JobId);
959         }
960
961         free(buffer);
962
963         return ret;
964
965 }
966
967 /****************************************************************************
968 ****************************************************************************/
969
970 static BOOL test_OnePrinter(struct torture_context *tctx,
971                             LPSTR printername,
972                             LPSTR architecture,
973                             LPPRINTER_DEFAULTS defaults)
974 {
975         HANDLE handle;
976         BOOL ret = TRUE;
977
978         torture_comment(tctx, "Testing Printer %s", printername);
979
980         ret &= test_OpenPrinter(tctx, printername, defaults, &handle);
981         ret &= test_GetPrinter(tctx, printername, handle);
982         ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
983         ret &= test_EnumForms(tctx, printername, handle);
984         ret &= test_EnumJobs(tctx, printername, handle);
985         ret &= test_EachJob(tctx, printername, handle);
986         ret &= test_EnumPrinterKey(tctx, printername, handle, "");
987         ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
988         ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL);
989         ret &= test_DeviceModes(tctx, printername, handle);
990         ret &= test_PrinterData(tctx, printername, handle);
991         ret &= test_ClosePrinter(tctx, handle);
992
993         return ret;
994 }
995
996 /****************************************************************************
997 ****************************************************************************/
998
999 static BOOL test_EachPrinter(struct torture_context *tctx,
1000                              LPSTR servername,
1001                              LPSTR architecture,
1002                              LPPRINTER_DEFAULTS defaults)
1003 {
1004         DWORD needed = 0;
1005         DWORD returned = 0;
1006         DWORD err = 0;
1007         char tmp[1024];
1008         DWORD i;
1009         DWORD flags = PRINTER_ENUM_NAME;
1010         PPRINTER_INFO_1 buffer = NULL;
1011         BOOL ret = TRUE;
1012
1013         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
1014
1015         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
1016         err = GetLastError();
1017         if (err == ERROR_INSUFFICIENT_BUFFER) {
1018                 err = 0;
1019                 buffer = (PPRINTER_INFO_1)malloc(needed);
1020                 torture_assert(tctx, buffer, "malloc failed");
1021                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
1022                         err = GetLastError();
1023                 }
1024         }
1025         if (err) {
1026                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
1027                         1, servername, needed, errstr(err));
1028                 torture_fail(tctx, tmp);
1029         }
1030
1031         for (i=0; i < returned; i++) {
1032                 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
1033         }
1034
1035         free(buffer);
1036
1037         return ret;
1038 }
1039
1040 /****************************************************************************
1041 ****************************************************************************/
1042
1043 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
1044                                             LPSTR servername,
1045                                             LPSTR architecture)
1046 {
1047         DWORD levels[]  = { 1 };
1048         DWORD success[] = { 1 };
1049         DWORD i;
1050         LPBYTE buffer = NULL;
1051
1052         for (i=0; i < ARRAY_SIZE(levels); i++) {
1053
1054                 DWORD needed = 0;
1055                 DWORD err = 0;
1056                 char tmp[1024];
1057
1058                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
1059
1060                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
1061                 err = GetLastError();
1062                 if (err == ERROR_INSUFFICIENT_BUFFER) {
1063                         err = 0;
1064                         buffer = malloc(needed);
1065                         torture_assert(tctx, buffer, "malloc failed");
1066                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
1067                                 err = GetLastError();
1068                         }
1069                 }
1070                 if (err) {
1071                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
1072                                 levels[i], servername, needed, errstr(err));
1073                         if (success[i]) {
1074                                 torture_fail(tctx, tmp);
1075                         } else {
1076                                 torture_warning(tctx, tmp);
1077                         }
1078                 }
1079
1080                 if (tctx->print) {
1081                         printf("\tPrint Processor Directory\t= %s\n\n", (LPSTR)buffer);
1082                 }
1083
1084                 free(buffer);
1085                 buffer = NULL;
1086         }
1087
1088         return TRUE;
1089 }
1090
1091 /****************************************************************************
1092 ****************************************************************************/
1093
1094 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
1095                                            LPSTR servername,
1096                                            LPSTR architecture)
1097 {
1098         DWORD levels[]  = { 1 };
1099         DWORD success[] = { 1 };
1100         DWORD i;
1101         LPBYTE buffer = NULL;
1102
1103         for (i=0; i < ARRAY_SIZE(levels); i++) {
1104
1105                 DWORD needed = 0;
1106                 DWORD err = 0;
1107                 char tmp[1024];
1108
1109                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
1110
1111                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
1112                 err = GetLastError();
1113                 if (err == ERROR_INSUFFICIENT_BUFFER) {
1114                         err = 0;
1115                         buffer = malloc(needed);
1116                         torture_assert(tctx, buffer, "malloc failed");
1117                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
1118                                 err = GetLastError();
1119                         }
1120                 }
1121                 if (err) {
1122                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
1123                                 levels[i], servername, needed, errstr(err));
1124                         if (success[i]) {
1125                                 torture_fail(tctx, tmp);
1126                         } else {
1127                                 torture_warning(tctx, tmp);
1128                         }
1129                 }
1130
1131                 if (tctx->print) {
1132                         printf("\tPrinter Driver Directory\t= %s\n\n", (LPSTR)buffer);
1133                 }
1134
1135                 free(buffer);
1136                 buffer = NULL;
1137         }
1138
1139         return TRUE;
1140 }
1141
1142 /****************************************************************************
1143 ****************************************************************************/
1144
1145 static BOOL test_GetPrinterData(struct torture_context *tctx,
1146                                 LPSTR servername,
1147                                 LPSTR valuename,
1148                                 HANDLE handle,
1149                                 DWORD *type_p,
1150                                 LPBYTE *buffer_p,
1151                                 DWORD *size_p)
1152 {
1153         LPBYTE buffer = NULL;
1154         DWORD needed = 0;
1155         DWORD type;
1156         DWORD err = 0;
1157         char tmp[1024];
1158
1159         torture_comment(tctx, "Testing GetPrinterData(%s)", valuename);
1160
1161         err = GetPrinterData(handle, valuename, &type, NULL, 0, &needed);
1162         if (err == ERROR_MORE_DATA) {
1163                 buffer = (LPBYTE)malloc(needed);
1164                 torture_assert(tctx, buffer, "malloc failed");
1165                 err = GetPrinterData(handle, valuename, &type, buffer, needed, &needed);
1166         }
1167         if (err) {
1168                 sprintf(tmp, "GetPrinterData(%s) failed on [%s] (buffer size = %d), error: %s\n",
1169                         valuename, servername, needed, errstr(err));
1170                 torture_fail(tctx, tmp);
1171         }
1172
1173         if (tctx->print) {
1174                 print_printer_data("PrinterDriverData", valuename, needed, buffer, type);
1175         }
1176
1177         if (type_p) {
1178                 *type_p = type;
1179         }
1180
1181         if (size_p) {
1182                 *size_p = needed;
1183         }
1184
1185         if (buffer_p) {
1186                 *buffer_p = buffer;
1187         } else {
1188                 free(buffer);
1189         }
1190
1191         return TRUE;
1192 }
1193
1194 /****************************************************************************
1195 ****************************************************************************/
1196
1197 static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
1198                                   LPSTR servername,
1199                                   LPSTR keyname,
1200                                   LPSTR valuename,
1201                                   HANDLE handle,
1202                                   DWORD *type_p,
1203                                   LPBYTE *buffer_p,
1204                                   DWORD *size_p)
1205 {
1206         LPBYTE buffer = NULL;
1207         DWORD needed = 0;
1208         DWORD type;
1209         DWORD err = 0;
1210         char tmp[1024];
1211
1212         torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)", keyname, valuename);
1213
1214         err = GetPrinterDataEx(handle, keyname, valuename, &type, NULL, 0, &needed);
1215         if (err == ERROR_MORE_DATA) {
1216                 buffer = (LPBYTE)malloc(needed);
1217                 torture_assert(tctx, buffer, "malloc failed");
1218                 err = GetPrinterDataEx(handle, keyname, valuename, &type, buffer, needed, &needed);
1219         }
1220         if (err) {
1221                 sprintf(tmp, "GetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
1222                         valuename, servername, needed, errstr(err));
1223                 torture_fail(tctx, tmp);
1224         }
1225
1226         if (tctx->print) {
1227                 print_printer_data(keyname, valuename, needed, buffer, type);
1228         }
1229
1230         if (type_p) {
1231                 *type_p = type;
1232         }
1233
1234         if (size_p) {
1235                 *size_p = needed;
1236         }
1237
1238         if (buffer_p) {
1239                 *buffer_p = buffer;
1240         } else {
1241                 free(buffer);
1242         }
1243
1244         return TRUE;
1245 }
1246
1247 /****************************************************************************
1248 ****************************************************************************/
1249
1250 static BOOL test_DeletePrinterDataEx(struct torture_context *tctx,
1251                                      LPSTR servername,
1252                                      LPSTR keyname,
1253                                      LPSTR valuename,
1254                                      HANDLE handle)
1255 {
1256         DWORD err = 0;
1257         char tmp[1024];
1258
1259         torture_comment(tctx, "Testing DeletePrinterDataEx(%s - %s)", keyname, valuename);
1260
1261         err = DeletePrinterDataEx(handle, keyname, valuename);
1262         if (err) {
1263                 sprintf(tmp, "DeletePrinterDataEx(%s - %s) failed on [%s], error: %s\n",
1264                         keyname, valuename, servername, errstr(err));
1265                 torture_fail(tctx, tmp);
1266         }
1267
1268         return TRUE;
1269 }
1270
1271 /****************************************************************************
1272 ****************************************************************************/
1273
1274 static BOOL test_DeletePrinterKey(struct torture_context *tctx,
1275                                   LPSTR servername,
1276                                   LPSTR keyname,
1277                                   HANDLE handle)
1278 {
1279         DWORD err = 0;
1280         char tmp[1024];
1281
1282         torture_comment(tctx, "Testing DeletePrinterKey(%s)", keyname);
1283
1284         err = DeletePrinterKey(handle, keyname);
1285         if (err) {
1286                 sprintf(tmp, "DeletePrinterKey(%s) failed on [%s], error: %s\n",
1287                         keyname, servername, errstr(err));
1288                 torture_fail(tctx, tmp);
1289         }
1290
1291         return TRUE;
1292 }
1293
1294 /****************************************************************************
1295 ****************************************************************************/
1296
1297 static BOOL test_SetPrinterDataEx(struct torture_context *tctx,
1298                                   LPSTR servername,
1299                                   LPSTR keyname,
1300                                   LPSTR valuename,
1301                                   HANDLE handle,
1302                                   DWORD type,
1303                                   LPBYTE buffer,
1304                                   DWORD offered)
1305 {
1306         DWORD err = 0;
1307         char tmp[1024];
1308
1309         torture_comment(tctx, "Testing SetPrinterDataEx(%s - %s)", keyname, valuename);
1310
1311         err = SetPrinterDataEx(handle, keyname, valuename, type, buffer, offered);
1312         if (err) {
1313                 sprintf(tmp, "SetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
1314                         valuename, servername, offered, errstr(err));
1315                 torture_fail(tctx, tmp);
1316         }
1317
1318         return TRUE;
1319 }
1320
1321 /****************************************************************************
1322 ****************************************************************************/
1323
1324 static BOOL test_PrinterData_Server(struct torture_context *tctx,
1325                                     LPSTR servername,
1326                                     HANDLE handle)
1327 {
1328         BOOL ret = TRUE;
1329         DWORD i;
1330         DWORD type, type_ex;
1331         LPBYTE buffer, buffer_ex;
1332         DWORD size, size_ex;
1333         LPSTR valuenames[] = {
1334                 SPLREG_DEFAULT_SPOOL_DIRECTORY,
1335                 SPLREG_MAJOR_VERSION,
1336                 SPLREG_MINOR_VERSION,
1337                 SPLREG_DS_PRESENT,
1338                 SPLREG_DNS_MACHINE_NAME,
1339                 SPLREG_ARCHITECTURE,
1340                 SPLREG_OS_VERSION
1341         };
1342
1343         for (i=0; i < ARRAY_SIZE(valuenames); i++) {
1344                 ret &= test_GetPrinterData(tctx, servername, valuenames[i], handle, &type, &buffer, &size);
1345                 ret &= test_GetPrinterDataEx(tctx, servername, "random", valuenames[i], handle, &type_ex, &buffer_ex, &size_ex);
1346                 torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
1347                 torture_assert_int_equal(tctx, size, size_ex, "size mismatch");
1348                 torture_assert_mem_equal(tctx, buffer, buffer_ex, size, "buffer mismatch");
1349                 free(buffer);
1350                 free(buffer_ex);
1351         }
1352
1353         return ret;
1354 }
1355
1356 /****************************************************************************
1357 ****************************************************************************/
1358
1359 static BOOL PrinterDataEqual(struct torture_context *tctx,
1360                              DWORD type1, DWORD type2,
1361                              DWORD size1, DWORD size2,
1362                              LPBYTE buffer1, LPBYTE buffer2)
1363 {
1364         torture_assert_int_equal(tctx, type1, type2, "type mismatch");
1365         torture_assert_int_equal(tctx, size1, size2, "size mismatch");
1366         torture_assert_mem_equal(tctx, buffer1, buffer2, size1, "buffer mismatch");
1367
1368         return TRUE;
1369 }
1370
1371 /****************************************************************************
1372 ****************************************************************************/
1373
1374 static BOOL test_PrinterData(struct torture_context *tctx,
1375                              LPSTR printername,
1376                              HANDLE handle)
1377 {
1378         char tmp[1024];
1379         LPSTR keyname = "torture_key";
1380         LPSTR valuename = "torture_value";
1381         BOOL ret = TRUE;
1382         DWORD types[] = {
1383                 REG_SZ,
1384                 REG_DWORD,
1385                 REG_BINARY
1386         };
1387         DWORD value = 12345678;
1388         LPSTR str = "abcdefghijklmnopqrstuvwxzy";
1389         DWORD t, s;
1390
1391         for (t=0; t < ARRAY_SIZE(types); t++) {
1392         for (s=0; s < strlen(str); s++) {
1393
1394                 DWORD type, type_ex;
1395                 LPBYTE buffer, buffer_ex;
1396                 DWORD size, size_ex;
1397
1398                 if (types[t] == REG_DWORD) {
1399                         s = 0xffff;
1400                 }
1401
1402                 switch (types[t]) {
1403                 case REG_BINARY:
1404                         buffer = malloc(s);
1405                         memcpy(buffer, str, s);
1406                         size = s;
1407                         break;
1408                 case REG_DWORD:
1409                         buffer = malloc(4);
1410                         size = 4;
1411                         break;
1412                 case REG_SZ:
1413                         buffer = malloc(s);
1414                         memcpy(buffer, str, s);
1415                         size = s;
1416                         break;
1417                 default:
1418                         sprintf(tmp, "type %d untested\n", types[t]);
1419                         torture_fail(tctx, tmp);
1420                         break;
1421                 }
1422
1423                 type = types[t];
1424
1425                 torture_comment(tctx, "Testing PrinterData (type: %s, size: 0x%08x)", reg_type_str(type), size);
1426
1427                 torture_assert(tctx,
1428                         test_SetPrinterDataEx(tctx, printername, keyname, valuename, handle, type, buffer, size),
1429                         "failed to call SetPrinterDataEx");
1430                 torture_assert(tctx,
1431                         test_GetPrinterDataEx(tctx, printername, keyname, valuename, handle, &type_ex, &buffer_ex, &size_ex),
1432                         "failed to call GetPrinterDataEx");
1433
1434                 if (!PrinterDataEqual(tctx, type_ex, type, size_ex, size, buffer_ex, buffer)) {
1435                         torture_warning(tctx, "GetPrinterDataEx does not return the same info as we set with SetPrinterDataEx");
1436                         ret = FALSE;
1437                 }
1438                 ret &= test_DeletePrinterDataEx(tctx, printername, keyname, valuename, handle);
1439                 ret &= test_DeletePrinterKey(tctx, printername, keyname, handle);
1440
1441                 free(buffer);
1442                 free(buffer_ex);
1443         }
1444         }
1445
1446         return ret;
1447 }
1448
1449 /****************************************************************************
1450 ****************************************************************************/
1451
1452 const char *get_string_param(const char *str)
1453 {
1454         const char *p;
1455
1456         p = strchr(str, '=');
1457         if (!p) {
1458                 return NULL;
1459         }
1460
1461         return (p+1);
1462 }
1463
1464 /****************************************************************************
1465 ****************************************************************************/
1466
1467 int main(int argc, char *argv[])
1468 {
1469         BOOL ret = FALSE;
1470         LPSTR servername;
1471         LPSTR architecture = "Windows NT x86";
1472         HANDLE server_handle;
1473         PRINTER_DEFAULTS defaults_admin, defaults_use;
1474         struct torture_context *tctx;
1475         int i;
1476
1477         if (argc < 2) {
1478                 fprintf(stderr, "usage: %s <name> [print] [samba3] [architecture=ARCHITECTURE]\n\n", argv[0]);
1479                 fprintf(stderr, "\t<name>           can be a server or printer name URI\n");
1480                 fprintf(stderr, "\t[print]          will print all data that has been retrieved\n");
1481                 fprintf(stderr, "\t                 from the printserver\n");
1482                 fprintf(stderr, "\t[samba3]         will skip some tests samba servers are known\n");
1483                 fprintf(stderr, "\t                 not to have implemented\n");
1484                 fprintf(stderr, "\t[architecture=X] allows to define a specific\n");
1485                 fprintf(stderr, "\t                 architecture to test with. choose between:\n");
1486                 fprintf(stderr, "\t                 \"Windows NT x86\" or \"Windows x64\"\n");
1487                 exit(-1);
1488         }
1489
1490         tctx = malloc(sizeof(struct torture_context));
1491         if (!tctx) {
1492                 fprintf(stderr, "out of memory\n");
1493                 exit(-1);
1494         }
1495         memset(tctx, '\0', sizeof(*tctx));
1496
1497         servername = argv[1];
1498
1499         for (i=1; i < argc; i++) {
1500                 if (strcmp(argv[i], "print") == 0) {
1501                         tctx->print = TRUE;
1502                 }
1503                 if (strcmp(argv[i], "samba3") == 0) {
1504                         tctx->samba3 = TRUE;
1505                 }
1506                 if (strncmp(argv[i], "architecture", strlen("architecture")) == 0) {
1507                         architecture = get_string_param(argv[i]);
1508                 }
1509         }
1510
1511         printf("Running testsuite with architecture: %s\n", architecture);
1512
1513         defaults_admin.pDatatype = NULL;
1514         defaults_admin.pDevMode = NULL;
1515         defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
1516
1517         defaults_use.pDatatype = NULL;
1518         defaults_use.pDevMode = NULL;
1519         defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
1520
1521         if ((servername[0] == '\\') && (servername[1] == '\\')) {
1522                 LPSTR p = servername+2;
1523                 LPSTR p2;
1524                 if ((p2 = strchr(p, '\\')) != NULL) {
1525                         ret = test_OnePrinter(tctx, servername, architecture, &defaults_admin);
1526                         goto done;
1527                 }
1528         }
1529
1530         ret &= test_EnumPrinters(tctx, servername);
1531         ret &= test_EnumDrivers(tctx, servername, architecture);
1532         ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
1533 /*      ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
1534         ret &= test_PrinterData_Server(tctx, servername, server_handle);
1535         ret &= test_EnumForms(tctx, servername, server_handle);
1536         ret &= test_ClosePrinter(tctx, server_handle);
1537         ret &= test_EnumPorts(tctx, servername);
1538         ret &= test_EnumMonitors(tctx, servername);
1539         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
1540         ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
1541         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
1542         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
1543         ret &= test_EachPrinter(tctx, servername, architecture, &defaults_admin);
1544
1545  done:
1546         if (!ret) {
1547                 if (tctx->last_reason) {
1548                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
1549                 }
1550                 free(tctx);
1551                 return -1;
1552         }
1553
1554         printf("%s run successfully\n", argv[0]);
1555
1556         free(tctx);
1557         return 0;
1558 }