testprogs: add EnumPrinterData test to win32 spoolss test.
[ira/wip.git] / testprogs / win32 / spoolss / spoolss.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for spoolss rpc operations
4
5    Copyright (C) Guenther Deschner 2009-2010
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 /****************************************************************************
22 ****************************************************************************/
23
24 #include "spoolss.h"
25 #include "string.h"
26 #include "torture.h"
27
28 /****************************************************************************
29 ****************************************************************************/
30
31 static BOOL test_OpenPrinter(struct torture_context *tctx,
32                              LPSTR printername,
33                              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         ret &= test_PrinterData(tctx, printername, handle);
1056         ret &= test_PrinterDataW(tctx, printername, handle);
1057         ret &= test_ClosePrinter(tctx, handle);
1058
1059         return ret;
1060 }
1061
1062 /****************************************************************************
1063 ****************************************************************************/
1064
1065 static BOOL test_EachPrinter(struct torture_context *tctx,
1066                              LPSTR servername,
1067                              LPSTR architecture,
1068                              LPPRINTER_DEFAULTS defaults)
1069 {
1070         DWORD needed = 0;
1071         DWORD returned = 0;
1072         DWORD err = 0;
1073         char tmp[1024];
1074         DWORD i;
1075         DWORD flags = PRINTER_ENUM_NAME;
1076         PPRINTER_INFO_1 buffer = NULL;
1077         BOOL ret = TRUE;
1078
1079         torture_comment(tctx, "Testing EnumPrinters level %d", 1);
1080
1081         EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
1082         err = GetLastError();
1083         if (err == ERROR_INSUFFICIENT_BUFFER) {
1084                 err = 0;
1085                 buffer = (PPRINTER_INFO_1)malloc(needed);
1086                 torture_assert(tctx, buffer, "malloc failed");
1087                 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
1088                         err = GetLastError();
1089                 }
1090         }
1091         if (err) {
1092                 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
1093                         1, servername, needed, errstr(err));
1094                 torture_fail(tctx, tmp);
1095         }
1096
1097         for (i=0; i < returned; i++) {
1098                 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
1099         }
1100
1101         free(buffer);
1102
1103         return ret;
1104 }
1105
1106 /****************************************************************************
1107 ****************************************************************************/
1108
1109 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
1110                                             LPSTR servername,
1111                                             LPSTR architecture)
1112 {
1113         DWORD levels[]  = { 1 };
1114         DWORD success[] = { 1 };
1115         DWORD i;
1116         LPBYTE buffer = NULL;
1117
1118         for (i=0; i < ARRAY_SIZE(levels); i++) {
1119
1120                 DWORD needed = 0;
1121                 DWORD err = 0;
1122                 char tmp[1024];
1123
1124                 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
1125
1126                 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
1127                 err = GetLastError();
1128                 if (err == ERROR_INSUFFICIENT_BUFFER) {
1129                         err = 0;
1130                         buffer = malloc(needed);
1131                         torture_assert(tctx, buffer, "malloc failed");
1132                         if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
1133                                 err = GetLastError();
1134                         }
1135                 }
1136                 if (err) {
1137                         sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
1138                                 levels[i], servername, needed, errstr(err));
1139                         if (success[i]) {
1140                                 torture_fail(tctx, tmp);
1141                         } else {
1142                                 torture_warning(tctx, tmp);
1143                         }
1144                 }
1145
1146                 if (tctx->print) {
1147                         printf("\tPrint Processor Directory\t= %s\n\n", (LPSTR)buffer);
1148                 }
1149
1150                 free(buffer);
1151                 buffer = NULL;
1152         }
1153
1154         return TRUE;
1155 }
1156
1157 /****************************************************************************
1158 ****************************************************************************/
1159
1160 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
1161                                            LPSTR servername,
1162                                            LPSTR architecture)
1163 {
1164         DWORD levels[]  = { 1 };
1165         DWORD success[] = { 1 };
1166         DWORD i;
1167         LPBYTE buffer = NULL;
1168
1169         for (i=0; i < ARRAY_SIZE(levels); i++) {
1170
1171                 DWORD needed = 0;
1172                 DWORD err = 0;
1173                 char tmp[1024];
1174
1175                 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
1176
1177                 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
1178                 err = GetLastError();
1179                 if (err == ERROR_INSUFFICIENT_BUFFER) {
1180                         err = 0;
1181                         buffer = malloc(needed);
1182                         torture_assert(tctx, buffer, "malloc failed");
1183                         if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
1184                                 err = GetLastError();
1185                         }
1186                 }
1187                 if (err) {
1188                         sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
1189                                 levels[i], servername, needed, errstr(err));
1190                         if (success[i]) {
1191                                 torture_fail(tctx, tmp);
1192                         } else {
1193                                 torture_warning(tctx, tmp);
1194                         }
1195                 }
1196
1197                 if (tctx->print) {
1198                         printf("\tPrinter Driver Directory\t= %s\n\n", (LPSTR)buffer);
1199                 }
1200
1201                 free(buffer);
1202                 buffer = NULL;
1203         }
1204
1205         return TRUE;
1206 }
1207
1208 /****************************************************************************
1209 ****************************************************************************/
1210
1211 static BOOL test_GetPrinterData(struct torture_context *tctx,
1212                                 LPSTR servername,
1213                                 LPSTR valuename,
1214                                 HANDLE handle,
1215                                 DWORD *type_p,
1216                                 LPBYTE *buffer_p,
1217                                 DWORD *size_p)
1218 {
1219         LPBYTE buffer = NULL;
1220         DWORD needed = 0;
1221         DWORD type;
1222         DWORD err = 0;
1223         char tmp[1024];
1224
1225         torture_comment(tctx, "Testing GetPrinterData(%s)", valuename);
1226
1227         err = GetPrinterData(handle, valuename, &type, NULL, 0, &needed);
1228         if (err == ERROR_MORE_DATA) {
1229                 buffer = (LPBYTE)malloc(needed);
1230                 torture_assert(tctx, buffer, "malloc failed");
1231                 err = GetPrinterData(handle, valuename, &type, buffer, needed, &needed);
1232         }
1233         if (err) {
1234                 sprintf(tmp, "GetPrinterData(%s) failed on [%s] (buffer size = %d), error: %s\n",
1235                         valuename, servername, needed, errstr(err));
1236                 torture_fail(tctx, tmp);
1237         }
1238
1239         if (tctx->print) {
1240                 print_printer_data("PrinterDriverData", valuename, needed, buffer, type);
1241         }
1242
1243         if (type_p) {
1244                 *type_p = type;
1245         }
1246
1247         if (size_p) {
1248                 *size_p = needed;
1249         }
1250
1251         if (buffer_p) {
1252                 *buffer_p = buffer;
1253         } else {
1254                 free(buffer);
1255         }
1256
1257         return TRUE;
1258 }
1259
1260 /****************************************************************************
1261 ****************************************************************************/
1262
1263 static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
1264                                   LPSTR servername,
1265                                   LPSTR keyname,
1266                                   LPSTR valuename,
1267                                   HANDLE handle,
1268                                   DWORD *type_p,
1269                                   LPBYTE *buffer_p,
1270                                   DWORD *size_p)
1271 {
1272         LPBYTE buffer = NULL;
1273         DWORD needed = 0;
1274         DWORD type;
1275         DWORD err = 0;
1276         char tmp[1024];
1277
1278         torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)", keyname, valuename);
1279
1280         err = GetPrinterDataEx(handle, keyname, valuename, &type, NULL, 0, &needed);
1281         if (err == ERROR_MORE_DATA) {
1282                 buffer = (LPBYTE)malloc(needed);
1283                 torture_assert(tctx, buffer, "malloc failed");
1284                 err = GetPrinterDataEx(handle, keyname, valuename, &type, buffer, needed, &needed);
1285         }
1286         if (err) {
1287                 sprintf(tmp, "GetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
1288                         valuename, servername, needed, errstr(err));
1289                 torture_fail(tctx, tmp);
1290         }
1291
1292         if (tctx->print) {
1293                 print_printer_data(keyname, valuename, needed, buffer, type);
1294         }
1295
1296         if (type_p) {
1297                 *type_p = type;
1298         }
1299
1300         if (size_p) {
1301                 *size_p = needed;
1302         }
1303
1304         if (buffer_p) {
1305                 *buffer_p = buffer;
1306         } else {
1307                 free(buffer);
1308         }
1309
1310         return TRUE;
1311 }
1312
1313 /****************************************************************************
1314 ****************************************************************************/
1315
1316 static BOOL test_GetPrinterDataExW(struct torture_context *tctx,
1317                                    LPSTR servername,
1318                                    LPCWSTR keyname,
1319                                    LPCWSTR valuename,
1320                                    HANDLE handle,
1321                                    DWORD *type_p,
1322                                    LPBYTE *buffer_p,
1323                                    DWORD *size_p)
1324 {
1325         LPBYTE buffer = NULL;
1326         DWORD needed = 0;
1327         DWORD type;
1328         DWORD err = 0;
1329         char tmp[1024];
1330
1331         torture_comment(tctx, "Testing GetPrinterDataExW(%ls - %ls)", keyname, valuename);
1332
1333         err = GetPrinterDataExW(handle, keyname, valuename, &type, NULL, 0, &needed);
1334         if (err == ERROR_MORE_DATA) {
1335                 buffer = (LPBYTE)malloc(needed);
1336                 torture_assert(tctx, buffer, "malloc failed");
1337                 err = GetPrinterDataExW(handle, keyname, valuename, &type, buffer, needed, &needed);
1338         }
1339         if (err) {
1340                 sprintf(tmp, "GetPrinterDataExW(%ls) failed on [%s] (buffer size = %d), error: %s\n",
1341                         valuename, servername, needed, errstr(err));
1342                 torture_fail(tctx, tmp);
1343         }
1344
1345         if (tctx->print) {
1346                 print_printer_dataw(keyname, valuename, needed, buffer, type);
1347         }
1348
1349         if (type_p) {
1350                 *type_p = type;
1351         }
1352
1353         if (size_p) {
1354                 *size_p = needed;
1355         }
1356
1357         if (buffer_p) {
1358                 *buffer_p = buffer;
1359         } else {
1360                 free(buffer);
1361         }
1362
1363         return TRUE;
1364 }
1365
1366
1367 /****************************************************************************
1368 ****************************************************************************/
1369
1370 static BOOL test_DeletePrinterDataEx(struct torture_context *tctx,
1371                                      LPSTR servername,
1372                                      LPSTR keyname,
1373                                      LPSTR valuename,
1374                                      HANDLE handle)
1375 {
1376         DWORD err = 0;
1377         char tmp[1024];
1378
1379         torture_comment(tctx, "Testing DeletePrinterDataEx(%s - %s)", keyname, valuename);
1380
1381         err = DeletePrinterDataEx(handle, keyname, valuename);
1382         if (err) {
1383                 sprintf(tmp, "DeletePrinterDataEx(%s - %s) failed on [%s], error: %s\n",
1384                         keyname, valuename, servername, errstr(err));
1385                 torture_fail(tctx, tmp);
1386         }
1387
1388         return TRUE;
1389 }
1390
1391 /****************************************************************************
1392 ****************************************************************************/
1393
1394 static BOOL test_DeletePrinterDataExW(struct torture_context *tctx,
1395                                       LPSTR servername,
1396                                       LPCWSTR keyname,
1397                                       LPCWSTR valuename,
1398                                       HANDLE handle)
1399 {
1400         DWORD err = 0;
1401         char tmp[1024];
1402
1403         torture_comment(tctx, "Testing DeletePrinterDataExW(%ls - %ls)", keyname, valuename);
1404
1405         err = DeletePrinterDataExW(handle, keyname, valuename);
1406         if (err) {
1407                 sprintf(tmp, "DeletePrinterDataExW(%ls - %ls) failed on [%s], error: %s\n",
1408                         keyname, valuename, servername, errstr(err));
1409                 torture_fail(tctx, tmp);
1410         }
1411
1412         return TRUE;
1413 }
1414
1415
1416 /****************************************************************************
1417 ****************************************************************************/
1418
1419 static BOOL test_DeletePrinterKey(struct torture_context *tctx,
1420                                   LPSTR servername,
1421                                   LPSTR keyname,
1422                                   HANDLE handle)
1423 {
1424         DWORD err = 0;
1425         char tmp[1024];
1426
1427         torture_comment(tctx, "Testing DeletePrinterKey(%s)", keyname);
1428
1429         err = DeletePrinterKey(handle, keyname);
1430         if (err) {
1431                 sprintf(tmp, "DeletePrinterKey(%s) failed on [%s], error: %s\n",
1432                         keyname, servername, errstr(err));
1433                 torture_fail(tctx, tmp);
1434         }
1435
1436         return TRUE;
1437 }
1438
1439 /****************************************************************************
1440 ****************************************************************************/
1441
1442 static BOOL test_DeletePrinterKeyW(struct torture_context *tctx,
1443                                    LPSTR servername,
1444                                    LPCWSTR keyname,
1445                                    HANDLE handle)
1446 {
1447         DWORD err = 0;
1448         char tmp[1024];
1449
1450         torture_comment(tctx, "Testing DeletePrinterKeyW(%ls)", keyname);
1451
1452         err = DeletePrinterKeyW(handle, keyname);
1453         if (err) {
1454                 sprintf(tmp, "DeletePrinterKeyW(%ls) failed on [%s], error: %s\n",
1455                         keyname, servername, errstr(err));
1456                 torture_fail(tctx, tmp);
1457         }
1458
1459         return TRUE;
1460 }
1461
1462 /****************************************************************************
1463 ****************************************************************************/
1464
1465 static BOOL test_SetPrinterDataEx(struct torture_context *tctx,
1466                                   LPSTR servername,
1467                                   LPSTR keyname,
1468                                   LPSTR valuename,
1469                                   HANDLE handle,
1470                                   DWORD type,
1471                                   LPBYTE buffer,
1472                                   DWORD offered)
1473 {
1474         DWORD err = 0;
1475         char tmp[1024];
1476
1477         torture_comment(tctx, "Testing SetPrinterDataEx(%s - %s)", keyname, valuename);
1478
1479         err = SetPrinterDataEx(handle, keyname, valuename, type, buffer, offered);
1480         if (err) {
1481                 sprintf(tmp, "SetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
1482                         valuename, servername, offered, errstr(err));
1483                 torture_fail(tctx, tmp);
1484         }
1485
1486         return TRUE;
1487 }
1488
1489 /****************************************************************************
1490 ****************************************************************************/
1491
1492 static BOOL test_SetPrinterDataExW(struct torture_context *tctx,
1493                                    LPCSTR servername,
1494                                    LPCWSTR keyname,
1495                                    LPCWSTR valuename,
1496                                    HANDLE handle,
1497                                    DWORD type,
1498                                    LPBYTE buffer,
1499                                    DWORD offered)
1500 {
1501         DWORD err = 0;
1502         char tmp[1024];
1503
1504         torture_comment(tctx, "Testing SetPrinterDataExW(%ls - %ls)", keyname, valuename);
1505
1506         err = SetPrinterDataExW(handle, keyname, valuename, type, buffer, offered);
1507         if (err) {
1508                 sprintf(tmp, "SetPrinterDataExW(%ls) failed on [%s] (buffer size = %d), error: %s\n",
1509                         valuename, servername, offered, errstr(err));
1510                 torture_fail(tctx, tmp);
1511         }
1512
1513         return TRUE;
1514 }
1515
1516
1517 /****************************************************************************
1518 ****************************************************************************/
1519
1520 static BOOL test_PrinterData_Server(struct torture_context *tctx,
1521                                     LPSTR servername,
1522                                     HANDLE handle)
1523 {
1524         BOOL ret = TRUE;
1525         DWORD i;
1526         DWORD type, type_ex;
1527         LPBYTE buffer, buffer_ex;
1528         DWORD size, size_ex;
1529         LPSTR valuenames[] = {
1530                 SPLREG_DEFAULT_SPOOL_DIRECTORY,
1531                 SPLREG_MAJOR_VERSION,
1532                 SPLREG_MINOR_VERSION,
1533                 SPLREG_DS_PRESENT,
1534                 SPLREG_DNS_MACHINE_NAME,
1535                 SPLREG_ARCHITECTURE,
1536                 SPLREG_OS_VERSION
1537         };
1538
1539         for (i=0; i < ARRAY_SIZE(valuenames); i++) {
1540                 ret &= test_GetPrinterData(tctx, servername, valuenames[i], handle, &type, &buffer, &size);
1541                 ret &= test_GetPrinterDataEx(tctx, servername, "random", valuenames[i], handle, &type_ex, &buffer_ex, &size_ex);
1542                 torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
1543                 torture_assert_int_equal(tctx, size, size_ex, "size mismatch");
1544                 torture_assert_mem_equal(tctx, buffer, buffer_ex, size, "buffer mismatch");
1545                 free(buffer);
1546                 free(buffer_ex);
1547         }
1548
1549         return ret;
1550 }
1551
1552 /****************************************************************************
1553 ****************************************************************************/
1554
1555 static BOOL PrinterDataEqual(struct torture_context *tctx,
1556                              DWORD type1, DWORD type2,
1557                              DWORD size1, DWORD size2,
1558                              LPBYTE buffer1, LPBYTE buffer2)
1559 {
1560         torture_assert_int_equal(tctx, type1, type2, "type mismatch");
1561         torture_assert_int_equal(tctx, size1, size2, "size mismatch");
1562         torture_assert_mem_equal(tctx, buffer1, buffer2, size1, "buffer mismatch");
1563
1564         return TRUE;
1565 }
1566
1567 /****************************************************************************
1568 ****************************************************************************/
1569
1570 static BOOL test_PrinterData(struct torture_context *tctx,
1571                              LPSTR printername,
1572                              HANDLE handle)
1573 {
1574         char tmp[1024];
1575         LPSTR keyname = "torture_key";
1576         LPSTR valuename = "torture_value";
1577         BOOL ret = TRUE;
1578         DWORD types[] = {
1579                 REG_SZ,
1580                 REG_DWORD,
1581                 REG_BINARY
1582         };
1583         DWORD value = 12345678;
1584         LPSTR str = "abcdefghijklmnopqrstuvwxzy";
1585         DWORD t, s;
1586
1587         for (t=0; t < ARRAY_SIZE(types); t++) {
1588         for (s=0; s < strlen(str); s++) {
1589
1590                 DWORD type, type_ex;
1591                 LPBYTE buffer, buffer_ex;
1592                 DWORD size, size_ex;
1593
1594                 if (types[t] == REG_DWORD) {
1595                         s = 0xffff;
1596                 }
1597
1598                 switch (types[t]) {
1599                 case REG_BINARY:
1600                         buffer = malloc(s);
1601                         memcpy(buffer, str, s);
1602                         size = s;
1603                         break;
1604                 case REG_DWORD:
1605                         buffer = malloc(4);
1606                         memcpy(buffer, &value, 4);
1607                         size = 4;
1608                         break;
1609                 case REG_SZ:
1610                         buffer = malloc(s);
1611                         memcpy(buffer, str, s);
1612                         size = s;
1613                         break;
1614                 default:
1615                         sprintf(tmp, "type %d untested\n", types[t]);
1616                         torture_fail(tctx, tmp);
1617                         break;
1618                 }
1619
1620                 type = types[t];
1621
1622                 torture_comment(tctx, "Testing PrinterData (type: %s, size: 0x%08x)", reg_type_str(type), size);
1623
1624                 torture_assert(tctx,
1625                         test_SetPrinterDataEx(tctx, printername, keyname, valuename, handle, type, buffer, size),
1626                         "failed to call SetPrinterDataEx");
1627                 torture_assert(tctx,
1628                         test_GetPrinterDataEx(tctx, printername, keyname, valuename, handle, &type_ex, &buffer_ex, &size_ex),
1629                         "failed to call GetPrinterDataEx");
1630
1631                 if (!PrinterDataEqual(tctx, type_ex, type, size_ex, size, buffer_ex, buffer)) {
1632                         torture_warning(tctx, "GetPrinterDataEx does not return the same info as we set with SetPrinterDataEx");
1633                         ret = FALSE;
1634                 }
1635                 ret &= test_DeletePrinterDataEx(tctx, printername, keyname, valuename, handle);
1636                 ret &= test_DeletePrinterKey(tctx, printername, keyname, handle);
1637
1638                 free(buffer);
1639                 free(buffer_ex);
1640         }
1641         }
1642
1643         return ret;
1644 }
1645
1646 /****************************************************************************
1647 ****************************************************************************/
1648
1649 static BOOL test_PrinterDataW(struct torture_context *tctx,
1650                               LPSTR printername,
1651                               HANDLE handle)
1652 {
1653         char tmp[1024];
1654         LPCWSTR keyname = L"torture_key";
1655         LPCWSTR valuename = L"torture_value";
1656         BOOL ret = TRUE;
1657         DWORD types[] = {
1658                 REG_SZ,
1659                 REG_DWORD,
1660                 REG_BINARY
1661         };
1662         DWORD value = 12345678;
1663         LPSTR str = "abcdefghijklmnopqrstuvwxzy";
1664         DWORD t, s;
1665
1666         for (t=0; t < ARRAY_SIZE(types); t++) {
1667         for (s=0; s < strlen(str); s++) {
1668
1669                 DWORD type, type_ex;
1670                 LPBYTE buffer, buffer_ex;
1671                 DWORD size, size_ex;
1672
1673                 if (types[t] == REG_DWORD) {
1674                         s = 0xffff;
1675                 }
1676
1677                 switch (types[t]) {
1678                 case REG_BINARY:
1679                         buffer = malloc(s);
1680                         memcpy(buffer, str, s);
1681                         size = s;
1682                         break;
1683                 case REG_DWORD:
1684                         buffer = malloc(4);
1685                         memcpy(buffer, &value, 4);
1686                         size = 4;
1687                         break;
1688                 case REG_SZ:
1689                         buffer = malloc(s);
1690                         memcpy(buffer, str, s);
1691                         size = s;
1692                         break;
1693                 default:
1694                         sprintf(tmp, "type %d untested\n", types[t]);
1695                         torture_fail(tctx, tmp);
1696                         break;
1697                 }
1698
1699                 type = types[t];
1700
1701                 torture_comment(tctx, "Testing PrinterDataW (type: %s, size: 0x%08x)", reg_type_str(type), size);
1702
1703                 torture_assert(tctx,
1704                         test_SetPrinterDataExW(tctx, printername, keyname, valuename, handle, type, buffer, size),
1705                         "failed to call SetPrinterDataExW");
1706                 torture_assert(tctx,
1707                         test_GetPrinterDataExW(tctx, printername, keyname, valuename, handle, &type_ex, &buffer_ex, &size_ex),
1708                         "failed to call GetPrinterDataExW");
1709
1710                 if (!PrinterDataEqual(tctx, type_ex, type, size_ex, size, buffer_ex, buffer)) {
1711                         torture_warning(tctx, "GetPrinterDataExW does not return the same info as we set with SetPrinterDataExW");
1712                         ret = FALSE;
1713                 }
1714                 ret &= test_DeletePrinterDataExW(tctx, printername, keyname, valuename, handle);
1715                 ret &= test_DeletePrinterKeyW(tctx, printername, keyname, handle);
1716
1717                 free(buffer);
1718                 free(buffer_ex);
1719         }
1720         }
1721
1722         return ret;
1723 }
1724
1725 /****************************************************************************
1726 ****************************************************************************/
1727
1728 const char *get_string_param(const char *str)
1729 {
1730         const char *p;
1731
1732         p = strchr(str, '=');
1733         if (!p) {
1734                 return NULL;
1735         }
1736
1737         return (p+1);
1738 }
1739
1740 /****************************************************************************
1741 ****************************************************************************/
1742
1743 int main(int argc, char *argv[])
1744 {
1745         BOOL ret = FALSE;
1746         LPSTR servername;
1747         LPSTR architecture = "Windows NT x86";
1748         HANDLE server_handle;
1749         PRINTER_DEFAULTS defaults_admin, defaults_use;
1750         struct torture_context *tctx;
1751         int i;
1752
1753         if (argc < 2) {
1754                 fprintf(stderr, "usage: %s <name> [print] [samba3] [architecture=ARCHITECTURE]\n\n", argv[0]);
1755                 fprintf(stderr, "\t<name>           can be a server or printer name URI\n");
1756                 fprintf(stderr, "\t[print]          will print all data that has been retrieved\n");
1757                 fprintf(stderr, "\t                 from the printserver\n");
1758                 fprintf(stderr, "\t[samba3]         will skip some tests samba servers are known\n");
1759                 fprintf(stderr, "\t                 not to have implemented\n");
1760                 fprintf(stderr, "\t[architecture=X] allows to define a specific\n");
1761                 fprintf(stderr, "\t                 architecture to test with. choose between:\n");
1762                 fprintf(stderr, "\t                 \"Windows NT x86\" or \"Windows x64\"\n");
1763                 exit(-1);
1764         }
1765
1766         tctx = malloc(sizeof(struct torture_context));
1767         if (!tctx) {
1768                 fprintf(stderr, "out of memory\n");
1769                 exit(-1);
1770         }
1771         memset(tctx, '\0', sizeof(*tctx));
1772
1773         servername = argv[1];
1774
1775         for (i=1; i < argc; i++) {
1776                 if (strcmp(argv[i], "print") == 0) {
1777                         tctx->print = TRUE;
1778                 }
1779                 if (strcmp(argv[i], "samba3") == 0) {
1780                         tctx->samba3 = TRUE;
1781                 }
1782                 if (strncmp(argv[i], "architecture", strlen("architecture")) == 0) {
1783                         architecture = get_string_param(argv[i]);
1784                 }
1785         }
1786
1787         printf("Running testsuite with architecture: %s\n", architecture);
1788
1789         defaults_admin.pDatatype = NULL;
1790         defaults_admin.pDevMode = NULL;
1791         defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
1792
1793         defaults_use.pDatatype = NULL;
1794         defaults_use.pDevMode = NULL;
1795         defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
1796
1797         if ((servername[0] == '\\') && (servername[1] == '\\')) {
1798                 LPSTR p = servername+2;
1799                 LPSTR p2;
1800                 if ((p2 = strchr(p, '\\')) != NULL) {
1801                         ret = test_OnePrinter(tctx, servername, architecture, &defaults_admin);
1802                         goto done;
1803                 }
1804         }
1805
1806         ret &= test_EnumPrinters(tctx, servername);
1807         ret &= test_EnumDrivers(tctx, servername, architecture);
1808         ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
1809 /*      ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
1810         ret &= test_PrinterData_Server(tctx, servername, server_handle);
1811         ret &= test_EnumForms(tctx, servername, server_handle);
1812         ret &= test_ClosePrinter(tctx, server_handle);
1813         ret &= test_EnumPorts(tctx, servername);
1814         ret &= test_EnumMonitors(tctx, servername);
1815         ret &= test_EnumPrintProcessors(tctx, servername, architecture);
1816         ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
1817         ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
1818         ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
1819         ret &= test_EachPrinter(tctx, servername, architecture, &defaults_admin);
1820
1821  done:
1822         if (!ret) {
1823                 if (tctx->last_reason) {
1824                         fprintf(stderr, "failed: %s\n", tctx->last_reason);
1825                 }
1826                 free(tctx);
1827                 return -1;
1828         }
1829
1830         printf("%s run successfully\n", argv[0]);
1831
1832         free(tctx);
1833         return 0;
1834 }