source: trunk/samba/source/rpc_parse/parse_spoolss.c @ 26

Last change on this file since 26 was 26, checked in by Paul Smedley, 14 years ago

Updated source to 3.0.25rc1

File size: 220.9 KB
Line 
1/*
2 *  Unix SMB/CIFS implementation.
3 *  RPC Pipe client / server routines
4 *  Copyright (C) Andrew Tridgell              1992-2000,
5 *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 *  Copyright (C) Jean François Micouleau      1998-2000,
7 *  Copyright (C) Gerald Carter                2000-2002,
8 *  Copyright (C) Tim Potter                   2001-2002.
9 *
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License as published by
12 *  the Free Software Foundation; either version 2 of the License, or
13 *  (at your option) any later version.
14 * 
15 *  This program is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU General Public License for more details.
19 * 
20 *  You should have received a copy of the GNU General Public License
21 *  along with this program; if not, write to the Free Software
22 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include "includes.h"
26
27#undef DBGC_CLASS
28#define DBGC_CLASS DBGC_RPC_PARSE
29
30
31/*******************************************************************
32This should be moved in a more generic lib.
33********************************************************************/ 
34
35BOOL spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
36{
37        if(!prs_uint16("year", ps, depth, &systime->year))
38                return False;
39        if(!prs_uint16("month", ps, depth, &systime->month))
40                return False;
41        if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
42                return False;
43        if(!prs_uint16("day", ps, depth, &systime->day))
44                return False;
45        if(!prs_uint16("hour", ps, depth, &systime->hour))
46                return False;
47        if(!prs_uint16("minute", ps, depth, &systime->minute))
48                return False;
49        if(!prs_uint16("second", ps, depth, &systime->second))
50                return False;
51        if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
52                return False;
53
54        return True;
55}
56
57/*******************************************************************
58********************************************************************/ 
59
60BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
61{
62        systime->year=unixtime->tm_year+1900;
63        systime->month=unixtime->tm_mon+1;
64        systime->dayofweek=unixtime->tm_wday;
65        systime->day=unixtime->tm_mday;
66        systime->hour=unixtime->tm_hour;
67        systime->minute=unixtime->tm_min;
68        systime->second=unixtime->tm_sec;
69        systime->milliseconds=0;
70
71        return True;
72}
73
74/*******************************************************************
75reads or writes an DOC_INFO structure.
76********************************************************************/ 
77
78static BOOL smb_io_doc_info_1(const char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
79{
80        if (info_1 == NULL) return False;
81
82        prs_debug(ps, depth, desc, "smb_io_doc_info_1");
83        depth++;
84 
85        if(!prs_align(ps))
86                return False;
87       
88        if(!prs_uint32("p_docname",    ps, depth, &info_1->p_docname))
89                return False;
90        if(!prs_uint32("p_outputfile", ps, depth, &info_1->p_outputfile))
91                return False;
92        if(!prs_uint32("p_datatype",   ps, depth, &info_1->p_datatype))
93                return False;
94
95        if(!smb_io_unistr2("", &info_1->docname,    info_1->p_docname,    ps, depth))
96                return False;
97        if(!smb_io_unistr2("", &info_1->outputfile, info_1->p_outputfile, ps, depth))
98                return False;
99        if(!smb_io_unistr2("", &info_1->datatype,   info_1->p_datatype,   ps, depth))
100                return False;
101
102        return True;
103}
104
105/*******************************************************************
106reads or writes an DOC_INFO structure.
107********************************************************************/ 
108
109static BOOL smb_io_doc_info(const char *desc, DOC_INFO *info, prs_struct *ps, int depth)
110{
111        uint32 useless_ptr=0;
112       
113        if (info == NULL) return False;
114
115        prs_debug(ps, depth, desc, "smb_io_doc_info");
116        depth++;
117 
118        if(!prs_align(ps))
119                return False;
120       
121        if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
122                return False;
123       
124        if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
125                return False;
126
127        switch (info->switch_value)
128        {
129                case 1: 
130                        if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
131                                return False;
132                        break;
133                case 2:
134                        /*
135                          this is just a placeholder
136                         
137                          MSDN July 1998 says doc_info_2 is only on
138                          Windows 95, and as Win95 doesn't do RPC to print
139                          this case is nearly impossible
140                         
141                          Maybe one day with Windows for dishwasher 2037 ...
142                         
143                        */
144                        /* smb_io_doc_info_2("",&info->doc_info_2, ps, depth); */
145                        break;
146                default:
147                        DEBUG(0,("Something is obviously wrong somewhere !\n"));
148                        break;
149        }
150
151        return True;
152}
153
154/*******************************************************************
155reads or writes an DOC_INFO_CONTAINER structure.
156********************************************************************/ 
157
158static BOOL smb_io_doc_info_container(const char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
159{
160        if (cont == NULL) return False;
161
162        prs_debug(ps, depth, desc, "smb_io_doc_info_container");
163        depth++;
164 
165        if(!prs_align(ps))
166                return False;
167       
168        if(!prs_uint32("level", ps, depth, &cont->level))
169                return False;
170       
171        if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
172                return False;
173
174        return True;
175}
176
177/*******************************************************************
178reads or writes an NOTIFY OPTION TYPE structure.
179********************************************************************/ 
180
181/* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
182   structure.  The _TYPE structure is really the deferred referrants (i.e
183   the notify fields array) of the _TYPE structure. -tpot */
184
185static BOOL smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
186{
187        prs_debug(ps, depth, desc, "smb_io_notify_option_type");
188        depth++;
189 
190        if (!prs_align(ps))
191                return False;
192
193        if(!prs_uint16("type", ps, depth, &type->type))
194                return False;
195        if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
196                return False;
197        if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
198                return False;
199        if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
200                return False;
201        if(!prs_uint32("count", ps, depth, &type->count))
202                return False;
203        if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
204                return False;
205
206        return True;
207}
208
209/*******************************************************************
210reads or writes an NOTIFY OPTION TYPE DATA.
211********************************************************************/ 
212
213static BOOL smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
214{
215        int i;
216
217        prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
218        depth++;
219 
220        /* if there are no fields just return */
221        if (type->fields_ptr==0)
222                return True;
223
224        if(!prs_align(ps))
225                return False;
226
227        if(!prs_uint32("count2", ps, depth, &type->count2))
228                return False;
229       
230        if (type->count2 != type->count)
231                DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
232
233        /* parse the option type data */
234        for(i=0;i<type->count2;i++)
235                if(!prs_uint16("fields",ps,depth,&type->fields[i]))
236                        return False;
237        return True;
238}
239
240/*******************************************************************
241reads or writes an NOTIFY OPTION structure.
242********************************************************************/ 
243
244static BOOL smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
245{               
246        int i;
247       
248        prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
249        depth++;
250 
251        if(!prs_uint32("count", ps, depth, &ctr->count))
252                return False;
253
254        /* reading */
255        if (UNMARSHALLING(ps))
256                if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL)
257                        return False;
258               
259        /* the option type struct */
260        for(i=0;i<ctr->count;i++)
261                if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
262                        return False;
263
264        /* the type associated with the option type struct */
265        for(i=0;i<ctr->count;i++)
266                if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
267                        return False;
268       
269        return True;
270}
271
272/*******************************************************************
273reads or writes an NOTIFY OPTION structure.
274********************************************************************/ 
275
276static BOOL smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
277{
278        prs_debug(ps, depth, desc, "smb_io_notify_option");
279        depth++;
280       
281        if(!prs_uint32("version", ps, depth, &option->version))
282                return False;
283        if(!prs_uint32("flags", ps, depth, &option->flags))
284                return False;
285        if(!prs_uint32("count", ps, depth, &option->count))
286                return False;
287        if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
288                return False;
289       
290        /* marshalling or unmarshalling, that would work */     
291        if (option->option_type_ptr!=0) {
292                if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
293                        return False;
294        }
295        else {
296                option->ctr.type=NULL;
297                option->ctr.count=0;
298        }
299       
300        return True;
301}
302
303/*******************************************************************
304reads or writes an NOTIFY INFO DATA structure.
305********************************************************************/ 
306
307static BOOL smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
308{
309        uint32 useless_ptr=0x0FF0ADDE;
310
311        prs_debug(ps, depth, desc, "smb_io_notify_info_data");
312        depth++;
313
314        if(!prs_align(ps))
315                return False;
316        if(!prs_uint16("type",           ps, depth, &data->type))
317                return False;
318        if(!prs_uint16("field",          ps, depth, &data->field))
319                return False;
320
321        if(!prs_uint32("how many words", ps, depth, &data->size))
322                return False;
323        if(!prs_uint32("id",             ps, depth, &data->id))
324                return False;
325        if(!prs_uint32("how many words", ps, depth, &data->size))
326                return False;
327
328        switch (data->enc_type) {
329
330                /* One and two value data has two uint32 values */
331
332        case NOTIFY_ONE_VALUE:
333        case NOTIFY_TWO_VALUE:
334
335                if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
336                        return False;
337                if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
338                        return False;
339                break;
340
341                /* Pointers and strings have a string length and a
342                   pointer.  For a string the length is expressed as
343                   the number of uint16 characters plus a trailing
344                   \0\0. */
345
346        case NOTIFY_POINTER:
347
348                if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
349                        return False;
350                if(!prs_uint32("pointer", ps, depth, &useless_ptr))
351                        return False;
352
353                break;
354
355        case NOTIFY_STRING:
356
357                if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
358                        return False;
359
360                if(!prs_uint32("pointer", ps, depth, &useless_ptr))
361                        return False;
362
363                break;
364
365        case NOTIFY_SECDESC:
366                if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
367                        return False;
368                if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
369                        return False;
370               
371                break;
372
373        default:
374                DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
375                          data->enc_type));
376                break;
377        }
378
379        return True;
380}
381
382/*******************************************************************
383reads or writes an NOTIFY INFO DATA structure.
384********************************************************************/ 
385
386BOOL smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
387                                     prs_struct *ps, int depth)
388{
389        prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
390        depth++;
391       
392        if(!prs_align(ps))
393                return False;
394
395        switch(data->enc_type) {
396
397                /* No data for values */
398
399        case NOTIFY_ONE_VALUE:
400        case NOTIFY_TWO_VALUE:
401
402                break;
403
404                /* Strings start with a length in uint16s */
405
406        case NOTIFY_STRING:
407
408                if (MARSHALLING(ps))
409                        data->notify_data.data.length /= 2;
410
411                if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
412                        return False;
413
414                if (UNMARSHALLING(ps)) {
415                        data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
416                                                                data->notify_data.data.length);
417
418                        if (!data->notify_data.data.string) 
419                                return False;
420                }
421
422                if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
423                                   data->notify_data.data.length))
424                        return False;
425
426                if (MARSHALLING(ps))
427                        data->notify_data.data.length *= 2;
428
429                break;
430
431        case NOTIFY_POINTER:
432
433                if (UNMARSHALLING(ps)) {
434                        data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
435                                                                data->notify_data.data.length);
436
437                        if (!data->notify_data.data.string) 
438                                return False;
439                }
440
441                if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
442                        return False;
443
444                break;
445
446        case NOTIFY_SECDESC:   
447                if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
448                        return False;
449                if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
450                        return False;
451                break;
452
453        default:
454                DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
455                          data->enc_type));
456                break;
457        }
458
459#if 0
460        if (isvalue==False) {
461
462                /* length of string in unicode include \0 */
463                x=data->notify_data.data.length+1;
464
465                if (data->field != 16)
466                if(!prs_uint32("string length", ps, depth, &x ))
467                        return False;
468
469                if (MARSHALLING(ps)) {
470                        /* These are already in little endian format. Don't byte swap. */
471                        if (x == 1) {
472
473                                /* No memory allocated for this string
474                                   therefore following the data.string
475                                   pointer is a bad idea.  Use a pointer to
476                                   the uint32 length union member to
477                                   provide a source for a unicode NULL */
478
479                                if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2))
480                                        return False;
481                        } else {
482
483                                if (data->field == 16)
484                                        x /= 2;
485
486                                if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
487                                        return False;
488                        }
489                } else {
490
491                        /* Tallocate memory for string */
492
493                        data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
494                        if (!data->notify_data.data.string)
495                                return False;
496
497                        if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
498                                return False;
499                }
500        }
501
502#endif
503
504#if 0   /* JERRY */
505        /* Win2k does not seem to put this parse align here */
506        if(!prs_align(ps))
507                return False;
508#endif
509
510        return True;
511}
512
513/*******************************************************************
514reads or writes an NOTIFY INFO structure.
515********************************************************************/ 
516
517static BOOL smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
518{
519        int i;
520
521        prs_debug(ps, depth, desc, "smb_io_notify_info");
522        depth++;
523 
524        if(!prs_align(ps))
525                return False;
526
527        if(!prs_uint32("count", ps, depth, &info->count))
528                return False;
529        if(!prs_uint32("version", ps, depth, &info->version))
530                return False;
531        if(!prs_uint32("flags", ps, depth, &info->flags))
532                return False;
533        if(!prs_uint32("count", ps, depth, &info->count))
534                return False;
535
536        for (i=0;i<info->count;i++) {
537                if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
538                        return False;
539        }
540
541        /* now do the strings at the end of the stream */       
542        for (i=0;i<info->count;i++) {
543                if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
544                        return False;
545        }
546
547        return True;
548}
549
550/*******************************************************************
551********************************************************************/ 
552
553BOOL spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
554{
555        prs_debug(ps, depth, desc, "");
556        depth++;
557
558        if (!prs_align(ps))
559                return False;
560
561        if (!prs_uint32("size", ps, depth, &q_u->size))
562                return False;
563
564        if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
565                return False;
566        if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
567                return False;
568
569        if (!prs_uint32("build", ps, depth, &q_u->build))
570                return False;
571        if (!prs_uint32("major", ps, depth, &q_u->major))
572                return False;
573        if (!prs_uint32("minor", ps, depth, &q_u->minor))
574                return False;
575        if (!prs_uint32("processor", ps, depth, &q_u->processor))
576                return False;
577
578        if (!prs_io_unistr2("", ps, depth, q_u->client_name))
579                return False;
580        if (!prs_align(ps))
581                return False;
582
583        if (!prs_io_unistr2("", ps, depth, q_u->user_name))
584                return False;
585
586        return True;
587}
588
589/*******************************************************************
590********************************************************************/ 
591
592static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
593{
594        if (q_u==NULL)
595                return False;
596
597        prs_debug(ps, depth, desc, "spool_io_user_level");
598        depth++;
599
600        if (!prs_align(ps))
601                return False;
602
603        if (!prs_uint32("level", ps, depth, &q_u->level))
604                return False;
605       
606        switch ( q_u->level ) 
607        {       
608                case 1:
609                        if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, 
610                                sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) 
611                        {
612                                return False;
613                        }
614                        break;
615                default:
616                        return False;   
617        }       
618
619        return True;
620}
621
622/*******************************************************************
623 * read or write a DEVICEMODE struct.
624 * on reading allocate memory for the private member
625 ********************************************************************/
626
627#define DM_NUM_OPTIONAL_FIELDS          8
628
629BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
630{
631        int available_space;            /* size of the device mode left to parse */
632                                        /* only important on unmarshalling       */
633        int i = 0;
634        uint16 *unistr_buffer;
635        int j;
636                                       
637        struct optional_fields {
638                fstring         name;
639                uint32*         field;
640        } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
641                { "icmmethod",          NULL },
642                { "icmintent",          NULL },
643                { "mediatype",          NULL },
644                { "dithertype",         NULL },
645                { "reserved1",          NULL },
646                { "reserved2",          NULL },
647                { "panningwidth",       NULL },
648                { "panningheight",      NULL }
649        };
650
651        /* assign at run time to keep non-gcc compilers happy */
652
653        opt_fields[0].field = &devmode->icmmethod;
654        opt_fields[1].field = &devmode->icmintent;
655        opt_fields[2].field = &devmode->mediatype;
656        opt_fields[3].field = &devmode->dithertype;
657        opt_fields[4].field = &devmode->reserved1;
658        opt_fields[5].field = &devmode->reserved2;
659        opt_fields[6].field = &devmode->panningwidth;
660        opt_fields[7].field = &devmode->panningheight;
661               
662       
663        prs_debug(ps, depth, desc, "spoolss_io_devmode");
664        depth++;
665
666        if (UNMARSHALLING(ps)) {
667                devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
668                if (devmode->devicename.buffer == NULL)
669                        return False;
670                unistr_buffer = devmode->devicename.buffer;
671        }
672        else {
673                /* devicename is a static sized string but the buffer we set is not */
674                unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
675                memset( unistr_buffer, 0x0, MAXDEVICENAME );
676                for ( j=0; devmode->devicename.buffer[j]; j++ )
677                        unistr_buffer[j] = devmode->devicename.buffer[j];
678        }
679               
680        if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
681                return False;
682       
683        if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
684                return False;
685               
686        if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
687                return False;
688        if (!prs_uint16("size",             ps, depth, &devmode->size))
689                return False;
690        if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
691                return False;
692        if (!prs_uint32("fields",           ps, depth, &devmode->fields))
693                return False;
694        if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
695                return False;
696        if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
697                return False;
698        if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
699                return False;
700        if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
701                return False;
702        if (!prs_uint16("scale",            ps, depth, &devmode->scale))
703                return False;
704        if (!prs_uint16("copies",           ps, depth, &devmode->copies))
705                return False;
706        if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
707                return False;
708        if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
709                return False;
710        if (!prs_uint16("color",            ps, depth, &devmode->color))
711                return False;
712        if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
713                return False;
714        if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
715                return False;
716        if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
717                return False;
718        if (!prs_uint16("collate",          ps, depth, &devmode->collate))
719                return False;
720
721        if (UNMARSHALLING(ps)) {
722                devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
723                if (devmode->formname.buffer == NULL)
724                        return False;
725                unistr_buffer = devmode->formname.buffer;
726        }
727        else {
728                /* devicename is a static sized string but the buffer we set is not */
729                unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
730                memset( unistr_buffer, 0x0, MAXDEVICENAME );
731                for ( j=0; devmode->formname.buffer[j]; j++ )
732                        unistr_buffer[j] = devmode->formname.buffer[j];
733        }
734       
735        if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
736                return False;
737        if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
738                return False;
739        if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
740                return False;
741        if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
742                return False;
743        if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
744                return False;
745        if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
746                return False;
747        if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
748                return False;
749        /*
750         * every device mode I've ever seen on the wire at least has up
751         * to the displayfrequency field.   --jerry (05-09-2002)
752         */
753         
754        /* add uint32's + uint16's + two UNICODE strings */
755         
756        available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
757       
758        /* Sanity check - we only have uint32's left tp parse */
759       
760        if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
761                DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
762                        available_space, devmode->size));
763                DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
764                return False;
765        }
766
767        /*
768         * Conditional parsing.  Assume that the DeviceMode has been
769         * zero'd by the caller.
770         */
771       
772        while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
773        {
774                DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
775                if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
776                        return False;
777                available_space -= sizeof(uint32);
778                i++;
779        }       
780       
781        /* Sanity Check - we should no available space at this point unless
782           MS changes the device mode structure */
783               
784        if (available_space) {
785                DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
786                DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
787                        available_space, devmode->size));
788                DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
789                return False;
790        }
791
792
793        if (devmode->driverextra!=0) {
794                if (UNMARSHALLING(ps)) {
795                        devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
796                        if(devmode->dev_private == NULL)
797                                return False;
798                        DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); 
799                }
800                       
801                DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
802                if (!prs_uint8s(False, "dev_private",  ps, depth,
803                                devmode->dev_private, devmode->driverextra))
804                        return False;
805        }
806
807        return True;
808}
809
810/*******************************************************************
811 Read or write a DEVICEMODE container
812********************************************************************/ 
813
814static BOOL spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
815{
816        if (dm_c==NULL)
817                return False;
818
819        prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
820        depth++;
821
822        if(!prs_align(ps))
823                return False;
824       
825        if (!prs_uint32("size", ps, depth, &dm_c->size))
826                return False;
827
828        if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
829                return False;
830
831        if (dm_c->size==0 || dm_c->devmode_ptr==0) {
832                if (UNMARSHALLING(ps))
833                        /* if while reading there is no DEVMODE ... */
834                        dm_c->devmode=NULL;
835                return True;
836        }
837       
838        /* so we have a DEVICEMODE to follow */         
839        if (UNMARSHALLING(ps)) {
840                DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
841                dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1);
842                if(dm_c->devmode == NULL)
843                        return False;
844        }
845       
846        /* this is bad code, shouldn't be there */
847        if (!prs_uint32("size", ps, depth, &dm_c->size))
848                return False;
849               
850        if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
851                return False;
852
853        return True;
854}
855
856/*******************************************************************
857********************************************************************/ 
858
859static BOOL spoolss_io_printer_default(const char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
860{
861        if (pd==NULL)
862                return False;
863
864        prs_debug(ps, depth, desc, "spoolss_io_printer_default");
865        depth++;
866
867        if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
868                return False;
869
870        if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
871                return False;
872       
873        if (!prs_align(ps))
874                return False;
875
876        if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
877                return False;
878
879        if (!prs_align(ps))
880                return False;
881
882        if (!prs_uint32("access_required", ps, depth, &pd->access_required))
883                return False;
884
885        return True;
886}
887
888/*******************************************************************
889 * init a structure.
890 ********************************************************************/
891
892BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
893                const fstring printername, 
894                const fstring datatype, 
895                uint32 access_required,
896                const fstring clientname,
897                const fstring user_name)
898{
899        DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
900
901        q_u->printername = TALLOC_P( get_talloc_ctx(), UNISTR2 );
902        if (!q_u->printername) {
903                return False;
904        }
905        init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
906
907        q_u->printer_default.datatype_ptr = 0;
908
909        q_u->printer_default.devmode_cont.size=0;
910        q_u->printer_default.devmode_cont.devmode_ptr=0;
911        q_u->printer_default.devmode_cont.devmode=NULL;
912        q_u->printer_default.access_required=access_required;
913
914        q_u->user_switch = 1;
915       
916        q_u->user_ctr.level                 = 1;
917        q_u->user_ctr.user.user1            = TALLOC_P( get_talloc_ctx(), SPOOL_USER_1 );
918        if (!q_u->user_ctr.user.user1) {
919                return False;
920        }
921        q_u->user_ctr.user.user1->size      = strlen(clientname) + strlen(user_name) + 10;
922        q_u->user_ctr.user.user1->build     = 1381;
923        q_u->user_ctr.user.user1->major     = 2;
924        q_u->user_ctr.user.user1->minor     = 0;
925        q_u->user_ctr.user.user1->processor = 0;
926
927        q_u->user_ctr.user.user1->client_name = TALLOC_P( get_talloc_ctx(), UNISTR2 );
928        if (!q_u->user_ctr.user.user1->client_name) {
929                return False;
930        }
931        q_u->user_ctr.user.user1->user_name   = TALLOC_P( get_talloc_ctx(), UNISTR2 );
932        if (!q_u->user_ctr.user.user1->user_name) {
933                return False;
934        }
935
936        init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
937        init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
938       
939        return True;
940}
941
942/*******************************************************************
943 * init a structure.
944 ********************************************************************/
945
946BOOL make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
947        const char *srv_name, const char* clientname, const char* user_name,
948        uint32 level, PRINTER_INFO_CTR *ctr)
949{
950        DEBUG(5,("make_spoolss_q_addprinterex\n"));
951       
952        if (!ctr || !ctr->printers_2) 
953                return False;
954
955        ZERO_STRUCTP(q_u);
956
957        q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
958        if (!q_u->server_name) {
959                return False;
960        }
961        init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
962
963        q_u->level = level;
964       
965        q_u->info.level = level;
966        q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
967        switch (level) {
968                case 2:
969                        /* init q_u->info.info2 from *info */
970                        if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
971                                DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
972                                return False;
973                        }
974                        break;
975                default :
976                        break;
977        }
978
979        q_u->user_switch=1;
980
981        q_u->user_ctr.level                 = 1;
982        q_u->user_ctr.user.user1            = TALLOC_P( get_talloc_ctx(), SPOOL_USER_1 );
983        if (!q_u->user_ctr.user.user1) {
984                return False;
985        }
986        q_u->user_ctr.user.user1->build     = 1381;
987        q_u->user_ctr.user.user1->major     = 2; 
988        q_u->user_ctr.user.user1->minor     = 0;
989        q_u->user_ctr.user.user1->processor = 0;
990
991        q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
992        if (!q_u->user_ctr.user.user1->client_name) {
993                return False;
994        }
995        q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
996        if (!q_u->user_ctr.user.user1->user_name) {
997                return False;
998        }
999        init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
1000        init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
1001
1002        q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
1003                                   q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
1004       
1005        return True;
1006}
1007       
1008/*******************************************************************
1009create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
1010*******************************************************************/
1011
1012BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
1013                                PRINTER_INFO_2 *info)
1014{
1015
1016        SPOOL_PRINTER_INFO_LEVEL_2 *inf;
1017
1018        /* allocate the necessary memory */
1019        if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
1020                DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
1021                return False;
1022        }
1023       
1024        inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
1025        inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
1026        inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
1027        inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
1028        inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
1029        inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
1030        inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
1031        inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
1032        inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
1033        inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
1034        inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
1035        inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
1036        inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
1037        inf->attributes         = info->attributes;
1038        inf->priority           = info->priority;
1039        inf->default_priority   = info->defaultpriority;
1040        inf->starttime          = info->starttime;
1041        inf->untiltime          = info->untiltime;
1042        inf->cjobs              = info->cjobs;
1043        inf->averageppm = info->averageppm;
1044        init_unistr2_from_unistr(&inf->servername,      &info->servername);
1045        init_unistr2_from_unistr(&inf->printername,     &info->printername);
1046        init_unistr2_from_unistr(&inf->sharename,       &info->sharename);
1047        init_unistr2_from_unistr(&inf->portname,        &info->portname);
1048        init_unistr2_from_unistr(&inf->drivername,      &info->drivername);
1049        init_unistr2_from_unistr(&inf->comment,         &info->comment);
1050        init_unistr2_from_unistr(&inf->location,        &info->location);
1051        init_unistr2_from_unistr(&inf->sepfile,         &info->sepfile);
1052        init_unistr2_from_unistr(&inf->printprocessor,  &info->printprocessor);
1053        init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
1054        init_unistr2_from_unistr(&inf->parameters,      &info->parameters);
1055        init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
1056
1057        *spool_info2 = inf;
1058
1059        return True;
1060}
1061
1062/*******************************************************************
1063create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
1064*******************************************************************/
1065
1066BOOL make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, 
1067                                PRINTER_INFO_3 *info)
1068{
1069
1070        SPOOL_PRINTER_INFO_LEVEL_3 *inf;
1071
1072        /* allocate the necessary memory */
1073        if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
1074                DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
1075                return False;
1076        }
1077       
1078        inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
1079
1080        *spool_info3 = inf;
1081
1082        return True;
1083}
1084
1085/*******************************************************************
1086create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
1087*******************************************************************/
1088
1089BOOL make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, 
1090                                PRINTER_INFO_7 *info)
1091{
1092
1093        SPOOL_PRINTER_INFO_LEVEL_7 *inf;
1094
1095        /* allocate the necessary memory */
1096        if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
1097                DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
1098                return False;
1099        }
1100
1101        inf->guid_ptr           = (info->guid.buffer!=NULL)?1:0;
1102        inf->action             = info->action;
1103        init_unistr2_from_unistr(&inf->guid,            &info->guid);
1104
1105        *spool_info7 = inf;
1106
1107        return True;
1108}
1109
1110
1111/*******************************************************************
1112 * read a structure.
1113 * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1114 ********************************************************************/
1115
1116BOOL spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
1117{
1118        if (q_u == NULL)
1119                return False;
1120
1121        prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
1122        depth++;
1123
1124        if (!prs_align(ps))
1125                return False;
1126
1127        if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1128                return False;
1129        if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1130                return False;
1131       
1132        if (!prs_align(ps))
1133                return False;
1134
1135        if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1136                return False;
1137               
1138        return True;
1139}
1140
1141/*******************************************************************
1142 * write a structure.
1143 * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1144 * called from spoolss_open_printer_ex (cli_spoolss.c)
1145 ********************************************************************/
1146
1147BOOL spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
1148{
1149        if (r_u == NULL) return False;
1150
1151        prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
1152        depth++;
1153       
1154        if (!prs_align(ps))
1155                return False;
1156
1157        if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1158                return False;   
1159
1160        if (!prs_werror("status code", ps, depth, &(r_u->status)))
1161                return False;
1162               
1163        return True;
1164}
1165
1166
1167/*******************************************************************
1168 * read a structure.
1169 * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1170 ********************************************************************/
1171
1172BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
1173{
1174        if (q_u == NULL)
1175                return False;
1176
1177        prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
1178        depth++;
1179
1180        if (!prs_align(ps))
1181                return False;
1182
1183        if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1184                return False;
1185        if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1186                return False;
1187       
1188        if (!prs_align(ps))
1189                return False;
1190
1191        if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1192                return False;
1193
1194        if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
1195                return False;   
1196        if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
1197                return False;
1198       
1199        return True;
1200}
1201
1202/*******************************************************************
1203 * write a structure.
1204 * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1205 * called from spoolss_open_printer_ex (cli_spoolss.c)
1206 ********************************************************************/
1207
1208BOOL spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
1209{
1210        if (r_u == NULL) return False;
1211
1212        prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
1213        depth++;
1214       
1215        if (!prs_align(ps))
1216                return False;
1217
1218        if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1219                return False;
1220
1221        if (!prs_werror("status code", ps, depth, &(r_u->status)))
1222                return False;
1223
1224        return True;
1225}
1226
1227/*******************************************************************
1228 * init a structure.
1229 ********************************************************************/
1230BOOL make_spoolss_q_deleteprinterdriverex( TALLOC_CTX *mem_ctx,
1231                                           SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, 
1232                                           const char *server,
1233                                           const char* arch, 
1234                                           const char* driver,
1235                                           int version)
1236{
1237        DEBUG(5,("make_spoolss_q_deleteprinterdriverex\n"));
1238 
1239        q_u->server_ptr = (server!=NULL)?1:0;
1240        q_u->delete_flags = DPD_DELETE_UNUSED_FILES;
1241 
1242        /* these must be NULL terminated or else NT4 will
1243           complain about invalid parameters --jerry */
1244        init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1245        init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1246        init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1247
1248        if (version >= 0) { 
1249                q_u->delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1250                q_u->version = version;
1251        }
1252
1253        return True;
1254}
1255
1256
1257/*******************************************************************
1258 * init a structure.
1259 ********************************************************************/
1260BOOL make_spoolss_q_deleteprinterdriver(
1261        TALLOC_CTX *mem_ctx,
1262        SPOOL_Q_DELETEPRINTERDRIVER *q_u, 
1263        const char *server,
1264        const char* arch, 
1265        const char* driver
1266)
1267{
1268        DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
1269       
1270        q_u->server_ptr = (server!=NULL)?1:0;
1271
1272        /* these must be NULL terminated or else NT4 will
1273           complain about invalid parameters --jerry */
1274        init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1275        init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1276        init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1277       
1278        return True;
1279}
1280
1281/*******************************************************************
1282 * make a structure.
1283 ********************************************************************/
1284
1285BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
1286                                   const POLICY_HND *handle,
1287                                   const char *valuename, uint32 size)
1288{
1289        if (q_u == NULL) return False;
1290
1291        DEBUG(5,("make_spoolss_q_getprinterdata\n"));
1292
1293        q_u->handle = *handle;
1294        init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1295        q_u->size = size;
1296
1297        return True;
1298}
1299
1300/*******************************************************************
1301 * make a structure.
1302 ********************************************************************/
1303
1304BOOL make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
1305                                     const POLICY_HND *handle,
1306                                     const char *keyname, 
1307                                     const char *valuename, uint32 size)
1308{
1309        if (q_u == NULL) return False;
1310
1311        DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
1312
1313        q_u->handle = *handle;
1314        init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1315        init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
1316        q_u->size = size;
1317
1318        return True;
1319}
1320
1321/*******************************************************************
1322 * read a structure.
1323 * called from spoolss_q_getprinterdata (srv_spoolss.c)
1324 ********************************************************************/
1325
1326BOOL spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
1327{
1328        if (q_u == NULL)
1329                return False;
1330
1331        prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
1332        depth++;
1333
1334        if (!prs_align(ps))
1335                return False;
1336        if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1337                return False;
1338        if (!prs_align(ps))
1339                return False;
1340        if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1341                return False;
1342        if (!prs_align(ps))
1343                return False;
1344        if (!prs_uint32("size", ps, depth, &q_u->size))
1345                return False;
1346
1347        return True;
1348}
1349
1350/*******************************************************************
1351 * read a structure.
1352 * called from spoolss_q_deleteprinterdata (srv_spoolss.c)
1353 ********************************************************************/
1354
1355BOOL spoolss_io_q_deleteprinterdata(const char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
1356{
1357        if (q_u == NULL)
1358                return False;
1359
1360        prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
1361        depth++;
1362
1363        if (!prs_align(ps))
1364                return False;
1365        if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1366                return False;
1367        if (!prs_align(ps))
1368                return False;
1369        if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1370                return False;
1371
1372        return True;
1373}
1374
1375/*******************************************************************
1376 * write a structure.
1377 * called from spoolss_r_deleteprinterdata (srv_spoolss.c)
1378 ********************************************************************/
1379
1380BOOL spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
1381{
1382        prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
1383        depth++;
1384        if(!prs_werror("status", ps, depth, &r_u->status))
1385                return False;
1386
1387        return True;
1388}
1389
1390/*******************************************************************
1391 * read a structure.
1392 * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
1393 ********************************************************************/
1394
1395BOOL spoolss_io_q_deleteprinterdataex(const char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
1396{
1397        if (q_u == NULL)
1398                return False;
1399
1400        prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
1401        depth++;
1402
1403        if (!prs_align(ps))
1404                return False;
1405        if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1406                return False;
1407       
1408        if (!smb_io_unistr2("keyname  ", &q_u->keyname, True, ps, depth))
1409                return False;
1410        if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
1411                return False;
1412
1413        return True;
1414}
1415
1416/*******************************************************************
1417 * write a structure.
1418 * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
1419 ********************************************************************/
1420
1421BOOL spoolss_io_r_deleteprinterdataex(const char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
1422{
1423        prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
1424        depth++;
1425       
1426        if(!prs_werror("status", ps, depth, &r_u->status))
1427                return False;
1428
1429        return True;
1430}
1431
1432/*******************************************************************
1433 * write a structure.
1434 * called from spoolss_r_getprinterdata (srv_spoolss.c)
1435 ********************************************************************/
1436
1437BOOL spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
1438{
1439        if (r_u == NULL)
1440                return False;
1441
1442        prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
1443        depth++;
1444
1445        if (!prs_align(ps))
1446                return False;
1447        if (!prs_uint32("type", ps, depth, &r_u->type))
1448                return False;
1449        if (!prs_uint32("size", ps, depth, &r_u->size))
1450                return False;
1451       
1452        if (UNMARSHALLING(ps) && r_u->size) {
1453                r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
1454                if(!r_u->data)
1455                        return False;
1456        }
1457
1458        if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
1459                return False;
1460               
1461        if (!prs_align(ps))
1462                return False;
1463       
1464        if (!prs_uint32("needed", ps, depth, &r_u->needed))
1465                return False;
1466        if (!prs_werror("status", ps, depth, &r_u->status))
1467                return False;
1468               
1469        return True;
1470}
1471
1472/*******************************************************************
1473 * make a structure.
1474 ********************************************************************/
1475
1476BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
1477{
1478        if (q_u == NULL) return False;
1479
1480        DEBUG(5,("make_spoolss_q_closeprinter\n"));
1481
1482        memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1483
1484        return True;
1485}
1486
1487/*******************************************************************
1488 * read a structure.
1489 * called from static spoolss_q_abortprinter (srv_spoolss.c)
1490 * called from spoolss_abortprinter (cli_spoolss.c)
1491 ********************************************************************/
1492
1493BOOL spoolss_io_q_abortprinter(const char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
1494{
1495        if (q_u == NULL) return False;
1496
1497        prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
1498        depth++;
1499
1500        if (!prs_align(ps))
1501                return False;
1502
1503        if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1504                return False;
1505
1506        return True;
1507}
1508
1509/*******************************************************************
1510 * write a structure.
1511 * called from spoolss_r_abortprinter (srv_spoolss.c)
1512 ********************************************************************/
1513
1514BOOL spoolss_io_r_abortprinter(const char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
1515{
1516        prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
1517        depth++;
1518        if(!prs_werror("status", ps, depth, &r_u->status))
1519                return False;
1520
1521        return True;
1522}
1523
1524/*******************************************************************
1525 * read a structure.
1526 * called from static spoolss_q_deleteprinter (srv_spoolss.c)
1527 * called from spoolss_deleteprinter (cli_spoolss.c)
1528 ********************************************************************/
1529
1530BOOL spoolss_io_q_deleteprinter(const char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
1531{
1532        if (q_u == NULL) return False;
1533
1534        prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
1535        depth++;
1536
1537        if (!prs_align(ps))
1538                return False;
1539
1540        if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1541                return False;
1542
1543        return True;
1544}
1545
1546/*******************************************************************
1547 * write a structure.
1548 * called from static spoolss_r_deleteprinter (srv_spoolss.c)
1549 * called from spoolss_deleteprinter (cli_spoolss.c)
1550 ********************************************************************/
1551
1552BOOL spoolss_io_r_deleteprinter(const char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
1553{
1554        prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
1555        depth++;
1556       
1557        if (!prs_align(ps))
1558                return False;
1559
1560        if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1561                return False;
1562        if (!prs_werror("status", ps, depth, &r_u->status))
1563                return False;
1564       
1565        return True;
1566}
1567
1568
1569/*******************************************************************
1570 * read a structure.
1571 * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1572 * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1573 ********************************************************************/
1574
1575BOOL spoolss_io_q_deleteprinterdriver(const char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
1576{
1577        if (q_u == NULL) return False;
1578
1579        prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
1580        depth++;
1581
1582        if (!prs_align(ps))
1583                return False;
1584
1585        if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1586                return False;           
1587        if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1588                return False;
1589        if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1590                return False;
1591        if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1592                return False;
1593
1594
1595        return True;
1596}
1597
1598
1599/*******************************************************************
1600 * write a structure.
1601 ********************************************************************/
1602BOOL spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
1603{
1604        if (r_u == NULL) return False;
1605
1606        prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
1607        depth++;
1608
1609        if (!prs_align(ps))
1610                return False;
1611
1612        if (!prs_werror("status", ps, depth, &r_u->status))
1613                return False;
1614
1615        return True;
1616}
1617
1618
1619/*******************************************************************
1620 * read a structure.
1621 * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1622 * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1623 ********************************************************************/
1624
1625BOOL spoolss_io_q_deleteprinterdriverex(const char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
1626{
1627        if (q_u == NULL) return False;
1628
1629        prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex");
1630        depth++;
1631
1632        if (!prs_align(ps))
1633                return False;
1634
1635        if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1636                return False;           
1637        if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1638                return False;
1639        if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1640                return False;
1641        if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1642                return False;
1643
1644        if (!prs_align(ps))
1645                return False;
1646
1647        if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
1648                return False;           
1649        if(!prs_uint32("version      ", ps, depth, &q_u->version))
1650                return False;           
1651
1652
1653        return True;
1654}
1655
1656
1657/*******************************************************************
1658 * write a structure.
1659 ********************************************************************/
1660BOOL spoolss_io_r_deleteprinterdriverex(const char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth)
1661{
1662        if (r_u == NULL) return False;
1663
1664        prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex");
1665        depth++;
1666
1667        if (!prs_align(ps))
1668                return False;
1669
1670        if (!prs_werror("status", ps, depth, &r_u->status))
1671                return False;
1672
1673        return True;
1674}
1675
1676
1677
1678/*******************************************************************
1679 * read a structure.
1680 * called from static spoolss_q_closeprinter (srv_spoolss.c)
1681 * called from spoolss_closeprinter (cli_spoolss.c)
1682 ********************************************************************/
1683
1684BOOL spoolss_io_q_closeprinter(const char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
1685{
1686        if (q_u == NULL) return False;
1687
1688        prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
1689        depth++;
1690
1691        if (!prs_align(ps))
1692                return False;
1693
1694        if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1695                return False;
1696
1697        return True;
1698}
1699
1700/*******************************************************************
1701 * write a structure.
1702 * called from static spoolss_r_closeprinter (srv_spoolss.c)
1703 * called from spoolss_closeprinter (cli_spoolss.c)
1704 ********************************************************************/
1705
1706BOOL spoolss_io_r_closeprinter(const char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
1707{
1708        prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
1709        depth++;
1710       
1711        if (!prs_align(ps))
1712                return False;
1713
1714        if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1715                return False;
1716        if (!prs_werror("status", ps, depth, &r_u->status))
1717                return False;
1718       
1719        return True;
1720}
1721
1722/*******************************************************************
1723 * read a structure.
1724 * called from spoolss_q_startdocprinter (srv_spoolss.c)
1725 ********************************************************************/
1726
1727BOOL spoolss_io_q_startdocprinter(const char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
1728{
1729        if (q_u == NULL) return False;
1730
1731        prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
1732        depth++;
1733
1734        if(!prs_align(ps))
1735                return False;
1736
1737        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1738                return False;
1739       
1740        if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
1741                return False;
1742
1743        return True;
1744}
1745
1746/*******************************************************************
1747 * write a structure.
1748 * called from spoolss_r_startdocprinter (srv_spoolss.c)
1749 ********************************************************************/
1750
1751BOOL spoolss_io_r_startdocprinter(const char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
1752{
1753        prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
1754        depth++;
1755        if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
1756                return False;
1757        if(!prs_werror("status", ps, depth, &r_u->status))
1758                return False;
1759
1760        return True;
1761}
1762
1763/*******************************************************************
1764 * read a structure.
1765 * called from spoolss_q_enddocprinter (srv_spoolss.c)
1766 ********************************************************************/
1767
1768BOOL spoolss_io_q_enddocprinter(const char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
1769{
1770        if (q_u == NULL) return False;
1771
1772        prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
1773        depth++;
1774
1775        if(!prs_align(ps))
1776                return False;
1777
1778        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1779                return False;
1780
1781        return True;
1782}
1783
1784/*******************************************************************
1785 * write a structure.
1786 * called from spoolss_r_enddocprinter (srv_spoolss.c)
1787 ********************************************************************/
1788
1789BOOL spoolss_io_r_enddocprinter(const char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
1790{
1791        prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
1792        depth++;
1793        if(!prs_werror("status", ps, depth, &r_u->status))
1794                return False;
1795
1796        return True;
1797}
1798
1799/*******************************************************************
1800 * read a structure.
1801 * called from spoolss_q_startpageprinter (srv_spoolss.c)
1802 ********************************************************************/
1803
1804BOOL spoolss_io_q_startpageprinter(const char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
1805{
1806        if (q_u == NULL) return False;
1807
1808        prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
1809        depth++;
1810
1811        if(!prs_align(ps))
1812                return False;
1813
1814        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1815                return False;
1816
1817        return True;
1818}
1819
1820/*******************************************************************
1821 * write a structure.
1822 * called from spoolss_r_startpageprinter (srv_spoolss.c)
1823 ********************************************************************/
1824
1825BOOL spoolss_io_r_startpageprinter(const char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1826{
1827        prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1828        depth++;
1829        if(!prs_werror("status", ps, depth, &r_u->status))
1830                return False;
1831
1832        return True;
1833}
1834
1835/*******************************************************************
1836 * read a structure.
1837 * called from spoolss_q_endpageprinter (srv_spoolss.c)
1838 ********************************************************************/
1839
1840BOOL spoolss_io_q_endpageprinter(const char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1841{
1842        if (q_u == NULL) return False;
1843
1844        prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1845        depth++;
1846
1847        if(!prs_align(ps))
1848                return False;
1849
1850        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1851                return False;
1852
1853        return True;
1854}
1855
1856/*******************************************************************
1857 * write a structure.
1858 * called from spoolss_r_endpageprinter (srv_spoolss.c)
1859 ********************************************************************/
1860
1861BOOL spoolss_io_r_endpageprinter(const char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1862{
1863        prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1864        depth++;
1865        if(!prs_werror("status", ps, depth, &r_u->status))
1866                return False;
1867
1868        return True;
1869}
1870
1871/*******************************************************************
1872 * read a structure.
1873 * called from spoolss_q_writeprinter (srv_spoolss.c)
1874 ********************************************************************/
1875
1876BOOL spoolss_io_q_writeprinter(const char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1877{
1878        if (q_u == NULL) return False;
1879
1880        prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1881        depth++;
1882
1883        if(!prs_align(ps))
1884                return False;
1885
1886        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1887                return False;
1888        if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
1889                return False;
1890       
1891        if (q_u->buffer_size!=0)
1892        {
1893                if (UNMARSHALLING(ps))
1894                        q_u->buffer=PRS_ALLOC_MEM(ps, uint8, q_u->buffer_size);
1895                if(q_u->buffer == NULL)
1896                        return False;   
1897                if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1898                        return False;
1899        }
1900        if(!prs_align(ps))
1901                return False;
1902        if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
1903                return False;
1904
1905        return True;
1906}
1907
1908/*******************************************************************
1909 * write a structure.
1910 * called from spoolss_r_writeprinter (srv_spoolss.c)
1911 ********************************************************************/
1912
1913BOOL spoolss_io_r_writeprinter(const char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1914{
1915        prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1916        depth++;
1917        if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
1918                return False;
1919        if(!prs_werror("status", ps, depth, &r_u->status))
1920                return False;
1921
1922        return True;
1923}
1924
1925/*******************************************************************
1926 * read a structure.
1927 * called from spoolss_q_rffpcnex (srv_spoolss.c)
1928 ********************************************************************/
1929
1930BOOL spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1931{
1932        prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1933        depth++;
1934
1935        if(!prs_align(ps))
1936                return False;
1937
1938        if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1939                return False;
1940        if(!prs_uint32("flags", ps, depth, &q_u->flags))
1941                return False;
1942        if(!prs_uint32("options", ps, depth, &q_u->options))
1943                return False;
1944        if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1945                return False;
1946        if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1947                return False;
1948
1949        if(!prs_align(ps))
1950                return False;
1951               
1952        if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1953                return False;
1954
1955        if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1956                return False;
1957       
1958        if (q_u->option_ptr!=0) {
1959       
1960                if (UNMARSHALLING(ps))
1961                        if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1962                                return False;
1963       
1964                if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1965                        return False;
1966        }
1967       
1968        return True;
1969}
1970
1971/*******************************************************************
1972 * write a structure.
1973 * called from spoolss_r_rffpcnex (srv_spoolss.c)
1974 ********************************************************************/
1975
1976BOOL spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1977{
1978        prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1979        depth++;
1980
1981        if(!prs_werror("status", ps, depth, &r_u->status))
1982                return False;
1983
1984        return True;
1985}
1986
1987/*******************************************************************
1988 * read a structure.
1989 * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1990 ********************************************************************/
1991
1992BOOL spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1993{
1994        prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1995        depth++;
1996
1997        if(!prs_align(ps))
1998                return False;
1999
2000        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
2001                return False;
2002
2003        if(!prs_uint32("change", ps, depth, &q_u->change))
2004                return False;
2005       
2006        if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
2007                return False;
2008       
2009        if (q_u->option_ptr!=0) {
2010       
2011                if (UNMARSHALLING(ps))
2012                        if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
2013                                return False;
2014       
2015                if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
2016                        return False;
2017        }
2018
2019        return True;
2020}
2021
2022/*******************************************************************
2023 * write a structure.
2024 * called from spoolss_r_rfnpcnex (srv_spoolss.c)
2025 ********************************************************************/
2026
2027BOOL spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
2028{
2029        prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
2030        depth++;
2031
2032        if(!prs_align(ps))
2033                return False;
2034               
2035        if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
2036                return False;
2037
2038        if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
2039                return False;
2040       
2041        if(!prs_align(ps))
2042                return False;
2043        if(!prs_werror("status", ps, depth, &r_u->status))
2044                return False;
2045
2046        return True;
2047}
2048
2049/*******************************************************************
2050 * return the length of a uint16 (obvious, but the code is clean)
2051 ********************************************************************/
2052
2053static uint32 size_of_uint16(uint16 *value)
2054{
2055        return (sizeof(*value));
2056}
2057
2058/*******************************************************************
2059 * return the length of a uint32 (obvious, but the code is clean)
2060 ********************************************************************/
2061
2062static uint32 size_of_uint32(uint32 *value)
2063{
2064        return (sizeof(*value));
2065}
2066
2067/*******************************************************************
2068 * return the length of a NTTIME (obvious, but the code is clean)
2069 ********************************************************************/
2070
2071static uint32 size_of_nttime(NTTIME *value)
2072{
2073        return (sizeof(*value));
2074}
2075
2076/*******************************************************************
2077 * return the length of a uint32 (obvious, but the code is clean)
2078 ********************************************************************/
2079
2080static uint32 size_of_device_mode(DEVICEMODE *devmode)
2081{
2082        if (devmode==NULL)
2083                return (4);
2084        else 
2085                return (4+devmode->size+devmode->driverextra);
2086}
2087
2088/*******************************************************************
2089 * return the length of a uint32 (obvious, but the code is clean)
2090 ********************************************************************/
2091
2092static uint32 size_of_systemtime(SYSTEMTIME *systime)
2093{
2094        if (systime==NULL)
2095                return (4);
2096        else 
2097                return (sizeof(SYSTEMTIME) +4);
2098}
2099
2100/*******************************************************************
2101 Parse a DEVMODE structure and its relative pointer.
2102********************************************************************/
2103
2104static BOOL smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
2105{
2106        prs_struct *ps=&buffer->prs;
2107
2108        prs_debug(ps, depth, desc, "smb_io_reldevmode");
2109        depth++;
2110
2111        if (MARSHALLING(ps)) {
2112                uint32 struct_offset = prs_offset(ps);
2113                uint32 relative_offset;
2114               
2115                if (*devmode == NULL) {
2116                        relative_offset=0;
2117                        if (!prs_uint32("offset", ps, depth, &relative_offset))
2118                                return False;
2119                        DEBUG(8, ("boing, the devmode was NULL\n"));
2120                       
2121                        return True;
2122                }
2123               
2124                buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
2125               
2126                if(!prs_set_offset(ps, buffer->string_at_end))
2127                        return False;
2128               
2129                /* write the DEVMODE */
2130                if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2131                        return False;
2132
2133                if(!prs_set_offset(ps, struct_offset))
2134                        return False;
2135               
2136                relative_offset=buffer->string_at_end - buffer->struct_start;
2137                /* write its offset */
2138                if (!prs_uint32("offset", ps, depth, &relative_offset))
2139                        return False;
2140        }
2141        else {
2142                uint32 old_offset;
2143               
2144                /* read the offset */
2145                if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2146                        return False;
2147                if (buffer->string_at_end == 0) {
2148                        *devmode = NULL;
2149                        return True;
2150                }
2151
2152                old_offset = prs_offset(ps);
2153                if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2154                        return False;
2155
2156                /* read the string */
2157                if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
2158                        return False;
2159                if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2160                        return False;
2161
2162                if(!prs_set_offset(ps, old_offset))
2163                        return False;
2164        }
2165        return True;
2166}
2167
2168/*******************************************************************
2169 Parse a PRINTER_INFO_0 structure.
2170********************************************************************/ 
2171
2172BOOL smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
2173{
2174        prs_struct *ps=&buffer->prs;
2175
2176        prs_debug(ps, depth, desc, "smb_io_printer_info_0");
2177        depth++;       
2178       
2179        buffer->struct_start=prs_offset(ps);
2180
2181        if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2182                return False;
2183        if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2184                return False;
2185       
2186        if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
2187                return False;
2188        if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
2189                return False;
2190        if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
2191                return False;
2192
2193        if(!prs_uint16("year", ps, depth, &info->year))
2194                return False;
2195        if(!prs_uint16("month", ps, depth, &info->month))
2196                return False;
2197        if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
2198                return False;
2199        if(!prs_uint16("day", ps, depth, &info->day))
2200                return False;
2201        if(!prs_uint16("hour", ps, depth, &info->hour))
2202                return False;
2203        if(!prs_uint16("minute", ps, depth, &info->minute))
2204                return False;
2205        if(!prs_uint16("second", ps, depth, &info->second))
2206                return False;
2207        if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
2208                return False;
2209
2210        if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
2211                return False;
2212        if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
2213                return False;
2214
2215        if(!prs_uint16("major_version", ps, depth, &info->major_version))
2216                return False;
2217        if(!prs_uint16("build_version", ps, depth, &info->build_version))
2218                return False;
2219        if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2220                return False;
2221        if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2222                return False;
2223        if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2224                return False;
2225        if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
2226                return False;
2227        if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
2228                return False;
2229        if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
2230                return False;
2231        if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
2232                return False;
2233        if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
2234                return False;
2235        if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
2236                return False;
2237        if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
2238                return False;
2239        if(!prs_uint32("change_id", ps, depth, &info->change_id))
2240                return False;
2241        if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
2242                return False;
2243        if(!prs_uint32("status"   , ps, depth, &info->status))
2244                return False;
2245        if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
2246                return False;
2247        if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
2248                return False;
2249        if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
2250                return False;
2251        if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
2252                return False;
2253        if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
2254                return False;
2255        if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
2256                return False;
2257        if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
2258                return False;
2259        if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
2260                return False;
2261        if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
2262                return False;
2263        if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
2264                return False;
2265
2266        return True;
2267}
2268
2269/*******************************************************************
2270 Parse a PRINTER_INFO_1 structure.
2271********************************************************************/ 
2272
2273BOOL smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
2274{
2275        prs_struct *ps=&buffer->prs;
2276
2277        prs_debug(ps, depth, desc, "smb_io_printer_info_1");
2278        depth++;       
2279       
2280        buffer->struct_start=prs_offset(ps);
2281
2282        if (!prs_uint32("flags", ps, depth, &info->flags))
2283                return False;
2284        if (!smb_io_relstr("description", buffer, depth, &info->description))
2285                return False;
2286        if (!smb_io_relstr("name", buffer, depth, &info->name))
2287                return False;
2288        if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2289                return False;   
2290
2291        return True;
2292}
2293
2294/*******************************************************************
2295 Parse a PRINTER_INFO_2 structure.
2296********************************************************************/ 
2297
2298BOOL smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
2299{
2300        prs_struct *ps=&buffer->prs;
2301        uint32 dm_offset, sd_offset, current_offset;
2302        uint32 dummy_value = 0, has_secdesc = 0;
2303
2304        prs_debug(ps, depth, desc, "smb_io_printer_info_2");
2305        depth++;       
2306       
2307        buffer->struct_start=prs_offset(ps);
2308       
2309        if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2310                return False;
2311        if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2312                return False;
2313        if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
2314                return False;
2315        if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2316                return False;
2317        if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2318                return False;
2319        if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2320                return False;
2321        if (!smb_io_relstr("location", buffer, depth, &info->location))
2322                return False;
2323
2324        /* save current offset and wind forwared by a uint32 */
2325        dm_offset = prs_offset(ps);
2326        if (!prs_uint32("devmode", ps, depth, &dummy_value))
2327                return False;
2328       
2329        if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
2330                return False;
2331        if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2332                return False;
2333        if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2334                return False;
2335        if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2336                return False;
2337
2338        /* save current offset for the sec_desc */
2339        sd_offset = prs_offset(ps);
2340        if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
2341                return False;
2342
2343       
2344        /* save current location so we can pick back up here */
2345        current_offset = prs_offset(ps);
2346       
2347        /* parse the devmode */
2348        if (!prs_set_offset(ps, dm_offset))
2349                return False;
2350        if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2351                return False;
2352       
2353        /* parse the sec_desc */
2354        if (info->secdesc) {
2355                if (!prs_set_offset(ps, sd_offset))
2356                        return False;
2357                if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
2358                        return False;
2359        }
2360
2361        /* pick up where we left off */
2362        if (!prs_set_offset(ps, current_offset))
2363                return False;
2364
2365        if (!prs_uint32("attributes", ps, depth, &info->attributes))
2366                return False;
2367        if (!prs_uint32("priority", ps, depth, &info->priority))
2368                return False;
2369        if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
2370                return False;
2371        if (!prs_uint32("starttime", ps, depth, &info->starttime))
2372                return False;
2373        if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
2374                return False;
2375        if (!prs_uint32("status", ps, depth, &info->status))
2376                return False;
2377        if (!prs_uint32("jobs", ps, depth, &info->cjobs))
2378                return False;
2379        if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
2380                return False;
2381
2382        return True;
2383}
2384
2385/*******************************************************************
2386 Parse a PRINTER_INFO_3 structure.
2387********************************************************************/ 
2388
2389BOOL smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
2390{
2391        uint32 offset = 0;
2392        prs_struct *ps=&buffer->prs;
2393
2394        prs_debug(ps, depth, desc, "smb_io_printer_info_3");
2395        depth++;       
2396       
2397        buffer->struct_start=prs_offset(ps);
2398       
2399        if (MARSHALLING(ps)) {
2400                /* Ensure the SD is 8 byte aligned in the buffer. */
2401                uint start = prs_offset(ps); /* Remember the start position. */
2402                uint off_val = 0;
2403
2404                /* Write a dummy value. */
2405                if (!prs_uint32("offset", ps, depth, &off_val))
2406                        return False;
2407
2408                /* 8 byte align. */
2409                if (!prs_align_uint64(ps))
2410                        return False;
2411
2412                /* Remember where we must seek back to write the SD. */
2413                offset = prs_offset(ps);
2414
2415                /* Calculate the real offset for the SD. */
2416
2417                off_val = offset - start;
2418
2419                /* Seek back to where we store the SD offset & store. */
2420                prs_set_offset(ps, start);
2421                if (!prs_uint32("offset", ps, depth, &off_val))
2422                        return False;
2423
2424                /* Return to after the 8 byte align. */
2425                prs_set_offset(ps, offset);
2426
2427        } else {
2428                if (!prs_uint32("offset", ps, depth, &offset))
2429                        return False;
2430                /* Seek within the buffer. */
2431                if (!prs_set_offset(ps, offset))
2432                        return False;
2433        }
2434        if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
2435                return False;
2436
2437        return True;
2438}
2439
2440/*******************************************************************
2441 Parse a PRINTER_INFO_4 structure.
2442********************************************************************/ 
2443
2444BOOL smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
2445{
2446        prs_struct *ps=&buffer->prs;
2447
2448        prs_debug(ps, depth, desc, "smb_io_printer_info_4");
2449        depth++;       
2450       
2451        buffer->struct_start=prs_offset(ps);
2452       
2453        if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2454                return False;
2455        if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2456                return False;
2457        if (!prs_uint32("attributes", ps, depth, &info->attributes))
2458                return False;
2459        return True;
2460}
2461
2462/*******************************************************************
2463 Parse a PRINTER_INFO_5 structure.
2464********************************************************************/ 
2465
2466BOOL smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
2467{
2468        prs_struct *ps=&buffer->prs;
2469
2470        prs_debug(ps, depth, desc, "smb_io_printer_info_5");
2471        depth++;       
2472       
2473        buffer->struct_start=prs_offset(ps);
2474       
2475        if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2476                return False;
2477        if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2478                return False;
2479        if (!prs_uint32("attributes", ps, depth, &info->attributes))
2480                return False;
2481        if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
2482                return False;
2483        if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
2484                return False;
2485        return True;
2486}
2487
2488/*******************************************************************
2489 Parse a PRINTER_INFO_6 structure.
2490********************************************************************/ 
2491
2492BOOL smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
2493                           PRINTER_INFO_6 *info, int depth)
2494{
2495        prs_struct *ps=&buffer->prs;
2496
2497        prs_debug(ps, depth, desc, "smb_io_printer_info_6");
2498        depth++;       
2499       
2500        if (!prs_uint32("status", ps, depth, &info->status))
2501                return False;
2502
2503        return True;
2504}
2505
2506/*******************************************************************
2507 Parse a PRINTER_INFO_7 structure.
2508********************************************************************/ 
2509
2510BOOL smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
2511{
2512        prs_struct *ps=&buffer->prs;
2513
2514        prs_debug(ps, depth, desc, "smb_io_printer_info_7");
2515        depth++;       
2516       
2517        buffer->struct_start=prs_offset(ps);
2518       
2519        if (!smb_io_relstr("guid", buffer, depth, &info->guid))
2520                return False;
2521        if (!prs_uint32("action", ps, depth, &info->action))
2522                return False;
2523        return True;
2524}
2525
2526/*******************************************************************
2527 Parse a PORT_INFO_1 structure.
2528********************************************************************/ 
2529
2530BOOL smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2531{
2532        prs_struct *ps=&buffer->prs;
2533
2534        prs_debug(ps, depth, desc, "smb_io_port_info_1");
2535        depth++;       
2536       
2537        buffer->struct_start=prs_offset(ps);
2538       
2539        if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2540                return False;
2541
2542        return True;
2543}
2544
2545/*******************************************************************
2546 Parse a PORT_INFO_2 structure.
2547********************************************************************/ 
2548
2549BOOL smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2550{
2551        prs_struct *ps=&buffer->prs;
2552
2553        prs_debug(ps, depth, desc, "smb_io_port_info_2");
2554        depth++;       
2555       
2556        buffer->struct_start=prs_offset(ps);
2557       
2558        if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2559                return False;
2560        if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2561                return False;
2562        if (!smb_io_relstr("description", buffer, depth, &info->description))
2563                return False;
2564        if (!prs_uint32("port_type", ps, depth, &info->port_type))
2565                return False;
2566        if (!prs_uint32("reserved", ps, depth, &info->reserved))
2567                return False;
2568
2569        return True;
2570}
2571
2572/*******************************************************************
2573 Parse a DRIVER_INFO_1 structure.
2574********************************************************************/
2575
2576BOOL smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
2577{
2578        prs_struct *ps=&buffer->prs;
2579
2580        prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
2581        depth++;       
2582       
2583        buffer->struct_start=prs_offset(ps);
2584
2585        if (!smb_io_relstr("name", buffer, depth, &info->name))
2586                return False;
2587
2588        return True;
2589}
2590
2591/*******************************************************************
2592 Parse a DRIVER_INFO_2 structure.
2593********************************************************************/
2594
2595BOOL smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
2596{
2597        prs_struct *ps=&buffer->prs;
2598
2599        prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
2600        depth++;       
2601       
2602        buffer->struct_start=prs_offset(ps);
2603
2604        if (!prs_uint32("version", ps, depth, &info->version))
2605                return False;
2606        if (!smb_io_relstr("name", buffer, depth, &info->name))
2607                return False;
2608        if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2609                return False;
2610        if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2611                return False;
2612        if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2613                return False;
2614        if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2615                return False;
2616
2617        return True;
2618}
2619
2620/*******************************************************************
2621 Parse a DRIVER_INFO_3 structure.
2622********************************************************************/
2623
2624BOOL smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
2625{
2626        prs_struct *ps=&buffer->prs;
2627
2628        prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
2629        depth++;       
2630       
2631        buffer->struct_start=prs_offset(ps);
2632
2633        if (!prs_uint32("version", ps, depth, &info->version))
2634                return False;
2635        if (!smb_io_relstr("name", buffer, depth, &info->name))
2636                return False;
2637        if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2638                return False;
2639        if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2640                return False;
2641        if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2642                return False;
2643        if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2644                return False;
2645        if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2646                return False;
2647
2648        if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2649                return False;
2650
2651        if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2652                return False;
2653        if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2654                return False;
2655
2656        return True;
2657}
2658
2659/*******************************************************************
2660 Parse a DRIVER_INFO_6 structure.
2661********************************************************************/
2662
2663BOOL smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
2664{
2665        prs_struct *ps=&buffer->prs;
2666
2667        prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
2668        depth++;       
2669       
2670        buffer->struct_start=prs_offset(ps);
2671
2672        if (!prs_uint32("version", ps, depth, &info->version))
2673                return False;
2674        if (!smb_io_relstr("name", buffer, depth, &info->name))
2675                return False;
2676        if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2677                return False;
2678        if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2679                return False;
2680        if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2681                return False;
2682        if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2683                return False;
2684        if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2685                return False;
2686
2687        if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2688                return False;
2689
2690        if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2691                return False;
2692        if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2693                return False;
2694
2695        if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2696                return False;
2697
2698        if (!prs_uint64("date", ps, depth, &info->driver_date))
2699                return False;
2700
2701        if (!prs_uint32("padding", ps, depth, &info->padding))
2702                return False;
2703
2704        if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2705                return False;
2706
2707        if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2708                return False;
2709
2710        if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2711                return False;
2712        if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2713                return False;
2714        if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2715                return False;
2716        if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2717                return False;
2718       
2719        return True;
2720}
2721
2722/*******************************************************************
2723 Parse a JOB_INFO_1 structure.
2724********************************************************************/ 
2725
2726BOOL smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2727{
2728        prs_struct *ps=&buffer->prs;
2729
2730        prs_debug(ps, depth, desc, "smb_io_job_info_1");
2731        depth++;       
2732       
2733        buffer->struct_start=prs_offset(ps);
2734
2735        if (!prs_uint32("jobid", ps, depth, &info->jobid))
2736                return False;
2737        if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2738                return False;
2739        if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2740                return False;
2741        if (!smb_io_relstr("username", buffer, depth, &info->username))
2742                return False;
2743        if (!smb_io_relstr("document", buffer, depth, &info->document))
2744                return False;
2745        if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2746                return False;
2747        if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2748                return False;
2749        if (!prs_uint32("status", ps, depth, &info->status))
2750                return False;
2751        if (!prs_uint32("priority", ps, depth, &info->priority))
2752                return False;
2753        if (!prs_uint32("position", ps, depth, &info->position))
2754                return False;
2755        if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2756                return False;
2757        if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2758                return False;
2759        if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2760                return False;
2761
2762        return True;
2763}
2764
2765/*******************************************************************
2766 Parse a JOB_INFO_2 structure.
2767********************************************************************/ 
2768
2769BOOL smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2770{       
2771        uint32 pipo=0;
2772        prs_struct *ps=&buffer->prs;
2773       
2774        prs_debug(ps, depth, desc, "smb_io_job_info_2");
2775        depth++;       
2776
2777        buffer->struct_start=prs_offset(ps);
2778       
2779        if (!prs_uint32("jobid",ps, depth, &info->jobid))
2780                return False;
2781        if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2782                return False;
2783        if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2784                return False;
2785        if (!smb_io_relstr("username", buffer, depth, &info->username))
2786                return False;
2787        if (!smb_io_relstr("document", buffer, depth, &info->document))
2788                return False;
2789        if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2790                return False;
2791        if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2792                return False;
2793
2794        if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2795                return False;
2796        if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2797                return False;
2798        if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2799                return False;
2800        if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2801                return False;
2802        if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2803                return False;
2804
2805/*      SEC_DESC sec_desc;*/
2806        if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2807                return False;
2808
2809        if (!prs_uint32("status",ps, depth, &info->status))
2810                return False;
2811        if (!prs_uint32("priority",ps, depth, &info->priority))
2812                return False;
2813        if (!prs_uint32("position",ps, depth, &info->position)) 
2814                return False;
2815        if (!prs_uint32("starttime",ps, depth, &info->starttime))
2816                return False;
2817        if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
2818                return False;
2819        if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2820                return False;
2821        if (!prs_uint32("size",ps, depth, &info->size))
2822                return False;
2823        if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2824                return False;
2825        if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2826                return False;
2827        if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2828                return False;
2829
2830        return True;
2831}
2832
2833/*******************************************************************
2834********************************************************************/ 
2835
2836BOOL smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
2837{
2838        prs_struct *ps=&buffer->prs;
2839       
2840        prs_debug(ps, depth, desc, "smb_io_form_1");
2841        depth++;
2842               
2843        buffer->struct_start=prs_offset(ps);
2844       
2845        if (!prs_uint32("flag", ps, depth, &info->flag))
2846                return False;
2847               
2848        if (!smb_io_relstr("name", buffer, depth, &info->name))
2849                return False;
2850
2851        if (!prs_uint32("width", ps, depth, &info->width))
2852                return False;
2853        if (!prs_uint32("length", ps, depth, &info->length))
2854                return False;
2855        if (!prs_uint32("left", ps, depth, &info->left))
2856                return False;
2857        if (!prs_uint32("top", ps, depth, &info->top))
2858                return False;
2859        if (!prs_uint32("right", ps, depth, &info->right))
2860                return False;
2861        if (!prs_uint32("bottom", ps, depth, &info->bottom))
2862                return False;
2863
2864        return True;
2865}
2866
2867
2868
2869/*******************************************************************
2870 Parse a DRIVER_DIRECTORY_1 structure.
2871********************************************************************/ 
2872
2873BOOL smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2874{
2875        prs_struct *ps=&buffer->prs;
2876
2877        prs_debug(ps, depth, desc, "smb_io_driverdir_1");
2878        depth++;
2879
2880        buffer->struct_start=prs_offset(ps);
2881
2882        if (!smb_io_unistr(desc, &info->name, ps, depth))
2883                return False;
2884
2885        return True;
2886}
2887
2888/*******************************************************************
2889 Parse a PORT_INFO_1 structure.
2890********************************************************************/ 
2891
2892BOOL smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2893{
2894        prs_struct *ps=&buffer->prs;
2895
2896        prs_debug(ps, depth, desc, "smb_io_port_1");
2897        depth++;
2898
2899        buffer->struct_start=prs_offset(ps);
2900
2901        if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2902                return False;
2903
2904        return True;
2905}
2906
2907/*******************************************************************
2908 Parse a PORT_INFO_2 structure.
2909********************************************************************/ 
2910
2911BOOL smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2912{
2913        prs_struct *ps=&buffer->prs;
2914
2915        prs_debug(ps, depth, desc, "smb_io_port_2");
2916        depth++;
2917
2918        buffer->struct_start=prs_offset(ps);
2919
2920        if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2921                return False;
2922        if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2923                return False;
2924        if(!smb_io_relstr("description", buffer, depth, &info->description))
2925                return False;
2926        if(!prs_uint32("port_type", ps, depth, &info->port_type))
2927                return False;
2928        if(!prs_uint32("reserved", ps, depth, &info->reserved))
2929                return False;
2930
2931        return True;
2932}
2933
2934/*******************************************************************
2935********************************************************************/ 
2936
2937BOOL smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2938{
2939        prs_struct *ps=&buffer->prs;
2940
2941        prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2942        depth++;       
2943
2944        buffer->struct_start=prs_offset(ps);
2945       
2946        if (smb_io_relstr("name", buffer, depth, &info->name))
2947                return False;
2948
2949        return True;
2950}
2951
2952/*******************************************************************
2953********************************************************************/ 
2954
2955BOOL smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2956{
2957        prs_struct *ps=&buffer->prs;
2958
2959        prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2960        depth++;       
2961
2962        buffer->struct_start=prs_offset(ps);
2963       
2964        if (smb_io_relstr("name", buffer, depth, &info->name))
2965                return False;
2966
2967        return True;
2968}
2969
2970/*******************************************************************
2971********************************************************************/ 
2972
2973BOOL smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2974{
2975        prs_struct *ps=&buffer->prs;
2976
2977        prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2978        depth++;       
2979
2980        buffer->struct_start=prs_offset(ps);
2981
2982        if (!smb_io_relstr("name", buffer, depth, &info->name))
2983                return False;
2984
2985        return True;
2986}
2987
2988/*******************************************************************
2989********************************************************************/ 
2990
2991BOOL smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2992{
2993        prs_struct *ps=&buffer->prs;
2994
2995        prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2996        depth++;       
2997
2998        buffer->struct_start=prs_offset(ps);
2999
3000        if (!smb_io_relstr("name", buffer, depth, &info->name))
3001                return False;
3002        if (!smb_io_relstr("environment", buffer, depth, &info->environment))
3003                return False;
3004        if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
3005                return False;
3006
3007        return True;
3008}
3009
3010/*******************************************************************
3011return the size required by a struct in the stream
3012********************************************************************/ 
3013
3014uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
3015{
3016        int size=0;
3017       
3018        size+=size_of_relative_string( &info->printername );
3019        size+=size_of_relative_string( &info->servername );
3020
3021        size+=size_of_uint32( &info->cjobs);
3022        size+=size_of_uint32( &info->total_jobs);
3023        size+=size_of_uint32( &info->total_bytes);
3024
3025        size+=size_of_uint16( &info->year);
3026        size+=size_of_uint16( &info->month);
3027        size+=size_of_uint16( &info->dayofweek);
3028        size+=size_of_uint16( &info->day);
3029        size+=size_of_uint16( &info->hour);
3030        size+=size_of_uint16( &info->minute);
3031        size+=size_of_uint16( &info->second);
3032        size+=size_of_uint16( &info->milliseconds);
3033
3034        size+=size_of_uint32( &info->global_counter);
3035        size+=size_of_uint32( &info->total_pages);
3036
3037        size+=size_of_uint16( &info->major_version);
3038        size+=size_of_uint16( &info->build_version);
3039
3040        size+=size_of_uint32( &info->unknown7);
3041        size+=size_of_uint32( &info->unknown8);
3042        size+=size_of_uint32( &info->unknown9);
3043        size+=size_of_uint32( &info->session_counter);
3044        size+=size_of_uint32( &info->unknown11);
3045        size+=size_of_uint32( &info->printer_errors);
3046        size+=size_of_uint32( &info->unknown13);
3047        size+=size_of_uint32( &info->unknown14);
3048        size+=size_of_uint32( &info->unknown15);
3049        size+=size_of_uint32( &info->unknown16);
3050        size+=size_of_uint32( &info->change_id);
3051        size+=size_of_uint32( &info->unknown18);
3052        size+=size_of_uint32( &info->status);
3053        size+=size_of_uint32( &info->unknown20);
3054        size+=size_of_uint32( &info->c_setprinter);
3055       
3056        size+=size_of_uint16( &info->unknown22);
3057        size+=size_of_uint16( &info->unknown23);
3058        size+=size_of_uint16( &info->unknown24);
3059        size+=size_of_uint16( &info->unknown25);
3060        size+=size_of_uint16( &info->unknown26);
3061        size+=size_of_uint16( &info->unknown27);
3062        size+=size_of_uint16( &info->unknown28);
3063        size+=size_of_uint16( &info->unknown29);
3064       
3065        return size;
3066}
3067
3068/*******************************************************************
3069return the size required by a struct in the stream
3070********************************************************************/ 
3071
3072uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
3073{
3074        int size=0;
3075               
3076        size+=size_of_uint32( &info->flags );   
3077        size+=size_of_relative_string( &info->description );
3078        size+=size_of_relative_string( &info->name );
3079        size+=size_of_relative_string( &info->comment );
3080
3081        return size;
3082}
3083
3084/*******************************************************************
3085return the size required by a struct in the stream
3086********************************************************************/
3087
3088uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
3089{
3090        uint32 size=0;
3091               
3092        size += 4;
3093       
3094        size += sec_desc_size( info->secdesc );
3095
3096        size+=size_of_device_mode( info->devmode );
3097       
3098        size+=size_of_relative_string( &info->servername );
3099        size+=size_of_relative_string( &info->printername );
3100        size+=size_of_relative_string( &info->sharename );
3101        size+=size_of_relative_string( &info->portname );
3102        size+=size_of_relative_string( &info->drivername );
3103        size+=size_of_relative_string( &info->comment );
3104        size+=size_of_relative_string( &info->location );
3105       
3106        size+=size_of_relative_string( &info->sepfile );
3107        size+=size_of_relative_string( &info->printprocessor );
3108        size+=size_of_relative_string( &info->datatype );
3109        size+=size_of_relative_string( &info->parameters );
3110
3111        size+=size_of_uint32( &info->attributes );
3112        size+=size_of_uint32( &info->priority );
3113        size+=size_of_uint32( &info->defaultpriority );
3114        size+=size_of_uint32( &info->starttime );
3115        size+=size_of_uint32( &info->untiltime );
3116        size+=size_of_uint32( &info->status );
3117        size+=size_of_uint32( &info->cjobs );
3118        size+=size_of_uint32( &info->averageppm );     
3119               
3120        /*
3121         * add any adjustments for alignment.  This is
3122         * not optimal since we could be calling this
3123         * function from a loop (e.g. enumprinters), but
3124         * it is easier to maintain the calculation here and
3125         * not place the burden on the caller to remember.   --jerry
3126         */
3127        if ((size % 4) != 0)
3128                size += 4 - (size % 4);
3129       
3130        return size;
3131}
3132
3133/*******************************************************************
3134return the size required by a struct in the stream
3135********************************************************************/
3136
3137uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
3138{
3139        uint32 size=0;
3140               
3141        size+=size_of_relative_string( &info->printername );
3142        size+=size_of_relative_string( &info->servername );
3143
3144        size+=size_of_uint32( &info->attributes );
3145        return size;
3146}
3147
3148/*******************************************************************
3149return the size required by a struct in the stream
3150********************************************************************/
3151
3152uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
3153{
3154        uint32 size=0;
3155               
3156        size+=size_of_relative_string( &info->printername );
3157        size+=size_of_relative_string( &info->portname );
3158
3159        size+=size_of_uint32( &info->attributes );
3160        size+=size_of_uint32( &info->device_not_selected_timeout );
3161        size+=size_of_uint32( &info->transmission_retry_timeout );
3162        return size;
3163}
3164
3165/*******************************************************************
3166return the size required by a struct in the stream
3167********************************************************************/
3168
3169uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
3170{
3171        return sizeof(uint32);
3172}
3173
3174/*******************************************************************
3175return the size required by a struct in the stream
3176********************************************************************/
3177
3178uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
3179{
3180        /* The 8 is for the self relative pointer - 8 byte aligned.. */
3181        return 8 + (uint32)sec_desc_size( info->secdesc );
3182}
3183
3184/*******************************************************************
3185return the size required by a struct in the stream
3186********************************************************************/
3187
3188uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
3189{
3190        uint32 size=0;
3191               
3192        size+=size_of_relative_string( &info->guid );
3193        size+=size_of_uint32( &info->action );
3194        return size;
3195}
3196
3197/*******************************************************************
3198return the size required by a struct in the stream
3199********************************************************************/
3200
3201uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
3202{
3203        int size=0;
3204        size+=size_of_relative_string( &info->name );
3205
3206        return size;
3207}
3208
3209/*******************************************************************
3210return the size required by a struct in the stream
3211********************************************************************/
3212
3213uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
3214{
3215        int size=0;
3216        size+=size_of_uint32( &info->version ); 
3217        size+=size_of_relative_string( &info->name );
3218        size+=size_of_relative_string( &info->architecture );
3219        size+=size_of_relative_string( &info->driverpath );
3220        size+=size_of_relative_string( &info->datafile );
3221        size+=size_of_relative_string( &info->configfile );
3222
3223        return size;
3224}
3225
3226/*******************************************************************
3227return the size required by a string array.
3228********************************************************************/
3229
3230uint32 spoolss_size_string_array(uint16 *string)
3231{
3232        uint32 i = 0;
3233
3234        if (string) {
3235                for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
3236        }
3237        i=i+2; /* to count all chars including the leading zero */
3238        i=2*i; /* because we need the value in bytes */
3239        i=i+4; /* the offset pointer size */
3240
3241        return i;
3242}
3243
3244/*******************************************************************
3245return the size required by a struct in the stream
3246********************************************************************/
3247
3248uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
3249{
3250        int size=0;
3251
3252        size+=size_of_uint32( &info->version ); 
3253        size+=size_of_relative_string( &info->name );
3254        size+=size_of_relative_string( &info->architecture );
3255        size+=size_of_relative_string( &info->driverpath );
3256        size+=size_of_relative_string( &info->datafile );
3257        size+=size_of_relative_string( &info->configfile );
3258        size+=size_of_relative_string( &info->helpfile );
3259        size+=size_of_relative_string( &info->monitorname );
3260        size+=size_of_relative_string( &info->defaultdatatype );
3261       
3262        size+=spoolss_size_string_array(info->dependentfiles);
3263
3264        return size;
3265}
3266
3267/*******************************************************************
3268return the size required by a struct in the stream
3269********************************************************************/
3270
3271uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
3272{
3273        uint32 size=0;
3274
3275        size+=size_of_uint32( &info->version ); 
3276        size+=size_of_relative_string( &info->name );
3277        size+=size_of_relative_string( &info->architecture );
3278        size+=size_of_relative_string( &info->driverpath );
3279        size+=size_of_relative_string( &info->datafile );
3280        size+=size_of_relative_string( &info->configfile );
3281        size+=size_of_relative_string( &info->helpfile );
3282
3283        size+=spoolss_size_string_array(info->dependentfiles);
3284
3285        size+=size_of_relative_string( &info->monitorname );
3286        size+=size_of_relative_string( &info->defaultdatatype );
3287       
3288        size+=spoolss_size_string_array(info->previousdrivernames);
3289
3290        size+=size_of_nttime(&info->driver_date);
3291        size+=size_of_uint32( &info->padding ); 
3292        size+=size_of_uint32( &info->driver_version_low );     
3293        size+=size_of_uint32( &info->driver_version_high );     
3294        size+=size_of_relative_string( &info->mfgname );
3295        size+=size_of_relative_string( &info->oem_url );
3296        size+=size_of_relative_string( &info->hardware_id );
3297        size+=size_of_relative_string( &info->provider );
3298
3299        return size;
3300}
3301
3302/*******************************************************************
3303return the size required by a struct in the stream
3304********************************************************************/ 
3305
3306uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
3307{
3308        int size=0;
3309        size+=size_of_uint32( &info->jobid );
3310        size+=size_of_relative_string( &info->printername );
3311        size+=size_of_relative_string( &info->machinename );
3312        size+=size_of_relative_string( &info->username );
3313        size+=size_of_relative_string( &info->document );
3314        size+=size_of_relative_string( &info->datatype );
3315        size+=size_of_relative_string( &info->text_status );
3316        size+=size_of_uint32( &info->status );
3317        size+=size_of_uint32( &info->priority );
3318        size+=size_of_uint32( &info->position );
3319        size+=size_of_uint32( &info->totalpages );
3320        size+=size_of_uint32( &info->pagesprinted );
3321        size+=size_of_systemtime( &info->submitted );
3322
3323        return size;
3324}
3325
3326/*******************************************************************
3327return the size required by a struct in the stream
3328********************************************************************/ 
3329
3330uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
3331{
3332        int size=0;
3333
3334        size+=4; /* size of sec desc ptr */
3335
3336        size+=size_of_uint32( &info->jobid );
3337        size+=size_of_relative_string( &info->printername );
3338        size+=size_of_relative_string( &info->machinename );
3339        size+=size_of_relative_string( &info->username );
3340        size+=size_of_relative_string( &info->document );
3341        size+=size_of_relative_string( &info->notifyname );
3342        size+=size_of_relative_string( &info->datatype );
3343        size+=size_of_relative_string( &info->printprocessor );
3344        size+=size_of_relative_string( &info->parameters );
3345        size+=size_of_relative_string( &info->drivername );
3346        size+=size_of_device_mode( info->devmode );
3347        size+=size_of_relative_string( &info->text_status );
3348/*      SEC_DESC sec_desc;*/
3349        size+=size_of_uint32( &info->status );
3350        size+=size_of_uint32( &info->priority );
3351        size+=size_of_uint32( &info->position );
3352        size+=size_of_uint32( &info->starttime );
3353        size+=size_of_uint32( &info->untiltime );
3354        size+=size_of_uint32( &info->totalpages );
3355        size+=size_of_uint32( &info->size );
3356        size+=size_of_systemtime( &info->submitted );
3357        size+=size_of_uint32( &info->timeelapsed );
3358        size+=size_of_uint32( &info->pagesprinted );
3359
3360        return size;
3361}
3362
3363/*******************************************************************
3364return the size required by a struct in the stream
3365********************************************************************/
3366
3367uint32 spoolss_size_form_1(FORM_1 *info)
3368{
3369        int size=0;
3370
3371        size+=size_of_uint32( &info->flag );
3372        size+=size_of_relative_string( &info->name );
3373        size+=size_of_uint32( &info->width );
3374        size+=size_of_uint32( &info->length );
3375        size+=size_of_uint32( &info->left );
3376        size+=size_of_uint32( &info->top );
3377        size+=size_of_uint32( &info->right );
3378        size+=size_of_uint32( &info->bottom );
3379
3380        return size;
3381}
3382
3383/*******************************************************************
3384return the size required by a struct in the stream
3385********************************************************************/ 
3386
3387uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
3388{
3389        int size=0;
3390
3391        size+=size_of_relative_string( &info->port_name );
3392
3393        return size;
3394}
3395
3396/*******************************************************************
3397return the size required by a struct in the stream
3398********************************************************************/ 
3399
3400uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
3401{
3402        int size=0;
3403
3404        size=str_len_uni(&info->name);  /* the string length       */
3405        size=size+1;                    /* add the leading zero    */
3406        size=size*2;                    /* convert in char         */
3407
3408        return size;
3409}
3410
3411/*******************************************************************
3412return the size required by a struct in the stream
3413********************************************************************/ 
3414
3415uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
3416{
3417        int size=0;
3418
3419        size=str_len_uni(&info->name);  /* the string length       */
3420        size=size+1;                    /* add the leading zero    */
3421        size=size*2;                    /* convert in char         */
3422
3423        return size;
3424}
3425
3426/*******************************************************************
3427return the size required by a struct in the stream
3428********************************************************************/ 
3429
3430uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
3431{
3432        int size=0;
3433
3434        size+=size_of_relative_string( &info->port_name );
3435        size+=size_of_relative_string( &info->monitor_name );
3436        size+=size_of_relative_string( &info->description );
3437
3438        size+=size_of_uint32( &info->port_type );
3439        size+=size_of_uint32( &info->reserved );
3440
3441        return size;
3442}
3443
3444/*******************************************************************
3445return the size required by a struct in the stream
3446********************************************************************/ 
3447
3448uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
3449{
3450        int size=0;
3451        size+=size_of_relative_string( &info->name );
3452
3453        return size;
3454}
3455
3456/*******************************************************************
3457return the size required by a struct in the stream
3458********************************************************************/ 
3459
3460uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
3461{
3462        int size=0;
3463        size+=size_of_relative_string( &info->name );
3464
3465        return size;
3466}
3467
3468/*******************************************************************
3469return the size required by a struct in the stream
3470********************************************************************/ 
3471uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
3472{
3473        uint32  size = 0; 
3474       
3475        if (!p)
3476                return 0;
3477       
3478        /* uint32(offset) + uint32(length) + length) */
3479        size += (size_of_uint32(&p->value_len)*2) + p->value_len;
3480        size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
3481       
3482        size += size_of_uint32(&p->type);
3483                       
3484        return size;
3485}
3486
3487/*******************************************************************
3488return the size required by a struct in the stream
3489********************************************************************/ 
3490
3491uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
3492{
3493        int size=0;
3494        size+=size_of_relative_string( &info->name );
3495
3496        return size;
3497}
3498
3499/*******************************************************************
3500return the size required by a struct in the stream
3501********************************************************************/ 
3502
3503uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
3504{
3505        int size=0;
3506        size+=size_of_relative_string( &info->name);
3507        size+=size_of_relative_string( &info->environment);
3508        size+=size_of_relative_string( &info->dll_name);
3509
3510        return size;
3511}
3512
3513/*******************************************************************
3514 * init a structure.
3515 ********************************************************************/
3516
3517BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
3518                               const POLICY_HND *hnd,
3519                               const fstring architecture,
3520                               uint32 level, uint32 clientmajor, uint32 clientminor,
3521                               RPC_BUFFER *buffer, uint32 offered)
3522{     
3523        if (q_u == NULL)
3524                return False;
3525
3526        memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3527
3528        init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
3529
3530        q_u->level=level;
3531        q_u->clientmajorversion=clientmajor;
3532        q_u->clientminorversion=clientminor;
3533
3534        q_u->buffer=buffer;
3535        q_u->offered=offered;
3536
3537        return True;
3538}
3539
3540/*******************************************************************
3541 * read a structure.
3542 * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3543 ********************************************************************/
3544
3545BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
3546{
3547        prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
3548        depth++;
3549
3550        if(!prs_align(ps))
3551                return False;
3552       
3553        if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3554                return False;
3555        if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
3556                return False;
3557        if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
3558                return False;
3559       
3560        if(!prs_align(ps))
3561                return False;
3562        if(!prs_uint32("level", ps, depth, &q_u->level))
3563                return False;
3564               
3565        if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3566                return False;
3567
3568        if(!prs_align(ps))
3569                return False;
3570
3571        if(!prs_uint32("offered", ps, depth, &q_u->offered))
3572                return False;
3573               
3574        if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
3575                return False;
3576        if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
3577                return False;
3578
3579        return True;
3580}
3581
3582/*******************************************************************
3583 * read a structure.
3584 * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3585 ********************************************************************/
3586
3587BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
3588{
3589        prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
3590        depth++;
3591
3592        if (!prs_align(ps))
3593                return False;
3594               
3595        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3596                return False;
3597
3598        if (!prs_align(ps))
3599                return False;
3600        if (!prs_uint32("needed", ps, depth, &r_u->needed))
3601                return False;
3602        if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
3603                return False;
3604        if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
3605                return False;           
3606        if (!prs_werror("status", ps, depth, &r_u->status))
3607                return False;
3608
3609        return True;           
3610}
3611
3612/*******************************************************************
3613 * init a structure.
3614 ********************************************************************/
3615
3616BOOL make_spoolss_q_enumprinters(
3617        SPOOL_Q_ENUMPRINTERS *q_u, 
3618        uint32 flags, 
3619        char *servername, 
3620        uint32 level, 
3621        RPC_BUFFER *buffer, 
3622        uint32 offered
3623)
3624{
3625        q_u->flags=flags;
3626       
3627        q_u->servername_ptr = (servername != NULL) ? 1 : 0;
3628        init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
3629
3630        q_u->level=level;
3631        q_u->buffer=buffer;
3632        q_u->offered=offered;
3633
3634        return True;
3635}
3636
3637/*******************************************************************
3638 * init a structure.
3639 ********************************************************************/
3640
3641BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
3642                                fstring servername, uint32 level, 
3643                                RPC_BUFFER *buffer, uint32 offered)
3644{
3645        q_u->name_ptr = (servername != NULL) ? 1 : 0;
3646        init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
3647
3648        q_u->level=level;
3649        q_u->buffer=buffer;
3650        q_u->offered=offered;
3651
3652        return True;
3653}
3654
3655/*******************************************************************
3656 * read a structure.
3657 * called from spoolss_enumprinters (srv_spoolss.c)
3658 ********************************************************************/
3659
3660BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
3661{
3662        prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
3663        depth++;
3664
3665        if (!prs_align(ps))
3666                return False;
3667
3668        if (!prs_uint32("flags", ps, depth, &q_u->flags))
3669                return False;
3670        if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
3671                return False;
3672
3673        if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
3674                return False;
3675               
3676        if (!prs_align(ps))
3677                return False;
3678        if (!prs_uint32("level", ps, depth, &q_u->level))
3679                return False;
3680
3681        if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3682                return False;
3683
3684        if (!prs_align(ps))
3685                return False;
3686        if (!prs_uint32("offered", ps, depth, &q_u->offered))
3687                return False;
3688
3689        return True;
3690}
3691
3692/*******************************************************************
3693 Parse a SPOOL_R_ENUMPRINTERS structure.
3694 ********************************************************************/
3695
3696BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
3697{
3698        prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
3699        depth++;
3700
3701        if (!prs_align(ps))
3702                return False;
3703               
3704        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3705                return False;
3706
3707        if (!prs_align(ps))
3708                return False;
3709               
3710        if (!prs_uint32("needed", ps, depth, &r_u->needed))
3711                return False;
3712               
3713        if (!prs_uint32("returned", ps, depth, &r_u->returned))
3714                return False;
3715               
3716        if (!prs_werror("status", ps, depth, &r_u->status))
3717                return False;
3718
3719        return True;           
3720}
3721
3722/*******************************************************************
3723 * write a structure.
3724 * called from spoolss_r_enum_printers (srv_spoolss.c)
3725 *
3726 ********************************************************************/
3727
3728BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
3729{       
3730        prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
3731        depth++;
3732
3733        if (!prs_align(ps))
3734                return False;
3735               
3736        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3737                return False;
3738
3739        if (!prs_align(ps))
3740                return False;
3741
3742        if (!prs_uint32("needed", ps, depth, &r_u->needed))
3743                return False;
3744               
3745        if (!prs_werror("status", ps, depth, &r_u->status))
3746                return False;
3747
3748        return True;           
3749}
3750
3751/*******************************************************************
3752 * read a structure.
3753 * called from spoolss_getprinter (srv_spoolss.c)
3754 ********************************************************************/
3755
3756BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
3757{
3758        prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
3759        depth++;
3760
3761        if (!prs_align(ps))
3762                return False;
3763
3764        if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3765                return False;
3766        if (!prs_uint32("level", ps, depth, &q_u->level))
3767                return False;
3768
3769        if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3770                return False;
3771
3772        if (!prs_align(ps))
3773                return False;
3774        if (!prs_uint32("offered", ps, depth, &q_u->offered))
3775                return False;
3776
3777        return True;
3778}
3779
3780/*******************************************************************
3781 * init a structure.
3782 ********************************************************************/
3783
3784BOOL make_spoolss_q_getprinter(
3785        TALLOC_CTX *mem_ctx,
3786        SPOOL_Q_GETPRINTER *q_u, 
3787        const POLICY_HND *hnd, 
3788        uint32 level, 
3789        RPC_BUFFER *buffer, 
3790        uint32 offered
3791)
3792{
3793        if (q_u == NULL)
3794        {
3795                return False;
3796        }
3797        memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3798
3799        q_u->level=level;
3800        q_u->buffer=buffer;
3801        q_u->offered=offered;
3802
3803        return True;
3804}
3805
3806/*******************************************************************
3807 * init a structure.
3808 ********************************************************************/
3809BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
3810                                const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
3811                                uint32 command)
3812{
3813        SEC_DESC *secdesc;
3814        DEVICEMODE *devmode;
3815
3816        if (!q_u || !info)
3817                return False;
3818       
3819        memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3820
3821        q_u->level = level;
3822        q_u->info.level = level;
3823        q_u->info.info_ptr = 1; /* Info is != NULL, see above */
3824        switch (level) {
3825
3826          /* There's no such thing as a setprinter level 1 */
3827
3828        case 2:
3829                secdesc = info->printers_2->secdesc;
3830                devmode = info->printers_2->devmode;
3831               
3832                make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
3833#if 1   /* JERRY TEST */
3834                q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3835                if (!q_u->secdesc_ctr)
3836                        return False;
3837                q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3838                q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3839                q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3840                q_u->secdesc_ctr->sec = secdesc;
3841
3842                q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
3843                q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
3844                q_u->devmode_ctr.devmode = devmode;
3845#else
3846                q_u->secdesc_ctr = NULL;
3847       
3848                q_u->devmode_ctr.devmode_ptr = 0;
3849                q_u->devmode_ctr.size = 0;
3850                q_u->devmode_ctr.devmode = NULL;
3851#endif
3852                break;
3853        case 3:
3854                secdesc = info->printers_3->secdesc;
3855               
3856                make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
3857               
3858                q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3859                if (!q_u->secdesc_ctr)
3860                        return False;
3861                q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3862                q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3863                q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3864                q_u->secdesc_ctr->sec = secdesc;
3865
3866                break;
3867        case 7:
3868                make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
3869                break;
3870
3871        default: 
3872                DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
3873                        break;
3874        }
3875
3876       
3877        q_u->command = command;
3878
3879        return True;
3880}
3881
3882
3883/*******************************************************************
3884********************************************************************/ 
3885
3886BOOL spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
3887{               
3888        prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
3889        depth++;
3890
3891        if(!prs_align(ps))
3892                return False;
3893       
3894        if(!prs_werror("status", ps, depth, &r_u->status))
3895                return False;
3896
3897        return True;
3898}
3899
3900/*******************************************************************
3901 Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
3902********************************************************************/ 
3903
3904BOOL spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
3905{
3906        uint32 ptr_sec_desc = 0;
3907
3908        prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
3909        depth++;
3910
3911        if(!prs_align(ps))
3912                return False;
3913
3914        if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
3915                return False;
3916        if(!prs_uint32("level", ps, depth, &q_u->level))
3917                return False;
3918       
3919        /* check for supported levels and structures we know about */
3920               
3921        switch ( q_u->level ) {
3922                case 0:
3923                case 2:
3924                case 3:
3925                case 7:
3926                        /* supported levels */
3927                        break;
3928                default:
3929                        DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
3930                                q_u->level));
3931                        return True;
3932        }
3933                       
3934
3935        if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3936                return False;
3937
3938        if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3939                return False;
3940       
3941        if(!prs_align(ps))
3942                return False;
3943
3944        switch (q_u->level)
3945        {
3946                case 2:
3947                {
3948                        ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3949                        break;
3950                }
3951                case 3:
3952                {
3953                        /* FIXME ! Our parsing here is wrong I think,
3954                         * but for a level3 it makes no sense for
3955                         * ptr_sec_desc to be NULL. JRA. Based on
3956                         * a Vista sniff from Martin Zielinski <mz@seh.de>.
3957                         */
3958                        if (UNMARSHALLING(ps)) {
3959                                ptr_sec_desc = 1;
3960                        } else {
3961                                ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3962                        }
3963                        break;
3964                }
3965        }
3966        if (ptr_sec_desc)
3967        {
3968                if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3969                        return False;
3970        } else {
3971                uint32 dummy = 0;
3972
3973                /* Parse a NULL security descriptor.  This should really
3974                   happen inside the sec_io_desc_buf() function. */
3975
3976                prs_debug(ps, depth, "", "sec_io_desc_buf");
3977                if (!prs_uint32("size", ps, depth + 1, &dummy))
3978                        return False;
3979                if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3980                        return False;
3981        }
3982       
3983        if(!prs_uint32("command", ps, depth, &q_u->command))
3984                return False;
3985
3986        return True;
3987}
3988
3989/*******************************************************************
3990********************************************************************/ 
3991
3992BOOL spoolss_io_r_fcpn(const char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
3993{               
3994        prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
3995        depth++;
3996
3997        if(!prs_align(ps))
3998                return False;
3999       
4000        if(!prs_werror("status", ps, depth, &r_u->status))
4001                return False;
4002
4003        return True;
4004}
4005
4006/*******************************************************************
4007********************************************************************/ 
4008
4009BOOL spoolss_io_q_fcpn(const char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
4010{
4011
4012        prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
4013        depth++;
4014
4015        if(!prs_align(ps))
4016                return False;
4017
4018        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4019                return False;
4020
4021        return True;
4022}
4023
4024
4025/*******************************************************************
4026********************************************************************/ 
4027
4028BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
4029{               
4030        prs_debug(ps, depth, desc, "");
4031        depth++;
4032
4033        if(!prs_align(ps))
4034                return False;
4035       
4036        if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4037                return False;
4038
4039        if(!prs_align(ps))
4040                return False;
4041       
4042        if(!prs_uint32("needed", ps, depth, &r_u->needed))
4043                return False;
4044
4045        if(!prs_werror("status", ps, depth, &r_u->status))
4046                return False;
4047
4048        return True;
4049}
4050
4051/*******************************************************************
4052********************************************************************/ 
4053
4054BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
4055{
4056        prs_debug(ps, depth, desc, "");
4057        depth++;
4058
4059        if(!prs_align(ps))
4060                return False;
4061
4062        if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4063                return False;
4064        if(!prs_uint32("level", ps, depth, &q_u->level))
4065                return False;
4066       
4067        if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4068                return False;
4069
4070        if(!prs_align(ps))
4071                return False;
4072       
4073        if(!prs_uint32("offered", ps, depth, &q_u->offered))
4074                return False;
4075
4076        return True;
4077}
4078
4079/*******************************************************************
4080********************************************************************/ 
4081
4082BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
4083{               
4084        prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
4085        depth++;
4086
4087        if (!prs_align(ps))
4088                return False;
4089               
4090        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4091                return False;
4092
4093        if (!prs_align(ps))
4094                return False;
4095               
4096        if (!prs_uint32("needed", ps, depth, &r_u->needed))
4097                return False;
4098               
4099        if (!prs_uint32("returned", ps, depth, &r_u->returned))
4100                return False;
4101               
4102        if (!prs_werror("status", ps, depth, &r_u->status))
4103                return False;
4104
4105        return True;           
4106}
4107
4108/*******************************************************************
4109********************************************************************/ 
4110
4111BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
4112                                uint32 firstjob,
4113                                uint32 numofjobs,
4114                                uint32 level,
4115                                RPC_BUFFER *buffer,
4116                                uint32 offered)
4117{
4118        if (q_u == NULL)
4119        {
4120                return False;
4121        }
4122        memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4123        q_u->firstjob = firstjob;
4124        q_u->numofjobs = numofjobs;
4125        q_u->level = level;
4126        q_u->buffer= buffer;
4127        q_u->offered = offered;
4128        return True;
4129}
4130
4131/*******************************************************************
4132********************************************************************/ 
4133
4134BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
4135{
4136        prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
4137        depth++;
4138
4139        if (!prs_align(ps))
4140                return False;
4141
4142        if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
4143                return False;
4144               
4145        if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
4146                return False;
4147        if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
4148                return False;
4149        if (!prs_uint32("level", ps, depth, &q_u->level))
4150                return False;
4151
4152        if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4153                return False;   
4154
4155        if(!prs_align(ps))
4156                return False;
4157
4158        if (!prs_uint32("offered", ps, depth, &q_u->offered))
4159                return False;
4160
4161        return True;
4162}
4163
4164/*******************************************************************
4165********************************************************************/ 
4166
4167BOOL spoolss_io_r_schedulejob(const char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
4168{               
4169        prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
4170        depth++;
4171
4172        if(!prs_align(ps))
4173                return False;
4174       
4175        if(!prs_werror("status", ps, depth, &r_u->status))
4176                return False;
4177
4178        return True;
4179}
4180
4181/*******************************************************************
4182********************************************************************/ 
4183
4184BOOL spoolss_io_q_schedulejob(const char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
4185{
4186        prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
4187        depth++;
4188
4189        if(!prs_align(ps))
4190                return False;
4191
4192        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4193                return False;
4194        if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4195                return False;
4196
4197        return True;
4198}
4199
4200/*******************************************************************
4201********************************************************************/ 
4202
4203BOOL spoolss_io_r_setjob(const char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
4204{               
4205        prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
4206        depth++;
4207
4208        if(!prs_align(ps))
4209                return False;
4210       
4211        if(!prs_werror("status", ps, depth, &r_u->status))
4212                return False;
4213
4214        return True;
4215}
4216
4217/*******************************************************************
4218********************************************************************/ 
4219
4220BOOL spoolss_io_q_setjob(const char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
4221{
4222        prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
4223        depth++;
4224
4225        if(!prs_align(ps))
4226                return False;
4227
4228        if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4229                return False;
4230        if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4231                return False;
4232        /*
4233         * level is usually 0. If (level!=0) then I'm in trouble !
4234         * I will try to generate setjob command with level!=0, one day.
4235         */
4236        if(!prs_uint32("level", ps, depth, &q_u->level))
4237                return False;
4238        if(!prs_uint32("command", ps, depth, &q_u->command))
4239                return False;
4240
4241        return True;
4242}
4243
4244/*******************************************************************
4245 Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
4246********************************************************************/ 
4247
4248BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
4249{
4250        prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
4251        depth++;
4252
4253        if (!prs_align(ps))
4254                return False;
4255               
4256        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4257                return False;
4258
4259        if (!prs_align(ps))
4260                return False;
4261               
4262        if (!prs_uint32("needed", ps, depth, &r_u->needed))
4263                return False;
4264               
4265        if (!prs_uint32("returned", ps, depth, &r_u->returned))
4266                return False;
4267               
4268        if (!prs_werror("status", ps, depth, &r_u->status))
4269                return False;
4270
4271        return True;           
4272}
4273
4274/*******************************************************************
4275 * init a structure.
4276 ********************************************************************/
4277
4278BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
4279                                const char *name,
4280                                const char *environment,
4281                                uint32 level,
4282                                RPC_BUFFER *buffer, uint32 offered)
4283{
4284        init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
4285        init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
4286
4287        q_u->level=level;
4288        q_u->buffer=buffer;
4289        q_u->offered=offered;
4290
4291        return True;
4292}
4293
4294/*******************************************************************
4295 Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
4296********************************************************************/ 
4297
4298BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
4299{
4300
4301        prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
4302        depth++;
4303
4304        if (!prs_align(ps))
4305                return False;
4306               
4307        if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4308                return False;
4309        if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
4310                return False;
4311               
4312        if (!prs_align(ps))
4313                return False;
4314        if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
4315                return False;
4316        if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4317                return False;
4318               
4319        if (!prs_align(ps))
4320                return False;
4321        if (!prs_uint32("level", ps, depth, &q_u->level))
4322                return False;
4323               
4324        if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4325                return False;
4326
4327        if (!prs_align(ps))
4328                return False;
4329               
4330        if (!prs_uint32("offered", ps, depth, &q_u->offered))
4331                return False;
4332
4333        return True;
4334}
4335
4336/*******************************************************************
4337********************************************************************/ 
4338
4339BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
4340{
4341
4342        prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
4343        depth++;
4344
4345        if (!prs_align(ps))
4346                return False;                   
4347        if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4348                return False;           
4349        if (!prs_uint32("level", ps, depth, &q_u->level))
4350                return False;   
4351       
4352        if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4353                return False;
4354
4355        if (!prs_align(ps))
4356                return False;
4357        if (!prs_uint32("offered", ps, depth, &q_u->offered))
4358                return False;
4359
4360        return True;
4361}
4362
4363/*******************************************************************
4364********************************************************************/ 
4365
4366BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
4367{
4368        prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
4369        depth++;
4370
4371        if (!prs_align(ps))
4372                return False;
4373               
4374        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4375                return False;
4376
4377        if (!prs_align(ps))
4378                return False;
4379               
4380        if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4381                return False;
4382               
4383        if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
4384                return False;
4385               
4386        if (!prs_werror("status", ps, depth, &r_u->status))
4387                return False;
4388
4389        return True;
4390}
4391
4392/*******************************************************************
4393********************************************************************/ 
4394
4395BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
4396{
4397
4398        prs_debug(ps, depth, desc, "spoolss_io_q_getform");
4399        depth++;
4400
4401        if (!prs_align(ps))
4402                return False;                   
4403        if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4404                return False;           
4405        if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
4406                return False;
4407
4408        if (!prs_align(ps))
4409                return False;
4410
4411        if (!prs_uint32("level", ps, depth, &q_u->level))
4412                return False;   
4413       
4414        if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4415                return False;
4416
4417        if (!prs_align(ps))
4418                return False;
4419        if (!prs_uint32("offered", ps, depth, &q_u->offered))
4420                return False;
4421
4422        return True;
4423}
4424
4425/*******************************************************************
4426********************************************************************/ 
4427
4428BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
4429{
4430        prs_debug(ps, depth, desc, "spoolss_io_r_getform");
4431        depth++;
4432
4433        if (!prs_align(ps))
4434                return False;
4435               
4436        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4437                return False;
4438
4439        if (!prs_align(ps))
4440                return False;
4441               
4442        if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4443                return False;
4444               
4445        if (!prs_werror("status", ps, depth, &r_u->status))
4446                return False;
4447
4448        return True;
4449}
4450
4451/*******************************************************************
4452 Parse a SPOOL_R_ENUMPORTS structure.
4453********************************************************************/ 
4454
4455BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
4456{
4457        prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
4458        depth++;
4459
4460        if (!prs_align(ps))
4461                return False;
4462               
4463        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4464                return False;
4465
4466        if (!prs_align(ps))
4467                return False;
4468               
4469        if (!prs_uint32("needed", ps, depth, &r_u->needed))
4470                return False;
4471               
4472        if (!prs_uint32("returned", ps, depth, &r_u->returned))
4473                return False;
4474               
4475        if (!prs_werror("status", ps, depth, &r_u->status))
4476                return False;
4477
4478        return True;           
4479}
4480
4481/*******************************************************************
4482********************************************************************/ 
4483
4484BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
4485{
4486        prs_debug(ps, depth, desc, "");
4487        depth++;
4488
4489        if (!prs_align(ps))
4490                return False;
4491
4492        if (!prs_uint32("", ps, depth, &q_u->name_ptr))
4493                return False;
4494        if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
4495                return False;
4496
4497        if (!prs_align(ps))
4498                return False;
4499        if (!prs_uint32("level", ps, depth, &q_u->level))
4500                return False;
4501               
4502        if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4503                return False;
4504
4505        if (!prs_align(ps))
4506                return False;
4507        if (!prs_uint32("offered", ps, depth, &q_u->offered))
4508                return False;
4509
4510        return True;
4511}
4512
4513/*******************************************************************
4514 Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
4515********************************************************************/ 
4516
4517BOOL spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
4518{       
4519        prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
4520        depth++;
4521               
4522        if(!prs_align(ps))
4523                return False;
4524
4525        if(!prs_uint32("flags", ps, depth, &il->flags))
4526                return False;
4527        if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
4528                return False;
4529        if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4530                return False;
4531        if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4532                return False;
4533               
4534        if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
4535                return False;
4536        if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4537                return False;
4538        if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4539                return False;
4540
4541        return True;
4542}
4543
4544/*******************************************************************
4545 Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
4546********************************************************************/ 
4547
4548BOOL spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
4549{       
4550        prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
4551        depth++;
4552               
4553        if(!prs_align(ps))
4554                return False;
4555
4556        if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4557                return False;
4558
4559        return True;
4560}
4561
4562/*******************************************************************
4563 Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
4564********************************************************************/ 
4565
4566BOOL spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
4567{       
4568        prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
4569        depth++;
4570               
4571        if(!prs_align(ps))
4572                return False;
4573
4574        if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
4575                return False;
4576        if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
4577                return False;
4578        if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
4579                return False;
4580        if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
4581                return False;
4582
4583        if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
4584                return False;
4585        if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4586                return False;
4587        if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
4588                return False;
4589        if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
4590                return False;
4591        if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
4592                return False;
4593        if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
4594                return False;
4595        if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
4596                return False;
4597        if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
4598                return False;
4599        if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4600                return False;
4601
4602        if(!prs_uint32("attributes", ps, depth, &il->attributes))
4603                return False;
4604        if(!prs_uint32("priority", ps, depth, &il->priority))
4605                return False;
4606        if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
4607                return False;
4608        if(!prs_uint32("starttime", ps, depth, &il->starttime))
4609                return False;
4610        if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
4611                return False;
4612        if(!prs_uint32("status", ps, depth, &il->status))
4613                return False;
4614        if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
4615                return False;
4616        if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
4617                return False;
4618
4619        if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
4620                return False;
4621        if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
4622                return False;
4623        if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
4624                return False;
4625        if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
4626                return False;
4627        if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
4628                return False;
4629        if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4630                return False;
4631        if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
4632                return False;
4633        if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
4634                return False;
4635        if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
4636                return False;
4637        if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
4638                return False;
4639        if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
4640                return False;
4641
4642        return True;
4643}
4644
4645BOOL spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
4646{       
4647        prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
4648        depth++;
4649               
4650        if(!prs_align(ps))
4651                return False;
4652
4653        if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
4654                return False;
4655        if(!prs_uint32("action", ps, depth, &il->action))
4656                return False;
4657
4658        if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
4659                return False;
4660        return True;
4661}
4662
4663/*******************************************************************
4664********************************************************************/ 
4665
4666BOOL spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
4667{
4668        prs_debug(ps, depth, desc, "spool_io_printer_info_level");
4669        depth++;
4670
4671        if(!prs_align(ps))
4672                return False;
4673        if(!prs_uint32("level", ps, depth, &il->level))
4674                return False;
4675        if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
4676                return False;
4677       
4678        /* if no struct inside just return */
4679        if (il->info_ptr==0) {
4680                if (UNMARSHALLING(ps)) {
4681                        il->info_1=NULL;
4682                        il->info_2=NULL;
4683                }
4684                return True;
4685        }
4686                       
4687        switch (il->level) {
4688                /*
4689                 * level 0 is used by setprinter when managing the queue
4690                 * (hold, stop, start a queue)
4691                 */
4692                case 0:
4693                        break;
4694                /* DOCUMENT ME!!! What is level 1 used for? */
4695                case 1:
4696                {
4697                        if (UNMARSHALLING(ps)) {
4698                                if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
4699                                        return False;
4700                        }
4701                        if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
4702                                return False;
4703                        break;         
4704                }
4705                /*
4706                 * level 2 is used by addprinter
4707                 * and by setprinter when updating printer's info
4708                 */     
4709                case 2:
4710                        if (UNMARSHALLING(ps)) {
4711                                if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
4712                                        return False;
4713                        }
4714                        if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
4715                                return False;
4716                        break;         
4717                /* DOCUMENT ME!!! What is level 3 used for? */
4718                case 3:
4719                {
4720                        if (UNMARSHALLING(ps)) {
4721                                if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
4722                                        return False;
4723                        }
4724                        if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
4725                                return False;
4726                        break;         
4727                }
4728                case 7:
4729                        if (UNMARSHALLING(ps))
4730                                if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
4731                                        return False;
4732                        if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
4733                                return False;
4734                        break;
4735        }
4736
4737        return True;
4738}
4739
4740/*******************************************************************
4741********************************************************************/ 
4742
4743BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
4744{
4745        uint32 ptr_sec_desc = 0;
4746
4747        prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
4748        depth++;
4749
4750        if(!prs_align(ps))
4751                return False;
4752
4753        if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
4754                return False;
4755        if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
4756                return False;
4757
4758        if(!prs_align(ps))
4759                return False;
4760
4761        if(!prs_uint32("info_level", ps, depth, &q_u->level))
4762                return False;
4763       
4764        if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4765                return False;
4766       
4767        if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4768                return False;
4769
4770        if(!prs_align(ps))
4771                return False;
4772
4773        switch (q_u->level) {
4774                case 2:
4775                        ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4776                        break;
4777                case 3:
4778                        ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4779                        break;
4780        }
4781        if (ptr_sec_desc) {
4782                if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
4783                        return False;
4784        } else {
4785                uint32 dummy;
4786
4787                /* Parse a NULL security descriptor.  This should really
4788                        happen inside the sec_io_desc_buf() function. */
4789
4790                prs_debug(ps, depth, "", "sec_io_desc_buf");
4791                if (!prs_uint32("size", ps, depth + 1, &dummy))
4792                        return False;
4793                if (!prs_uint32("ptr", ps, depth + 1, &dummy))
4794                        return False;
4795        }
4796
4797        if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
4798                return False;
4799        if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
4800                return False;
4801
4802        return True;
4803}
4804
4805/*******************************************************************
4806********************************************************************/ 
4807
4808BOOL spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
4809                               prs_struct *ps, int depth)
4810{
4811        prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
4812        depth++;
4813       
4814        if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
4815                return False;
4816
4817        if(!prs_werror("status", ps, depth, &r_u->status))
4818                return False;
4819
4820        return True;
4821}
4822
4823/*******************************************************************
4824********************************************************************/ 
4825
4826BOOL spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
4827                                          prs_struct *ps, int depth)
4828{       
4829        SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
4830       
4831        prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
4832        depth++;
4833               
4834        /* reading */
4835        if (UNMARSHALLING(ps)) {
4836                il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
4837                if(il == NULL)
4838                        return False;
4839                *q_u=il;
4840        }
4841        else {
4842                il=*q_u;
4843        }
4844       
4845        if(!prs_align(ps))
4846                return False;
4847
4848        if(!prs_uint32("cversion", ps, depth, &il->cversion))
4849                return False;
4850        if(!prs_uint32("name", ps, depth, &il->name_ptr))
4851                return False;
4852        if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
4853                return False;
4854        if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
4855                return False;
4856        if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
4857                return False;
4858        if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
4859                return False;
4860        if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
4861                return False;
4862        if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
4863                return False;
4864        if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4865                return False;
4866        if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
4867                return False;
4868        if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
4869                return False;
4870
4871        if(!prs_align(ps))
4872                return False;
4873       
4874        if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4875                return False;
4876        if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4877                return False;
4878        if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4879                return False;
4880        if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4881                return False;
4882        if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4883                return False;
4884        if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4885                return False;
4886        if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4887                return False;
4888        if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4889                return False;
4890
4891        if(!prs_align(ps))
4892                return False;
4893               
4894        if (il->dependentfiles_ptr)
4895                smb_io_buffer5("", &il->dependentfiles, ps, depth);
4896
4897        return True;
4898}
4899
4900/*******************************************************************
4901parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
4902********************************************************************/ 
4903
4904BOOL spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
4905                                          prs_struct *ps, int depth)
4906{       
4907        SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
4908       
4909        prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
4910        depth++;
4911               
4912        /* reading */
4913        if (UNMARSHALLING(ps)) {
4914                il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
4915                if(il == NULL)
4916                        return False;
4917                *q_u=il;
4918        }
4919        else {
4920                il=*q_u;
4921        }
4922       
4923        if(!prs_align(ps))
4924                return False;
4925
4926        /*
4927         * I know this seems weird, but I have no other explanation.
4928         * This is observed behavior on both NT4 and 2K servers.
4929         * --jerry
4930         */
4931         
4932        if (!prs_align_uint64(ps))
4933                return False;
4934
4935        /* parse the main elements the packet */
4936
4937        if(!prs_uint32("cversion       ", ps, depth, &il->version))
4938                return False;
4939        if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
4940                return False;
4941        if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
4942                return False;
4943        if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
4944                return False;
4945        if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
4946                return False;
4947        if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
4948                return False;
4949        if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
4950                return False;
4951        if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
4952                return False;
4953        if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4954                return False;
4955        if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
4956                return False;
4957        if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
4958                return False;
4959        if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
4960                return False;
4961        if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
4962                return False;
4963        if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
4964                return False;
4965        if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
4966                return False;
4967        if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
4968                return False;
4969        if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
4970                return False;
4971        if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
4972                return False;
4973        if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
4974                return False;
4975        if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
4976                return False;
4977
4978        /* parse the structures in the packet */
4979
4980        if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4981                return False;
4982        if(!prs_align(ps))
4983                return False;
4984
4985        if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4986                return False;
4987        if(!prs_align(ps))
4988                return False;
4989
4990        if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4991                return False;
4992        if(!prs_align(ps))
4993                return False;
4994
4995        if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4996                return False;
4997        if(!prs_align(ps))
4998                return False;
4999
5000        if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
5001                return False;
5002        if(!prs_align(ps))
5003                return False;
5004
5005        if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
5006                return False;
5007        if(!prs_align(ps))
5008                return False;
5009
5010        if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
5011                return False;
5012        if(!prs_align(ps))
5013                return False;
5014
5015        if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
5016                return False;
5017        if(!prs_align(ps))
5018                return False;
5019        if (il->dependentfiles_ptr) {
5020                if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
5021                        return False;
5022                if(!prs_align(ps))
5023                        return False;
5024        }
5025        if (il->previousnames_ptr) {
5026                if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
5027                        return False;
5028                if(!prs_align(ps))
5029                        return False;
5030        }
5031        if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
5032                return False;
5033        if(!prs_align(ps))
5034                return False;
5035        if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
5036                return False;
5037        if(!prs_align(ps))
5038                return False;
5039        if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
5040                return False;
5041        if(!prs_align(ps))
5042                return False;
5043        if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
5044                return False;
5045
5046        return True;
5047}
5048
5049/*******************************************************************
5050 convert a buffer of UNICODE strings null terminated
5051 the buffer is terminated by a NULL
5052 
5053 convert to an dos codepage array (null terminated)
5054 
5055 dynamically allocate memory
5056 
5057********************************************************************/ 
5058
5059static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
5060{
5061        fstring f;
5062        int n = 0;
5063        char *src;
5064
5065        if (buf5==NULL)
5066                return False;
5067
5068        src = (char *)buf5->buffer;
5069        *ar = SMB_MALLOC_ARRAY(fstring, 1);
5070        if (!*ar) {
5071                return False;
5072        }
5073
5074        while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
5075                rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
5076                src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
5077                *ar = SMB_REALLOC_ARRAY(*ar, fstring, n+2);
5078                if (!*ar) {
5079                        return False;
5080                }
5081                fstrcpy((*ar)[n], f);
5082                n++;
5083        }
5084
5085        fstrcpy((*ar)[n], "");
5086 
5087        return True;
5088}
5089
5090/*******************************************************************
5091 read a UNICODE array with null terminated strings
5092 and null terminated array
5093 and size of array at beginning
5094********************************************************************/ 
5095
5096BOOL smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
5097{
5098        if (buffer==NULL) return False;
5099
5100        buffer->offset=0;
5101        buffer->uni_str_len=buffer->uni_max_len;
5102       
5103        if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
5104                return False;
5105
5106        if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
5107                return False;
5108
5109        return True;
5110}
5111
5112/*******************************************************************
5113********************************************************************/ 
5114
5115BOOL spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
5116{
5117        prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
5118        depth++;
5119
5120        if(!prs_align(ps))
5121                return False;
5122        if(!prs_uint32("level", ps, depth, &il->level))
5123                return False;
5124        if(!prs_uint32("ptr", ps, depth, &il->ptr))
5125                return False;
5126
5127        if (il->ptr==0)
5128                return True;
5129               
5130        switch (il->level) {
5131                case 3:
5132                        if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
5133                                return False;
5134                        break;         
5135                case 6:
5136                        if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
5137                                return False;
5138                        break;         
5139        default:
5140                return False;
5141        }
5142
5143        return True;
5144}
5145
5146/*******************************************************************
5147 init a SPOOL_Q_ADDPRINTERDRIVER struct
5148 ******************************************************************/
5149
5150BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
5151                                SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
5152                                uint32 level, PRINTER_DRIVER_CTR *info)
5153{
5154        DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
5155       
5156        if (!srv_name || !info) {
5157                return False;
5158        }
5159
5160        q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */
5161        init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
5162       
5163        q_u->level = level;
5164       
5165        q_u->info.level = level;
5166        q_u->info.ptr = 1;      /* Info is != NULL, see above */
5167        switch (level)
5168        {
5169        /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
5170        case 3 :
5171                make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
5172                break;
5173               
5174        default:
5175                DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
5176                break;
5177        }
5178       
5179        return True;
5180}
5181
5182BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, 
5183        SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
5184                                DRIVER_INFO_3 *info3)
5185{
5186        uint32          len = 0;
5187        SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
5188
5189        if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
5190                return False;
5191       
5192        inf->cversion   = info3->version;
5193        inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
5194        inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
5195        inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
5196        inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
5197        inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
5198        inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
5199        inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
5200        inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
5201
5202        init_unistr2_from_unistr(&inf->name, &info3->name);
5203        init_unistr2_from_unistr(&inf->environment, &info3->architecture);
5204        init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
5205        init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
5206        init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
5207        init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
5208        init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
5209        init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
5210
5211        if (info3->dependentfiles) {
5212                BOOL done = False;
5213                BOOL null_char = False;
5214                uint16 *ptr = info3->dependentfiles;
5215
5216                while (!done) {
5217                        switch (*ptr) {
5218                                case 0:
5219                                        /* the null_char BOOL is used to help locate
5220                                           two '\0's back to back */
5221                                        if (null_char) {
5222                                                done = True;
5223                                        } else {
5224                                                null_char = True;
5225                                        }
5226                                        break;
5227                                       
5228                                default:
5229                                        null_char = False;
5230                                        break;                         
5231                        }
5232                        len++;
5233                        ptr++;
5234                }
5235        }
5236
5237        inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
5238        inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0;
5239        if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) {
5240                SAFE_FREE(inf);
5241                return False;
5242        }
5243       
5244        *spool_drv_info = inf;
5245       
5246        return True;
5247}
5248
5249/*******************************************************************
5250 make a BUFFER5 struct from a uint16*
5251 ******************************************************************/
5252
5253BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
5254{
5255
5256        buf5->buf_len = len;
5257        if (src) {
5258                if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
5259                        DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
5260                        return False;
5261                }
5262        } else {
5263                buf5->buffer=NULL;
5264        }
5265       
5266        return True;
5267}
5268
5269/*******************************************************************
5270 fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5271 ********************************************************************/ 
5272
5273BOOL spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5274{
5275        prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
5276        depth++;
5277
5278        if(!prs_align(ps))
5279                return False;
5280
5281        if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5282                return False;
5283        if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5284                return False;
5285               
5286        if(!prs_align(ps))
5287                return False;
5288        if(!prs_uint32("info_level", ps, depth, &q_u->level))
5289                return False;
5290
5291        if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5292                return False;
5293
5294        return True;
5295}
5296
5297/*******************************************************************
5298********************************************************************/ 
5299
5300BOOL spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5301{
5302        prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
5303        depth++;
5304
5305        if(!prs_werror("status", ps, depth, &q_u->status))
5306                return False;
5307
5308        return True;
5309}
5310
5311/*******************************************************************
5312 fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5313 ********************************************************************/ 
5314
5315BOOL spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5316{
5317        prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
5318        depth++;
5319
5320        if(!prs_align(ps))
5321                return False;
5322
5323        if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5324                return False;
5325        if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5326                return False;
5327               
5328        if(!prs_align(ps))
5329                return False;
5330        if(!prs_uint32("info_level", ps, depth, &q_u->level))
5331                return False;
5332
5333        if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5334                return False;
5335
5336        if(!prs_align(ps))
5337                return False;
5338        if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
5339                return False;
5340               
5341        return True;
5342}
5343
5344/*******************************************************************
5345********************************************************************/ 
5346
5347BOOL spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5348{
5349        prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
5350        depth++;
5351
5352        if(!prs_werror("status", ps, depth, &q_u->status))
5353                return False;
5354
5355        return True;
5356}
5357
5358/*******************************************************************
5359********************************************************************/ 
5360
5361BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
5362                                NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
5363{
5364        NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
5365       
5366        DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
5367       
5368        if (*asc==NULL)
5369        {
5370                *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
5371                if(*asc == NULL)
5372                        return False;
5373                ZERO_STRUCTP(*asc);
5374        }       
5375
5376        d=*asc;
5377
5378        d->cversion=uni->cversion;
5379
5380        unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5381        unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5382        unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5383        unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5384        unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5385        unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5386        unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5387        unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5388
5389        DEBUGADD(8,( "version:         %d\n", d->cversion));
5390        DEBUGADD(8,( "name:            %s\n", d->name));
5391        DEBUGADD(8,( "environment:     %s\n", d->environment));
5392        DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5393        DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5394        DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5395        DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5396        DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5397        DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5398
5399        if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5400                return True;
5401       
5402        SAFE_FREE(*asc);
5403        return False;
5404}
5405
5406/*******************************************************************
5407********************************************************************/ 
5408BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
5409                                NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
5410{
5411        NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
5412       
5413        DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
5414       
5415        if (*asc==NULL)
5416        {
5417                *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
5418                if(*asc == NULL)
5419                        return False;
5420                ZERO_STRUCTP(*asc);
5421        }       
5422
5423        d=*asc;
5424
5425        d->version=uni->version;
5426
5427        unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5428        unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5429        unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5430        unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5431        unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5432        unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5433        unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5434        unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5435
5436        DEBUGADD(8,( "version:         %d\n", d->version));
5437        DEBUGADD(8,( "name:            %s\n", d->name));
5438        DEBUGADD(8,( "environment:     %s\n", d->environment));
5439        DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5440        DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5441        DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5442        DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5443        DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5444        DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5445
5446        if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5447                goto error;
5448        if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
5449                goto error;
5450       
5451        return True;
5452       
5453error:
5454        SAFE_FREE(*asc);
5455        return False;
5456}
5457
5458BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
5459                              NT_PRINTER_INFO_LEVEL_2  *d)
5460{
5461        DEBUG(7,("Converting from UNICODE to ASCII\n"));
5462       
5463        d->attributes=uni->attributes;
5464        d->priority=uni->priority;
5465        d->default_priority=uni->default_priority;
5466        d->starttime=uni->starttime;
5467        d->untiltime=uni->untiltime;
5468        d->status=uni->status;
5469        d->cjobs=uni->cjobs;
5470       
5471        unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
5472        unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
5473        unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
5474        unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
5475        unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
5476        unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
5477        unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
5478        unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
5479        unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
5480        unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
5481        unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
5482
5483        return True;
5484}
5485
5486/*******************************************************************
5487 * init a structure.
5488 ********************************************************************/
5489
5490BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
5491                                fstring servername, fstring env_name, uint32 level,
5492                                RPC_BUFFER *buffer, uint32 offered)
5493{
5494        init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
5495        init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
5496
5497        q_u->level=level;
5498        q_u->buffer=buffer;
5499        q_u->offered=offered;
5500
5501        return True;
5502}
5503
5504/*******************************************************************
5505 Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
5506********************************************************************/ 
5507
5508BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
5509{
5510        prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
5511        depth++;
5512
5513        if(!prs_align(ps))
5514                return False;
5515        if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5516                return False;
5517        if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
5518                return False;
5519
5520        if(!prs_align(ps))
5521                return False;
5522               
5523        if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
5524                return False;
5525        if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5526                return False;
5527               
5528        if(!prs_align(ps))
5529                return False;
5530
5531        if(!prs_uint32("level", ps, depth, &q_u->level))
5532                return False;
5533               
5534        if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5535                return False;
5536               
5537        if(!prs_align(ps))
5538                return False;
5539               
5540        if(!prs_uint32("offered", ps, depth, &q_u->offered))
5541                return False;
5542
5543        return True;
5544}
5545
5546/*******************************************************************
5547 Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
5548********************************************************************/ 
5549
5550BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
5551{               
5552        prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
5553        depth++;
5554
5555        if (!prs_align(ps))
5556                return False;
5557               
5558        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5559                return False;
5560
5561        if (!prs_align(ps))
5562                return False;
5563               
5564        if (!prs_uint32("needed", ps, depth, &r_u->needed))
5565                return False;
5566               
5567        if (!prs_werror("status", ps, depth, &r_u->status))
5568                return False;
5569
5570        return True;           
5571}
5572
5573/*******************************************************************
5574********************************************************************/ 
5575
5576BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
5577{               
5578        prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
5579        depth++;
5580
5581        if (!prs_align(ps))
5582                return False;
5583               
5584        if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5585                return False;
5586
5587        if (!prs_align(ps))
5588                return False;
5589               
5590        if (!prs_uint32("needed", ps, depth, &r_u->needed))
5591                return False;
5592               
5593        if (!prs_uint32("returned", ps, depth, &r_u->returned))
5594                return False;
5595               
5596        if (!prs_werror("status", ps, depth, &r_u->status))
5597                return False;
5598
5599        return True;           
5600}
5601
5602/*******************************************************************
5603********************************************************************/ 
5604
5605BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
5606{
5607        prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
5608        depth++;
5609
5610        if (!prs_align(ps))
5611                return False;
5612               
5613        if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5614                return False;
5615        if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5616                return False;
5617               
5618        if (!prs_align(ps))
5619                return False;
5620               
5621        if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
5622                return False;
5623        if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5624                return False;
5625       
5626        if (!prs_align(ps))
5627                return False;
5628               
5629        if (!prs_uint32("level", ps, depth, &q_u->level))
5630                return False;
5631               
5632        if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5633                return False;
5634
5635        if (!prs_align(ps))
5636                return False;
5637
5638        if (!prs_uint32("offered", ps, depth, &q_u->offered))
5639                return False;
5640
5641        return True;
5642}
5643
5644/*******************************************************************
5645********************************************************************/ 
5646
5647BOOL spoolss_io_q_addprintprocessor(const char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
5648{
5649        prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
5650        depth++;
5651
5652        if (!prs_align(ps))
5653                return False;
5654               
5655        if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
5656                return False;
5657        if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
5658                return False;
5659               
5660        if (!prs_align(ps))
5661                return False;
5662        if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
5663                return False;
5664               
5665        if (!prs_align(ps))
5666                return False;
5667        if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
5668                return False;
5669
5670        if (!prs_align(ps))
5671                return False;
5672        if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5673                return False;
5674
5675        return True;
5676}
5677
5678/*******************************************************************
5679********************************************************************/ 
5680
5681BOOL spoolss_io_r_addprintprocessor(const char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
5682{               
5683        prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor"