r14080: Fix Coverity bug #18. Ensure non-null before ref.
[bbaumbach/samba-autobuild/.git] / source / rpc_parse / parse_spoolss.c
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 /*******************************************************************
32 This should be moved in a more generic lib.
33 ********************************************************************/  
34
35 BOOL 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
60 BOOL 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 /*******************************************************************
75 reads or writes an DOC_INFO structure.
76 ********************************************************************/  
77
78 static 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 /*******************************************************************
106 reads or writes an DOC_INFO structure.
107 ********************************************************************/  
108
109 static 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 /*******************************************************************
155 reads or writes an DOC_INFO_CONTAINER structure.
156 ********************************************************************/  
157
158 static 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 /*******************************************************************
178 reads 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
185 static 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 /*******************************************************************
210 reads or writes an NOTIFY OPTION TYPE DATA.
211 ********************************************************************/  
212
213 static 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 /*******************************************************************
241 reads or writes an NOTIFY OPTION structure.
242 ********************************************************************/  
243
244 static 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 /*******************************************************************
273 reads or writes an NOTIFY OPTION structure.
274 ********************************************************************/  
275
276 static 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 /*******************************************************************
304 reads or writes an NOTIFY INFO DATA structure.
305 ********************************************************************/  
306
307 static 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 /*******************************************************************
383 reads or writes an NOTIFY INFO DATA structure.
384 ********************************************************************/  
385
386 BOOL 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 /*******************************************************************
514 reads or writes an NOTIFY INFO structure.
515 ********************************************************************/  
516
517 static 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
553 BOOL 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
592 static 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
629 BOOL 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
814 static 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
859 static 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
892 BOOL 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         init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
903
904         q_u->printer_default.datatype_ptr = 0;
905
906         q_u->printer_default.devmode_cont.size=0;
907         q_u->printer_default.devmode_cont.devmode_ptr=0;
908         q_u->printer_default.devmode_cont.devmode=NULL;
909         q_u->printer_default.access_required=access_required;
910
911         q_u->user_switch = 1;
912         
913         q_u->user_ctr.level                 = 1;
914         q_u->user_ctr.user.user1            = TALLOC_P( get_talloc_ctx(), SPOOL_USER_1 );
915         q_u->user_ctr.user.user1->size      = strlen(clientname) + strlen(user_name) + 10;
916         q_u->user_ctr.user.user1->build     = 1381;
917         q_u->user_ctr.user.user1->major     = 2;
918         q_u->user_ctr.user.user1->minor     = 0;
919         q_u->user_ctr.user.user1->processor = 0;
920
921         q_u->user_ctr.user.user1->client_name = TALLOC_P( get_talloc_ctx(), UNISTR2 );
922         q_u->user_ctr.user.user1->user_name   = TALLOC_P( get_talloc_ctx(), UNISTR2 );
923
924         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
925         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
926         
927         return True;
928 }
929
930 /*******************************************************************
931  * init a structure.
932  ********************************************************************/
933
934 BOOL make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
935         const char *srv_name, const char* clientname, const char* user_name,
936         uint32 level, PRINTER_INFO_CTR *ctr)
937 {
938         DEBUG(5,("make_spoolss_q_addprinterex\n"));
939         
940         if (!ctr || !ctr->printers_2) 
941                 return False;
942
943         ZERO_STRUCTP(q_u);
944
945         q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
946         init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
947
948         q_u->level = level;
949         
950         q_u->info.level = level;
951         q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
952         switch (level) {
953                 case 2:
954                         /* init q_u->info.info2 from *info */
955                         if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
956                                 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
957                                 return False;
958                         }
959                         break;
960                 default :
961                         break;
962         }
963
964         q_u->user_switch=1;
965
966         q_u->user_ctr.level                 = 1;
967         q_u->user_ctr.user.user1            = TALLOC_P( get_talloc_ctx(), SPOOL_USER_1 );
968         q_u->user_ctr.user.user1->build     = 1381;
969         q_u->user_ctr.user.user1->major     = 2; 
970         q_u->user_ctr.user.user1->minor     = 0;
971         q_u->user_ctr.user.user1->processor = 0;
972
973         q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
974         q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
975
976         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
977         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
978
979         q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
980                                    q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
981         
982         return True;
983 }
984         
985 /*******************************************************************
986 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
987 *******************************************************************/
988
989 BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
990                                 PRINTER_INFO_2 *info)
991 {
992
993         SPOOL_PRINTER_INFO_LEVEL_2 *inf;
994
995         /* allocate the necessary memory */
996         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
997                 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
998                 return False;
999         }
1000         
1001         inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
1002         inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
1003         inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
1004         inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
1005         inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
1006         inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
1007         inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
1008         inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
1009         inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
1010         inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
1011         inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
1012         inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
1013         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
1014         inf->attributes         = info->attributes;
1015         inf->priority           = info->priority;
1016         inf->default_priority   = info->defaultpriority;
1017         inf->starttime          = info->starttime;
1018         inf->untiltime          = info->untiltime;
1019         inf->cjobs              = info->cjobs;
1020         inf->averageppm = info->averageppm;
1021         init_unistr2_from_unistr(&inf->servername,      &info->servername);
1022         init_unistr2_from_unistr(&inf->printername,     &info->printername);
1023         init_unistr2_from_unistr(&inf->sharename,       &info->sharename);
1024         init_unistr2_from_unistr(&inf->portname,        &info->portname);
1025         init_unistr2_from_unistr(&inf->drivername,      &info->drivername);
1026         init_unistr2_from_unistr(&inf->comment,         &info->comment);
1027         init_unistr2_from_unistr(&inf->location,        &info->location);
1028         init_unistr2_from_unistr(&inf->sepfile,         &info->sepfile);
1029         init_unistr2_from_unistr(&inf->printprocessor,  &info->printprocessor);
1030         init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
1031         init_unistr2_from_unistr(&inf->parameters,      &info->parameters);
1032         init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
1033
1034         *spool_info2 = inf;
1035
1036         return True;
1037 }
1038
1039 /*******************************************************************
1040 create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
1041 *******************************************************************/
1042
1043 BOOL make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, 
1044                                 PRINTER_INFO_3 *info)
1045 {
1046
1047         SPOOL_PRINTER_INFO_LEVEL_3 *inf;
1048
1049         /* allocate the necessary memory */
1050         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
1051                 DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
1052                 return False;
1053         }
1054         
1055         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
1056
1057         *spool_info3 = inf;
1058
1059         return True;
1060 }
1061
1062 /*******************************************************************
1063 create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
1064 *******************************************************************/
1065
1066 BOOL make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, 
1067                                 PRINTER_INFO_7 *info)
1068 {
1069
1070         SPOOL_PRINTER_INFO_LEVEL_7 *inf;
1071
1072         /* allocate the necessary memory */
1073         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
1074                 DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
1075                 return False;
1076         }
1077
1078         inf->guid_ptr           = (info->guid.buffer!=NULL)?1:0;
1079         inf->action             = info->action;
1080         init_unistr2_from_unistr(&inf->guid,            &info->guid);
1081
1082         *spool_info7 = inf;
1083
1084         return True;
1085 }
1086
1087
1088 /*******************************************************************
1089  * read a structure.
1090  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1091  ********************************************************************/
1092
1093 BOOL spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
1094 {
1095         if (q_u == NULL)
1096                 return False;
1097
1098         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
1099         depth++;
1100
1101         if (!prs_align(ps))
1102                 return False;
1103
1104         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1105                 return False;
1106         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1107                 return False;
1108         
1109         if (!prs_align(ps))
1110                 return False;
1111
1112         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1113                 return False;
1114                 
1115         return True;
1116 }
1117
1118 /*******************************************************************
1119  * write a structure.
1120  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1121  * called from spoolss_open_printer_ex (cli_spoolss.c)
1122  ********************************************************************/
1123
1124 BOOL spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
1125 {
1126         if (r_u == NULL) return False;
1127
1128         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
1129         depth++;
1130         
1131         if (!prs_align(ps))
1132                 return False;
1133
1134         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1135                 return False;   
1136
1137         if (!prs_werror("status code", ps, depth, &(r_u->status)))
1138                 return False;
1139                 
1140         return True;
1141 }
1142
1143
1144 /*******************************************************************
1145  * read a structure.
1146  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1147  ********************************************************************/
1148
1149 BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
1150 {
1151         if (q_u == NULL)
1152                 return False;
1153
1154         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
1155         depth++;
1156
1157         if (!prs_align(ps))
1158                 return False;
1159
1160         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1161                 return False;
1162         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1163                 return False;
1164         
1165         if (!prs_align(ps))
1166                 return False;
1167
1168         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1169                 return False;
1170
1171         if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
1172                 return False;   
1173         if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
1174                 return False;
1175         
1176         return True;
1177 }
1178
1179 /*******************************************************************
1180  * write a structure.
1181  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1182  * called from spoolss_open_printer_ex (cli_spoolss.c)
1183  ********************************************************************/
1184
1185 BOOL spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
1186 {
1187         if (r_u == NULL) return False;
1188
1189         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
1190         depth++;
1191         
1192         if (!prs_align(ps))
1193                 return False;
1194
1195         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1196                 return False;
1197
1198         if (!prs_werror("status code", ps, depth, &(r_u->status)))
1199                 return False;
1200
1201         return True;
1202 }
1203
1204 /*******************************************************************
1205  * init a structure.
1206  ********************************************************************/
1207 BOOL make_spoolss_q_deleteprinterdriverex( TALLOC_CTX *mem_ctx,
1208                                            SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, 
1209                                            const char *server,
1210                                            const char* arch, 
1211                                            const char* driver,
1212                                            int version)
1213 {
1214         DEBUG(5,("make_spoolss_q_deleteprinterdriverex\n"));
1215  
1216         q_u->server_ptr = (server!=NULL)?1:0;
1217         q_u->delete_flags = DPD_DELETE_UNUSED_FILES;
1218  
1219         /* these must be NULL terminated or else NT4 will
1220            complain about invalid parameters --jerry */
1221         init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1222         init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1223         init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1224
1225         if (version >= 0) { 
1226                 q_u->delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1227                 q_u->version = version;
1228         }
1229
1230         return True;
1231 }
1232
1233
1234 /*******************************************************************
1235  * init a structure.
1236  ********************************************************************/
1237 BOOL make_spoolss_q_deleteprinterdriver(
1238         TALLOC_CTX *mem_ctx,
1239         SPOOL_Q_DELETEPRINTERDRIVER *q_u, 
1240         const char *server,
1241         const char* arch, 
1242         const char* driver 
1243 )
1244 {
1245         DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
1246         
1247         q_u->server_ptr = (server!=NULL)?1:0;
1248
1249         /* these must be NULL terminated or else NT4 will
1250            complain about invalid parameters --jerry */
1251         init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1252         init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1253         init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1254         
1255         return True;
1256 }
1257
1258 /*******************************************************************
1259  * make a structure.
1260  ********************************************************************/
1261
1262 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
1263                                    const POLICY_HND *handle,
1264                                    const char *valuename, uint32 size)
1265 {
1266         if (q_u == NULL) return False;
1267
1268         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
1269
1270         q_u->handle = *handle;
1271         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1272         q_u->size = size;
1273
1274         return True;
1275 }
1276
1277 /*******************************************************************
1278  * make a structure.
1279  ********************************************************************/
1280
1281 BOOL make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
1282                                      const POLICY_HND *handle,
1283                                      const char *keyname, 
1284                                      const char *valuename, uint32 size)
1285 {
1286         if (q_u == NULL) return False;
1287
1288         DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
1289
1290         q_u->handle = *handle;
1291         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1292         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
1293         q_u->size = size;
1294
1295         return True;
1296 }
1297
1298 /*******************************************************************
1299  * read a structure.
1300  * called from spoolss_q_getprinterdata (srv_spoolss.c)
1301  ********************************************************************/
1302
1303 BOOL spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
1304 {
1305         if (q_u == NULL)
1306                 return False;
1307
1308         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
1309         depth++;
1310
1311         if (!prs_align(ps))
1312                 return False;
1313         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1314                 return False;
1315         if (!prs_align(ps))
1316                 return False;
1317         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1318                 return False;
1319         if (!prs_align(ps))
1320                 return False;
1321         if (!prs_uint32("size", ps, depth, &q_u->size))
1322                 return False;
1323
1324         return True;
1325 }
1326
1327 /*******************************************************************
1328  * read a structure.
1329  * called from spoolss_q_deleteprinterdata (srv_spoolss.c)
1330  ********************************************************************/
1331
1332 BOOL spoolss_io_q_deleteprinterdata(const char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
1333 {
1334         if (q_u == NULL)
1335                 return False;
1336
1337         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
1338         depth++;
1339
1340         if (!prs_align(ps))
1341                 return False;
1342         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1343                 return False;
1344         if (!prs_align(ps))
1345                 return False;
1346         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1347                 return False;
1348
1349         return True;
1350 }
1351
1352 /*******************************************************************
1353  * write a structure.
1354  * called from spoolss_r_deleteprinterdata (srv_spoolss.c)
1355  ********************************************************************/
1356
1357 BOOL spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
1358 {
1359         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
1360         depth++;
1361         if(!prs_werror("status", ps, depth, &r_u->status))
1362                 return False;
1363
1364         return True;
1365 }
1366
1367 /*******************************************************************
1368  * read a structure.
1369  * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
1370  ********************************************************************/
1371
1372 BOOL spoolss_io_q_deleteprinterdataex(const char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
1373 {
1374         if (q_u == NULL)
1375                 return False;
1376
1377         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
1378         depth++;
1379
1380         if (!prs_align(ps))
1381                 return False;
1382         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1383                 return False;
1384         
1385         if (!smb_io_unistr2("keyname  ", &q_u->keyname, True, ps, depth))
1386                 return False;
1387         if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
1388                 return False;
1389
1390         return True;
1391 }
1392
1393 /*******************************************************************
1394  * write a structure.
1395  * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
1396  ********************************************************************/
1397
1398 BOOL spoolss_io_r_deleteprinterdataex(const char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
1399 {
1400         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
1401         depth++;
1402         
1403         if(!prs_werror("status", ps, depth, &r_u->status))
1404                 return False;
1405
1406         return True;
1407 }
1408
1409 /*******************************************************************
1410  * write a structure.
1411  * called from spoolss_r_getprinterdata (srv_spoolss.c)
1412  ********************************************************************/
1413
1414 BOOL spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
1415 {
1416         if (r_u == NULL)
1417                 return False;
1418
1419         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
1420         depth++;
1421
1422         if (!prs_align(ps))
1423                 return False;
1424         if (!prs_uint32("type", ps, depth, &r_u->type))
1425                 return False;
1426         if (!prs_uint32("size", ps, depth, &r_u->size))
1427                 return False;
1428         
1429         if (UNMARSHALLING(ps) && r_u->size) {
1430                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
1431                 if(!r_u->data)
1432                         return False;
1433         }
1434
1435         if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
1436                 return False;
1437                 
1438         if (!prs_align(ps))
1439                 return False;
1440         
1441         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1442                 return False;
1443         if (!prs_werror("status", ps, depth, &r_u->status))
1444                 return False;
1445                 
1446         return True;
1447 }
1448
1449 /*******************************************************************
1450  * make a structure.
1451  ********************************************************************/
1452
1453 BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
1454 {
1455         if (q_u == NULL) return False;
1456
1457         DEBUG(5,("make_spoolss_q_closeprinter\n"));
1458
1459         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1460
1461         return True;
1462 }
1463
1464 /*******************************************************************
1465  * read a structure.
1466  * called from static spoolss_q_abortprinter (srv_spoolss.c)
1467  * called from spoolss_abortprinter (cli_spoolss.c)
1468  ********************************************************************/
1469
1470 BOOL spoolss_io_q_abortprinter(const char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
1471 {
1472         if (q_u == NULL) return False;
1473
1474         prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
1475         depth++;
1476
1477         if (!prs_align(ps))
1478                 return False;
1479
1480         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1481                 return False;
1482
1483         return True;
1484 }
1485
1486 /*******************************************************************
1487  * write a structure.
1488  * called from spoolss_r_abortprinter (srv_spoolss.c)
1489  ********************************************************************/
1490
1491 BOOL spoolss_io_r_abortprinter(const char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
1492 {
1493         prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
1494         depth++;
1495         if(!prs_werror("status", ps, depth, &r_u->status))
1496                 return False;
1497
1498         return True;
1499 }
1500
1501 /*******************************************************************
1502  * read a structure.
1503  * called from static spoolss_q_deleteprinter (srv_spoolss.c)
1504  * called from spoolss_deleteprinter (cli_spoolss.c)
1505  ********************************************************************/
1506
1507 BOOL spoolss_io_q_deleteprinter(const char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
1508 {
1509         if (q_u == NULL) return False;
1510
1511         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
1512         depth++;
1513
1514         if (!prs_align(ps))
1515                 return False;
1516
1517         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1518                 return False;
1519
1520         return True;
1521 }
1522
1523 /*******************************************************************
1524  * write a structure.
1525  * called from static spoolss_r_deleteprinter (srv_spoolss.c)
1526  * called from spoolss_deleteprinter (cli_spoolss.c)
1527  ********************************************************************/
1528
1529 BOOL spoolss_io_r_deleteprinter(const char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
1530 {
1531         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
1532         depth++;
1533         
1534         if (!prs_align(ps))
1535                 return False;
1536
1537         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1538                 return False;
1539         if (!prs_werror("status", ps, depth, &r_u->status))
1540                 return False;
1541         
1542         return True;
1543 }
1544
1545
1546 /*******************************************************************
1547  * read a structure.
1548  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1549  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1550  ********************************************************************/
1551
1552 BOOL spoolss_io_q_deleteprinterdriver(const char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
1553 {
1554         if (q_u == NULL) return False;
1555
1556         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
1557         depth++;
1558
1559         if (!prs_align(ps))
1560                 return False;
1561
1562         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1563                 return False;           
1564         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1565                 return False;
1566         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1567                 return False;
1568         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1569                 return False;
1570
1571
1572         return True;
1573 }
1574
1575
1576 /*******************************************************************
1577  * write a structure.
1578  ********************************************************************/
1579 BOOL spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
1580 {
1581         if (r_u == NULL) return False;
1582
1583         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
1584         depth++;
1585
1586         if (!prs_align(ps))
1587                 return False;
1588
1589         if (!prs_werror("status", ps, depth, &r_u->status))
1590                 return False;
1591
1592         return True;
1593 }
1594
1595
1596 /*******************************************************************
1597  * read a structure.
1598  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1599  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1600  ********************************************************************/
1601
1602 BOOL spoolss_io_q_deleteprinterdriverex(const char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
1603 {
1604         if (q_u == NULL) return False;
1605
1606         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex");
1607         depth++;
1608
1609         if (!prs_align(ps))
1610                 return False;
1611
1612         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1613                 return False;           
1614         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1615                 return False;
1616         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1617                 return False;
1618         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1619                 return False;
1620
1621         if (!prs_align(ps))
1622                 return False;
1623
1624         if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
1625                 return False;           
1626         if(!prs_uint32("version      ", ps, depth, &q_u->version))
1627                 return False;           
1628
1629
1630         return True;
1631 }
1632
1633
1634 /*******************************************************************
1635  * write a structure.
1636  ********************************************************************/
1637 BOOL spoolss_io_r_deleteprinterdriverex(const char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth)
1638 {
1639         if (r_u == NULL) return False;
1640
1641         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex");
1642         depth++;
1643
1644         if (!prs_align(ps))
1645                 return False;
1646
1647         if (!prs_werror("status", ps, depth, &r_u->status))
1648                 return False;
1649
1650         return True;
1651 }
1652
1653
1654
1655 /*******************************************************************
1656  * read a structure.
1657  * called from static spoolss_q_closeprinter (srv_spoolss.c)
1658  * called from spoolss_closeprinter (cli_spoolss.c)
1659  ********************************************************************/
1660
1661 BOOL spoolss_io_q_closeprinter(const char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
1662 {
1663         if (q_u == NULL) return False;
1664
1665         prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
1666         depth++;
1667
1668         if (!prs_align(ps))
1669                 return False;
1670
1671         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1672                 return False;
1673
1674         return True;
1675 }
1676
1677 /*******************************************************************
1678  * write a structure.
1679  * called from static spoolss_r_closeprinter (srv_spoolss.c)
1680  * called from spoolss_closeprinter (cli_spoolss.c)
1681  ********************************************************************/
1682
1683 BOOL spoolss_io_r_closeprinter(const char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
1684 {
1685         prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
1686         depth++;
1687         
1688         if (!prs_align(ps))
1689                 return False;
1690
1691         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1692                 return False;
1693         if (!prs_werror("status", ps, depth, &r_u->status))
1694                 return False;
1695         
1696         return True;
1697 }
1698
1699 /*******************************************************************
1700  * read a structure.
1701  * called from spoolss_q_startdocprinter (srv_spoolss.c)
1702  ********************************************************************/
1703
1704 BOOL spoolss_io_q_startdocprinter(const char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
1705 {
1706         if (q_u == NULL) return False;
1707
1708         prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
1709         depth++;
1710
1711         if(!prs_align(ps))
1712                 return False;
1713
1714         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1715                 return False;
1716         
1717         if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
1718                 return False;
1719
1720         return True;
1721 }
1722
1723 /*******************************************************************
1724  * write a structure.
1725  * called from spoolss_r_startdocprinter (srv_spoolss.c)
1726  ********************************************************************/
1727
1728 BOOL spoolss_io_r_startdocprinter(const char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
1729 {
1730         prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
1731         depth++;
1732         if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
1733                 return False;
1734         if(!prs_werror("status", ps, depth, &r_u->status))
1735                 return False;
1736
1737         return True;
1738 }
1739
1740 /*******************************************************************
1741  * read a structure.
1742  * called from spoolss_q_enddocprinter (srv_spoolss.c)
1743  ********************************************************************/
1744
1745 BOOL spoolss_io_q_enddocprinter(const char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
1746 {
1747         if (q_u == NULL) return False;
1748
1749         prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
1750         depth++;
1751
1752         if(!prs_align(ps))
1753                 return False;
1754
1755         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1756                 return False;
1757
1758         return True;
1759 }
1760
1761 /*******************************************************************
1762  * write a structure.
1763  * called from spoolss_r_enddocprinter (srv_spoolss.c)
1764  ********************************************************************/
1765
1766 BOOL spoolss_io_r_enddocprinter(const char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
1767 {
1768         prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
1769         depth++;
1770         if(!prs_werror("status", ps, depth, &r_u->status))
1771                 return False;
1772
1773         return True;
1774 }
1775
1776 /*******************************************************************
1777  * read a structure.
1778  * called from spoolss_q_startpageprinter (srv_spoolss.c)
1779  ********************************************************************/
1780
1781 BOOL spoolss_io_q_startpageprinter(const char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
1782 {
1783         if (q_u == NULL) return False;
1784
1785         prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
1786         depth++;
1787
1788         if(!prs_align(ps))
1789                 return False;
1790
1791         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1792                 return False;
1793
1794         return True;
1795 }
1796
1797 /*******************************************************************
1798  * write a structure.
1799  * called from spoolss_r_startpageprinter (srv_spoolss.c)
1800  ********************************************************************/
1801
1802 BOOL spoolss_io_r_startpageprinter(const char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1803 {
1804         prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1805         depth++;
1806         if(!prs_werror("status", ps, depth, &r_u->status))
1807                 return False;
1808
1809         return True;
1810 }
1811
1812 /*******************************************************************
1813  * read a structure.
1814  * called from spoolss_q_endpageprinter (srv_spoolss.c)
1815  ********************************************************************/
1816
1817 BOOL spoolss_io_q_endpageprinter(const char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1818 {
1819         if (q_u == NULL) return False;
1820
1821         prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1822         depth++;
1823
1824         if(!prs_align(ps))
1825                 return False;
1826
1827         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1828                 return False;
1829
1830         return True;
1831 }
1832
1833 /*******************************************************************
1834  * write a structure.
1835  * called from spoolss_r_endpageprinter (srv_spoolss.c)
1836  ********************************************************************/
1837
1838 BOOL spoolss_io_r_endpageprinter(const char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1839 {
1840         prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1841         depth++;
1842         if(!prs_werror("status", ps, depth, &r_u->status))
1843                 return False;
1844
1845         return True;
1846 }
1847
1848 /*******************************************************************
1849  * read a structure.
1850  * called from spoolss_q_writeprinter (srv_spoolss.c)
1851  ********************************************************************/
1852
1853 BOOL spoolss_io_q_writeprinter(const char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1854 {
1855         if (q_u == NULL) return False;
1856
1857         prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1858         depth++;
1859
1860         if(!prs_align(ps))
1861                 return False;
1862
1863         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1864                 return False;
1865         if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
1866                 return False;
1867         
1868         if (q_u->buffer_size!=0)
1869         {
1870                 if (UNMARSHALLING(ps))
1871                         q_u->buffer=PRS_ALLOC_MEM(ps, uint8, q_u->buffer_size);
1872                 if(q_u->buffer == NULL)
1873                         return False;   
1874                 if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1875                         return False;
1876         }
1877         if(!prs_align(ps))
1878                 return False;
1879         if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
1880                 return False;
1881
1882         return True;
1883 }
1884
1885 /*******************************************************************
1886  * write a structure.
1887  * called from spoolss_r_writeprinter (srv_spoolss.c)
1888  ********************************************************************/
1889
1890 BOOL spoolss_io_r_writeprinter(const char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1891 {
1892         prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1893         depth++;
1894         if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
1895                 return False;
1896         if(!prs_werror("status", ps, depth, &r_u->status))
1897                 return False;
1898
1899         return True;
1900 }
1901
1902 /*******************************************************************
1903  * read a structure.
1904  * called from spoolss_q_rffpcnex (srv_spoolss.c)
1905  ********************************************************************/
1906
1907 BOOL spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1908 {
1909         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1910         depth++;
1911
1912         if(!prs_align(ps))
1913                 return False;
1914
1915         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1916                 return False;
1917         if(!prs_uint32("flags", ps, depth, &q_u->flags))
1918                 return False;
1919         if(!prs_uint32("options", ps, depth, &q_u->options))
1920                 return False;
1921         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1922                 return False;
1923         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1924                 return False;
1925
1926         if(!prs_align(ps))
1927                 return False;
1928                 
1929         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1930                 return False;
1931
1932         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1933                 return False;
1934         
1935         if (q_u->option_ptr!=0) {
1936         
1937                 if (UNMARSHALLING(ps))
1938                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1939                                 return False;
1940         
1941                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1942                         return False;
1943         }
1944         
1945         return True;
1946 }
1947
1948 /*******************************************************************
1949  * write a structure.
1950  * called from spoolss_r_rffpcnex (srv_spoolss.c)
1951  ********************************************************************/
1952
1953 BOOL spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1954 {
1955         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1956         depth++;
1957
1958         if(!prs_werror("status", ps, depth, &r_u->status))
1959                 return False;
1960
1961         return True;
1962 }
1963
1964 /*******************************************************************
1965  * read a structure.
1966  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1967  ********************************************************************/
1968
1969 BOOL spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1970 {
1971         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1972         depth++;
1973
1974         if(!prs_align(ps))
1975                 return False;
1976
1977         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1978                 return False;
1979
1980         if(!prs_uint32("change", ps, depth, &q_u->change))
1981                 return False;
1982         
1983         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1984                 return False;
1985         
1986         if (q_u->option_ptr!=0) {
1987         
1988                 if (UNMARSHALLING(ps))
1989                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1990                                 return False;
1991         
1992                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1993                         return False;
1994         }
1995
1996         return True;
1997 }
1998
1999 /*******************************************************************
2000  * write a structure.
2001  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
2002  ********************************************************************/
2003
2004 BOOL spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
2005 {
2006         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
2007         depth++;
2008
2009         if(!prs_align(ps))
2010                 return False;
2011                 
2012         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
2013                 return False;
2014
2015         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
2016                 return False;
2017         
2018         if(!prs_align(ps))
2019                 return False;
2020         if(!prs_werror("status", ps, depth, &r_u->status))
2021                 return False;
2022
2023         return True;
2024 }
2025
2026 /*******************************************************************
2027  * return the length of a uint16 (obvious, but the code is clean)
2028  ********************************************************************/
2029
2030 static uint32 size_of_uint16(uint16 *value)
2031 {
2032         return (sizeof(*value));
2033 }
2034
2035 /*******************************************************************
2036  * return the length of a uint32 (obvious, but the code is clean)
2037  ********************************************************************/
2038
2039 static uint32 size_of_uint32(uint32 *value)
2040 {
2041         return (sizeof(*value));
2042 }
2043
2044 /*******************************************************************
2045  * return the length of a NTTIME (obvious, but the code is clean)
2046  ********************************************************************/
2047
2048 static uint32 size_of_nttime(NTTIME *value)
2049 {
2050         return (sizeof(*value));
2051 }
2052
2053 /*******************************************************************
2054  * return the length of a uint32 (obvious, but the code is clean)
2055  ********************************************************************/
2056
2057 static uint32 size_of_device_mode(DEVICEMODE *devmode)
2058 {
2059         if (devmode==NULL)
2060                 return (4);
2061         else 
2062                 return (4+devmode->size+devmode->driverextra);
2063 }
2064
2065 /*******************************************************************
2066  * return the length of a uint32 (obvious, but the code is clean)
2067  ********************************************************************/
2068
2069 static uint32 size_of_systemtime(SYSTEMTIME *systime)
2070 {
2071         if (systime==NULL)
2072                 return (4);
2073         else 
2074                 return (sizeof(SYSTEMTIME) +4);
2075 }
2076
2077 /*******************************************************************
2078  Parse a DEVMODE structure and its relative pointer.
2079 ********************************************************************/
2080
2081 static BOOL smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
2082 {
2083         prs_struct *ps=&buffer->prs;
2084
2085         prs_debug(ps, depth, desc, "smb_io_reldevmode");
2086         depth++;
2087
2088         if (MARSHALLING(ps)) {
2089                 uint32 struct_offset = prs_offset(ps);
2090                 uint32 relative_offset;
2091                 
2092                 if (*devmode == NULL) {
2093                         relative_offset=0;
2094                         if (!prs_uint32("offset", ps, depth, &relative_offset))
2095                                 return False;
2096                         DEBUG(8, ("boing, the devmode was NULL\n"));
2097                         
2098                         return True;
2099                 }
2100                 
2101                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
2102                 
2103                 if(!prs_set_offset(ps, buffer->string_at_end))
2104                         return False;
2105                 
2106                 /* write the DEVMODE */
2107                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2108                         return False;
2109
2110                 if(!prs_set_offset(ps, struct_offset))
2111                         return False;
2112                 
2113                 relative_offset=buffer->string_at_end - buffer->struct_start;
2114                 /* write its offset */
2115                 if (!prs_uint32("offset", ps, depth, &relative_offset))
2116                         return False;
2117         }
2118         else {
2119                 uint32 old_offset;
2120                 
2121                 /* read the offset */
2122                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2123                         return False;
2124                 if (buffer->string_at_end == 0) {
2125                         *devmode = NULL;
2126                         return True;
2127                 }
2128
2129                 old_offset = prs_offset(ps);
2130                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2131                         return False;
2132
2133                 /* read the string */
2134                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
2135                         return False;
2136                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2137                         return False;
2138
2139                 if(!prs_set_offset(ps, old_offset))
2140                         return False;
2141         }
2142         return True;
2143 }
2144
2145 /*******************************************************************
2146  Parse a PRINTER_INFO_0 structure.
2147 ********************************************************************/  
2148
2149 BOOL smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
2150 {
2151         prs_struct *ps=&buffer->prs;
2152
2153         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
2154         depth++;        
2155         
2156         buffer->struct_start=prs_offset(ps);
2157
2158         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2159                 return False;
2160         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2161                 return False;
2162         
2163         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
2164                 return False;
2165         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
2166                 return False;
2167         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
2168                 return False;
2169
2170         if(!prs_uint16("year", ps, depth, &info->year))
2171                 return False;
2172         if(!prs_uint16("month", ps, depth, &info->month))
2173                 return False;
2174         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
2175                 return False;
2176         if(!prs_uint16("day", ps, depth, &info->day))
2177                 return False;
2178         if(!prs_uint16("hour", ps, depth, &info->hour))
2179                 return False;
2180         if(!prs_uint16("minute", ps, depth, &info->minute))
2181                 return False;
2182         if(!prs_uint16("second", ps, depth, &info->second))
2183                 return False;
2184         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
2185                 return False;
2186
2187         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
2188                 return False;
2189         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
2190                 return False;
2191
2192         if(!prs_uint16("major_version", ps, depth, &info->major_version))
2193                 return False;
2194         if(!prs_uint16("build_version", ps, depth, &info->build_version))
2195                 return False;
2196         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2197                 return False;
2198         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2199                 return False;
2200         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2201                 return False;
2202         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
2203                 return False;
2204         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
2205                 return False;
2206         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
2207                 return False;
2208         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
2209                 return False;
2210         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
2211                 return False;
2212         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
2213                 return False;
2214         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
2215                 return False;
2216         if(!prs_uint32("change_id", ps, depth, &info->change_id))
2217                 return False;
2218         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
2219                 return False;
2220         if(!prs_uint32("status"   , ps, depth, &info->status))
2221                 return False;
2222         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
2223                 return False;
2224         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
2225                 return False;
2226         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
2227                 return False;
2228         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
2229                 return False;
2230         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
2231                 return False;
2232         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
2233                 return False;
2234         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
2235                 return False;
2236         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
2237                 return False;
2238         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
2239                 return False;
2240         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
2241                 return False;
2242
2243         return True;
2244 }
2245
2246 /*******************************************************************
2247  Parse a PRINTER_INFO_1 structure.
2248 ********************************************************************/  
2249
2250 BOOL smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
2251 {
2252         prs_struct *ps=&buffer->prs;
2253
2254         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
2255         depth++;        
2256         
2257         buffer->struct_start=prs_offset(ps);
2258
2259         if (!prs_uint32("flags", ps, depth, &info->flags))
2260                 return False;
2261         if (!smb_io_relstr("description", buffer, depth, &info->description))
2262                 return False;
2263         if (!smb_io_relstr("name", buffer, depth, &info->name))
2264                 return False;
2265         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2266                 return False;   
2267
2268         return True;
2269 }
2270
2271 /*******************************************************************
2272  Parse a PRINTER_INFO_2 structure.
2273 ********************************************************************/  
2274
2275 BOOL smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
2276 {
2277         prs_struct *ps=&buffer->prs;
2278         uint32 dm_offset, sd_offset, current_offset;
2279         uint32 dummy_value = 0, has_secdesc = 0;
2280
2281         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
2282         depth++;        
2283         
2284         buffer->struct_start=prs_offset(ps);
2285         
2286         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2287                 return False;
2288         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2289                 return False;
2290         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
2291                 return False;
2292         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2293                 return False;
2294         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2295                 return False;
2296         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2297                 return False;
2298         if (!smb_io_relstr("location", buffer, depth, &info->location))
2299                 return False;
2300
2301         /* save current offset and wind forwared by a uint32 */
2302         dm_offset = prs_offset(ps);
2303         if (!prs_uint32("devmode", ps, depth, &dummy_value))
2304                 return False;
2305         
2306         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
2307                 return False;
2308         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2309                 return False;
2310         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2311                 return False;
2312         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2313                 return False;
2314
2315         /* save current offset for the sec_desc */
2316         sd_offset = prs_offset(ps);
2317         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
2318                 return False;
2319
2320         
2321         /* save current location so we can pick back up here */
2322         current_offset = prs_offset(ps);
2323         
2324         /* parse the devmode */
2325         if (!prs_set_offset(ps, dm_offset))
2326                 return False;
2327         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2328                 return False;
2329         
2330         /* parse the sec_desc */
2331         if (info->secdesc) {
2332                 if (!prs_set_offset(ps, sd_offset))
2333                         return False;
2334                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
2335                         return False;
2336         }
2337
2338         /* pick up where we left off */
2339         if (!prs_set_offset(ps, current_offset))
2340                 return False;
2341
2342         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2343                 return False;
2344         if (!prs_uint32("priority", ps, depth, &info->priority))
2345                 return False;
2346         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
2347                 return False;
2348         if (!prs_uint32("starttime", ps, depth, &info->starttime))
2349                 return False;
2350         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
2351                 return False;
2352         if (!prs_uint32("status", ps, depth, &info->status))
2353                 return False;
2354         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
2355                 return False;
2356         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
2357                 return False;
2358
2359         return True;
2360 }
2361
2362 /*******************************************************************
2363  Parse a PRINTER_INFO_3 structure.
2364 ********************************************************************/  
2365
2366 BOOL smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
2367 {
2368         prs_struct *ps=&buffer->prs;
2369
2370         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
2371         depth++;        
2372         
2373         buffer->struct_start=prs_offset(ps);
2374         
2375         if (!prs_uint32("flags", ps, depth, &info->flags))
2376                 return False;
2377         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
2378                 return False;
2379
2380         return True;
2381 }
2382
2383 /*******************************************************************
2384  Parse a PRINTER_INFO_4 structure.
2385 ********************************************************************/  
2386
2387 BOOL smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
2388 {
2389         prs_struct *ps=&buffer->prs;
2390
2391         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
2392         depth++;        
2393         
2394         buffer->struct_start=prs_offset(ps);
2395         
2396         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2397                 return False;
2398         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2399                 return False;
2400         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2401                 return False;
2402         return True;
2403 }
2404
2405 /*******************************************************************
2406  Parse a PRINTER_INFO_5 structure.
2407 ********************************************************************/  
2408
2409 BOOL smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
2410 {
2411         prs_struct *ps=&buffer->prs;
2412
2413         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
2414         depth++;        
2415         
2416         buffer->struct_start=prs_offset(ps);
2417         
2418         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2419                 return False;
2420         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2421                 return False;
2422         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2423                 return False;
2424         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
2425                 return False;
2426         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
2427                 return False;
2428         return True;
2429 }
2430
2431 /*******************************************************************
2432  Parse a PRINTER_INFO_7 structure.
2433 ********************************************************************/  
2434
2435 BOOL smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
2436 {
2437         prs_struct *ps=&buffer->prs;
2438
2439         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
2440         depth++;        
2441         
2442         buffer->struct_start=prs_offset(ps);
2443         
2444         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
2445                 return False;
2446         if (!prs_uint32("action", ps, depth, &info->action))
2447                 return False;
2448         return True;
2449 }
2450
2451 /*******************************************************************
2452  Parse a PORT_INFO_1 structure.
2453 ********************************************************************/  
2454
2455 BOOL smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2456 {
2457         prs_struct *ps=&buffer->prs;
2458
2459         prs_debug(ps, depth, desc, "smb_io_port_info_1");
2460         depth++;        
2461         
2462         buffer->struct_start=prs_offset(ps);
2463         
2464         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2465                 return False;
2466
2467         return True;
2468 }
2469
2470 /*******************************************************************
2471  Parse a PORT_INFO_2 structure.
2472 ********************************************************************/  
2473
2474 BOOL smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2475 {
2476         prs_struct *ps=&buffer->prs;
2477
2478         prs_debug(ps, depth, desc, "smb_io_port_info_2");
2479         depth++;        
2480         
2481         buffer->struct_start=prs_offset(ps);
2482         
2483         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2484                 return False;
2485         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2486                 return False;
2487         if (!smb_io_relstr("description", buffer, depth, &info->description))
2488                 return False;
2489         if (!prs_uint32("port_type", ps, depth, &info->port_type))
2490                 return False;
2491         if (!prs_uint32("reserved", ps, depth, &info->reserved))
2492                 return False;
2493
2494         return True;
2495 }
2496
2497 /*******************************************************************
2498  Parse a DRIVER_INFO_1 structure.
2499 ********************************************************************/
2500
2501 BOOL smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
2502 {
2503         prs_struct *ps=&buffer->prs;
2504
2505         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
2506         depth++;        
2507         
2508         buffer->struct_start=prs_offset(ps);
2509
2510         if (!smb_io_relstr("name", buffer, depth, &info->name))
2511                 return False;
2512
2513         return True;
2514 }
2515
2516 /*******************************************************************
2517  Parse a DRIVER_INFO_2 structure.
2518 ********************************************************************/
2519
2520 BOOL smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
2521 {
2522         prs_struct *ps=&buffer->prs;
2523
2524         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
2525         depth++;        
2526         
2527         buffer->struct_start=prs_offset(ps);
2528
2529         if (!prs_uint32("version", ps, depth, &info->version))
2530                 return False;
2531         if (!smb_io_relstr("name", buffer, depth, &info->name))
2532                 return False;
2533         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2534                 return False;
2535         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2536                 return False;
2537         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2538                 return False;
2539         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2540                 return False;
2541
2542         return True;
2543 }
2544
2545 /*******************************************************************
2546  Parse a DRIVER_INFO_3 structure.
2547 ********************************************************************/
2548
2549 BOOL smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
2550 {
2551         prs_struct *ps=&buffer->prs;
2552
2553         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
2554         depth++;        
2555         
2556         buffer->struct_start=prs_offset(ps);
2557
2558         if (!prs_uint32("version", ps, depth, &info->version))
2559                 return False;
2560         if (!smb_io_relstr("name", buffer, depth, &info->name))
2561                 return False;
2562         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2563                 return False;
2564         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2565                 return False;
2566         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2567                 return False;
2568         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2569                 return False;
2570         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2571                 return False;
2572
2573         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2574                 return False;
2575
2576         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2577                 return False;
2578         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2579                 return False;
2580
2581         return True;
2582 }
2583
2584 /*******************************************************************
2585  Parse a DRIVER_INFO_6 structure.
2586 ********************************************************************/
2587
2588 BOOL smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
2589 {
2590         prs_struct *ps=&buffer->prs;
2591
2592         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
2593         depth++;        
2594         
2595         buffer->struct_start=prs_offset(ps);
2596
2597         if (!prs_uint32("version", ps, depth, &info->version))
2598                 return False;
2599         if (!smb_io_relstr("name", buffer, depth, &info->name))
2600                 return False;
2601         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2602                 return False;
2603         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2604                 return False;
2605         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2606                 return False;
2607         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2608                 return False;
2609         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2610                 return False;
2611
2612         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2613                 return False;
2614
2615         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2616                 return False;
2617         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2618                 return False;
2619
2620         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2621                 return False;
2622
2623         if (!prs_uint32("date.low", ps, depth, &info->driver_date.low))
2624                 return False;
2625         if (!prs_uint32("date.high", ps, depth, &info->driver_date.high))
2626                 return False;
2627
2628         if (!prs_uint32("padding", ps, depth, &info->padding))
2629                 return False;
2630
2631         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2632                 return False;
2633
2634         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2635                 return False;
2636
2637         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2638                 return False;
2639         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2640                 return False;
2641         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2642                 return False;
2643         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2644                 return False;
2645         
2646         return True;
2647 }
2648
2649 /*******************************************************************
2650  Parse a JOB_INFO_1 structure.
2651 ********************************************************************/  
2652
2653 BOOL smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2654 {
2655         prs_struct *ps=&buffer->prs;
2656
2657         prs_debug(ps, depth, desc, "smb_io_job_info_1");
2658         depth++;        
2659         
2660         buffer->struct_start=prs_offset(ps);
2661
2662         if (!prs_uint32("jobid", ps, depth, &info->jobid))
2663                 return False;
2664         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2665                 return False;
2666         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2667                 return False;
2668         if (!smb_io_relstr("username", buffer, depth, &info->username))
2669                 return False;
2670         if (!smb_io_relstr("document", buffer, depth, &info->document))
2671                 return False;
2672         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2673                 return False;
2674         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2675                 return False;
2676         if (!prs_uint32("status", ps, depth, &info->status))
2677                 return False;
2678         if (!prs_uint32("priority", ps, depth, &info->priority))
2679                 return False;
2680         if (!prs_uint32("position", ps, depth, &info->position))
2681                 return False;
2682         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2683                 return False;
2684         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2685                 return False;
2686         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2687                 return False;
2688
2689         return True;
2690 }
2691
2692 /*******************************************************************
2693  Parse a JOB_INFO_2 structure.
2694 ********************************************************************/  
2695
2696 BOOL smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2697 {       
2698         uint32 pipo=0;
2699         prs_struct *ps=&buffer->prs;
2700         
2701         prs_debug(ps, depth, desc, "smb_io_job_info_2");
2702         depth++;        
2703
2704         buffer->struct_start=prs_offset(ps);
2705         
2706         if (!prs_uint32("jobid",ps, depth, &info->jobid))
2707                 return False;
2708         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2709                 return False;
2710         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2711                 return False;
2712         if (!smb_io_relstr("username", buffer, depth, &info->username))
2713                 return False;
2714         if (!smb_io_relstr("document", buffer, depth, &info->document))
2715                 return False;
2716         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2717                 return False;
2718         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2719                 return False;
2720
2721         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2722                 return False;
2723         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2724                 return False;
2725         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2726                 return False;
2727         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2728                 return False;
2729         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2730                 return False;
2731
2732 /*      SEC_DESC sec_desc;*/
2733         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2734                 return False;
2735
2736         if (!prs_uint32("status",ps, depth, &info->status))
2737                 return False;
2738         if (!prs_uint32("priority",ps, depth, &info->priority))
2739                 return False;
2740         if (!prs_uint32("position",ps, depth, &info->position)) 
2741                 return False;
2742         if (!prs_uint32("starttime",ps, depth, &info->starttime))
2743                 return False;
2744         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
2745                 return False;
2746         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2747                 return False;
2748         if (!prs_uint32("size",ps, depth, &info->size))
2749                 return False;
2750         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2751                 return False;
2752         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2753                 return False;
2754         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2755                 return False;
2756
2757         return True;
2758 }
2759
2760 /*******************************************************************
2761 ********************************************************************/  
2762
2763 BOOL smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
2764 {
2765         prs_struct *ps=&buffer->prs;
2766         
2767         prs_debug(ps, depth, desc, "smb_io_form_1");
2768         depth++;
2769                 
2770         buffer->struct_start=prs_offset(ps);
2771         
2772         if (!prs_uint32("flag", ps, depth, &info->flag))
2773                 return False;
2774                 
2775         if (!smb_io_relstr("name", buffer, depth, &info->name))
2776                 return False;
2777
2778         if (!prs_uint32("width", ps, depth, &info->width))
2779                 return False;
2780         if (!prs_uint32("length", ps, depth, &info->length))
2781                 return False;
2782         if (!prs_uint32("left", ps, depth, &info->left))
2783                 return False;
2784         if (!prs_uint32("top", ps, depth, &info->top))
2785                 return False;
2786         if (!prs_uint32("right", ps, depth, &info->right))
2787                 return False;
2788         if (!prs_uint32("bottom", ps, depth, &info->bottom))
2789                 return False;
2790
2791         return True;
2792 }
2793
2794
2795
2796 /*******************************************************************
2797  Parse a DRIVER_DIRECTORY_1 structure.
2798 ********************************************************************/  
2799
2800 BOOL smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2801 {
2802         prs_struct *ps=&buffer->prs;
2803
2804         prs_debug(ps, depth, desc, "smb_io_driverdir_1");
2805         depth++;
2806
2807         buffer->struct_start=prs_offset(ps);
2808
2809         if (!smb_io_unistr(desc, &info->name, ps, depth))
2810                 return False;
2811
2812         return True;
2813 }
2814
2815 /*******************************************************************
2816  Parse a PORT_INFO_1 structure.
2817 ********************************************************************/  
2818
2819 BOOL smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2820 {
2821         prs_struct *ps=&buffer->prs;
2822
2823         prs_debug(ps, depth, desc, "smb_io_port_1");
2824         depth++;
2825
2826         buffer->struct_start=prs_offset(ps);
2827
2828         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2829                 return False;
2830
2831         return True;
2832 }
2833
2834 /*******************************************************************
2835  Parse a PORT_INFO_2 structure.
2836 ********************************************************************/  
2837
2838 BOOL smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2839 {
2840         prs_struct *ps=&buffer->prs;
2841
2842         prs_debug(ps, depth, desc, "smb_io_port_2");
2843         depth++;
2844
2845         buffer->struct_start=prs_offset(ps);
2846
2847         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2848                 return False;
2849         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2850                 return False;
2851         if(!smb_io_relstr("description", buffer, depth, &info->description))
2852                 return False;
2853         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2854                 return False;
2855         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2856                 return False;
2857
2858         return True;
2859 }
2860
2861 /*******************************************************************
2862 ********************************************************************/  
2863
2864 BOOL smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2865 {
2866         prs_struct *ps=&buffer->prs;
2867
2868         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2869         depth++;        
2870
2871         buffer->struct_start=prs_offset(ps);
2872         
2873         if (smb_io_relstr("name", buffer, depth, &info->name))
2874                 return False;
2875
2876         return True;
2877 }
2878
2879 /*******************************************************************
2880 ********************************************************************/  
2881
2882 BOOL smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2883 {
2884         prs_struct *ps=&buffer->prs;
2885
2886         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2887         depth++;        
2888
2889         buffer->struct_start=prs_offset(ps);
2890         
2891         if (smb_io_relstr("name", buffer, depth, &info->name))
2892                 return False;
2893
2894         return True;
2895 }
2896
2897 /*******************************************************************
2898 ********************************************************************/  
2899
2900 BOOL smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2901 {
2902         prs_struct *ps=&buffer->prs;
2903
2904         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2905         depth++;        
2906
2907         buffer->struct_start=prs_offset(ps);
2908
2909         if (!smb_io_relstr("name", buffer, depth, &info->name))
2910                 return False;
2911
2912         return True;
2913 }
2914
2915 /*******************************************************************
2916 ********************************************************************/  
2917
2918 BOOL smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2919 {
2920         prs_struct *ps=&buffer->prs;
2921
2922         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2923         depth++;        
2924
2925         buffer->struct_start=prs_offset(ps);
2926
2927         if (!smb_io_relstr("name", buffer, depth, &info->name))
2928                 return False;
2929         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
2930                 return False;
2931         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2932                 return False;
2933
2934         return True;
2935 }
2936
2937 /*******************************************************************
2938 return the size required by a struct in the stream
2939 ********************************************************************/  
2940
2941 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2942 {
2943         int size=0;
2944         
2945         size+=size_of_relative_string( &info->printername );
2946         size+=size_of_relative_string( &info->servername );
2947
2948         size+=size_of_uint32( &info->cjobs);
2949         size+=size_of_uint32( &info->total_jobs);
2950         size+=size_of_uint32( &info->total_bytes);
2951
2952         size+=size_of_uint16( &info->year);
2953         size+=size_of_uint16( &info->month);
2954         size+=size_of_uint16( &info->dayofweek);
2955         size+=size_of_uint16( &info->day);
2956         size+=size_of_uint16( &info->hour);
2957         size+=size_of_uint16( &info->minute);
2958         size+=size_of_uint16( &info->second);
2959         size+=size_of_uint16( &info->milliseconds);
2960
2961         size+=size_of_uint32( &info->global_counter);
2962         size+=size_of_uint32( &info->total_pages);
2963
2964         size+=size_of_uint16( &info->major_version);
2965         size+=size_of_uint16( &info->build_version);
2966
2967         size+=size_of_uint32( &info->unknown7);
2968         size+=size_of_uint32( &info->unknown8);
2969         size+=size_of_uint32( &info->unknown9);
2970         size+=size_of_uint32( &info->session_counter);
2971         size+=size_of_uint32( &info->unknown11);
2972         size+=size_of_uint32( &info->printer_errors);
2973         size+=size_of_uint32( &info->unknown13);
2974         size+=size_of_uint32( &info->unknown14);
2975         size+=size_of_uint32( &info->unknown15);
2976         size+=size_of_uint32( &info->unknown16);
2977         size+=size_of_uint32( &info->change_id);
2978         size+=size_of_uint32( &info->unknown18);
2979         size+=size_of_uint32( &info->status);
2980         size+=size_of_uint32( &info->unknown20);
2981         size+=size_of_uint32( &info->c_setprinter);
2982         
2983         size+=size_of_uint16( &info->unknown22);
2984         size+=size_of_uint16( &info->unknown23);
2985         size+=size_of_uint16( &info->unknown24);
2986         size+=size_of_uint16( &info->unknown25);
2987         size+=size_of_uint16( &info->unknown26);
2988         size+=size_of_uint16( &info->unknown27);
2989         size+=size_of_uint16( &info->unknown28);
2990         size+=size_of_uint16( &info->unknown29);
2991         
2992         return size;
2993 }
2994
2995 /*******************************************************************
2996 return the size required by a struct in the stream
2997 ********************************************************************/  
2998
2999 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
3000 {
3001         int size=0;
3002                 
3003         size+=size_of_uint32( &info->flags );   
3004         size+=size_of_relative_string( &info->description );
3005         size+=size_of_relative_string( &info->name );
3006         size+=size_of_relative_string( &info->comment );
3007
3008         return size;
3009 }
3010
3011 /*******************************************************************
3012 return the size required by a struct in the stream
3013 ********************************************************************/
3014
3015 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
3016 {
3017         uint32 size=0;
3018                 
3019         size += 4;
3020         
3021         size += sec_desc_size( info->secdesc );
3022
3023         size+=size_of_device_mode( info->devmode );
3024         
3025         size+=size_of_relative_string( &info->servername );
3026         size+=size_of_relative_string( &info->printername );
3027         size+=size_of_relative_string( &info->sharename );
3028         size+=size_of_relative_string( &info->portname );
3029         size+=size_of_relative_string( &info->drivername );
3030         size+=size_of_relative_string( &info->comment );
3031         size+=size_of_relative_string( &info->location );
3032         
3033         size+=size_of_relative_string( &info->sepfile );
3034         size+=size_of_relative_string( &info->printprocessor );
3035         size+=size_of_relative_string( &info->datatype );
3036         size+=size_of_relative_string( &info->parameters );
3037
3038         size+=size_of_uint32( &info->attributes );
3039         size+=size_of_uint32( &info->priority );
3040         size+=size_of_uint32( &info->defaultpriority );
3041         size+=size_of_uint32( &info->starttime );
3042         size+=size_of_uint32( &info->untiltime );
3043         size+=size_of_uint32( &info->status );
3044         size+=size_of_uint32( &info->cjobs );
3045         size+=size_of_uint32( &info->averageppm );      
3046                 
3047         /* 
3048          * add any adjustments for alignment.  This is
3049          * not optimal since we could be calling this
3050          * function from a loop (e.g. enumprinters), but 
3051          * it is easier to maintain the calculation here and
3052          * not place the burden on the caller to remember.   --jerry
3053          */
3054         if ((size % 4) != 0)
3055                 size += 4 - (size % 4);
3056         
3057         return size;
3058 }
3059
3060 /*******************************************************************
3061 return the size required by a struct in the stream
3062 ********************************************************************/
3063
3064 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
3065 {
3066         uint32 size=0;
3067                 
3068         size+=size_of_relative_string( &info->printername );
3069         size+=size_of_relative_string( &info->servername );
3070
3071         size+=size_of_uint32( &info->attributes );
3072         return size;
3073 }
3074
3075 /*******************************************************************
3076 return the size required by a struct in the stream
3077 ********************************************************************/
3078
3079 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
3080 {
3081         uint32 size=0;
3082                 
3083         size+=size_of_relative_string( &info->printername );
3084         size+=size_of_relative_string( &info->portname );
3085
3086         size+=size_of_uint32( &info->attributes );
3087         size+=size_of_uint32( &info->device_not_selected_timeout );
3088         size+=size_of_uint32( &info->transmission_retry_timeout );
3089         return size;
3090 }
3091
3092
3093 /*******************************************************************
3094 return the size required by a struct in the stream
3095 ********************************************************************/
3096
3097 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
3098 {
3099         /* The 4 is for the self relative pointer.. */
3100         /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
3101         return 4 + (uint32)sec_desc_size( info->secdesc );
3102 }
3103
3104 /*******************************************************************
3105 return the size required by a struct in the stream
3106 ********************************************************************/
3107
3108 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
3109 {
3110         uint32 size=0;
3111                 
3112         size+=size_of_relative_string( &info->guid );
3113         size+=size_of_uint32( &info->action );
3114         return size;
3115 }
3116
3117 /*******************************************************************
3118 return the size required by a struct in the stream
3119 ********************************************************************/
3120
3121 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
3122 {
3123         int size=0;
3124         size+=size_of_relative_string( &info->name );
3125
3126         return size;
3127 }
3128
3129 /*******************************************************************
3130 return the size required by a struct in the stream
3131 ********************************************************************/
3132
3133 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
3134 {
3135         int size=0;
3136         size+=size_of_uint32( &info->version ); 
3137         size+=size_of_relative_string( &info->name );
3138         size+=size_of_relative_string( &info->architecture );
3139         size+=size_of_relative_string( &info->driverpath );
3140         size+=size_of_relative_string( &info->datafile );
3141         size+=size_of_relative_string( &info->configfile );
3142
3143         return size;
3144 }
3145
3146 /*******************************************************************
3147 return the size required by a string array.
3148 ********************************************************************/
3149
3150 uint32 spoolss_size_string_array(uint16 *string)
3151 {
3152         uint32 i = 0;
3153
3154         if (string) {
3155                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
3156         }
3157         i=i+2; /* to count all chars including the leading zero */
3158         i=2*i; /* because we need the value in bytes */
3159         i=i+4; /* the offset pointer size */
3160
3161         return i;
3162 }
3163
3164 /*******************************************************************
3165 return the size required by a struct in the stream
3166 ********************************************************************/
3167
3168 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
3169 {
3170         int size=0;
3171
3172         size+=size_of_uint32( &info->version ); 
3173         size+=size_of_relative_string( &info->name );
3174         size+=size_of_relative_string( &info->architecture );
3175         size+=size_of_relative_string( &info->driverpath );
3176         size+=size_of_relative_string( &info->datafile );
3177         size+=size_of_relative_string( &info->configfile );
3178         size+=size_of_relative_string( &info->helpfile );
3179         size+=size_of_relative_string( &info->monitorname );
3180         size+=size_of_relative_string( &info->defaultdatatype );
3181         
3182         size+=spoolss_size_string_array(info->dependentfiles);
3183
3184         return size;
3185 }
3186
3187 /*******************************************************************
3188 return the size required by a struct in the stream
3189 ********************************************************************/
3190
3191 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
3192 {
3193         uint32 size=0;
3194
3195         size+=size_of_uint32( &info->version ); 
3196         size+=size_of_relative_string( &info->name );
3197         size+=size_of_relative_string( &info->architecture );
3198         size+=size_of_relative_string( &info->driverpath );
3199         size+=size_of_relative_string( &info->datafile );
3200         size+=size_of_relative_string( &info->configfile );
3201         size+=size_of_relative_string( &info->helpfile );
3202
3203         size+=spoolss_size_string_array(info->dependentfiles);
3204
3205         size+=size_of_relative_string( &info->monitorname );
3206         size+=size_of_relative_string( &info->defaultdatatype );
3207         
3208         size+=spoolss_size_string_array(info->previousdrivernames);
3209
3210         size+=size_of_nttime(&info->driver_date);
3211         size+=size_of_uint32( &info->padding ); 
3212         size+=size_of_uint32( &info->driver_version_low );      
3213         size+=size_of_uint32( &info->driver_version_high );     
3214         size+=size_of_relative_string( &info->mfgname );
3215         size+=size_of_relative_string( &info->oem_url );
3216         size+=size_of_relative_string( &info->hardware_id );
3217         size+=size_of_relative_string( &info->provider );
3218
3219         return size;
3220 }
3221
3222 /*******************************************************************
3223 return the size required by a struct in the stream
3224 ********************************************************************/  
3225
3226 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
3227 {
3228         int size=0;
3229         size+=size_of_uint32( &info->jobid );
3230         size+=size_of_relative_string( &info->printername );
3231         size+=size_of_relative_string( &info->machinename );
3232         size+=size_of_relative_string( &info->username );
3233         size+=size_of_relative_string( &info->document );
3234         size+=size_of_relative_string( &info->datatype );
3235         size+=size_of_relative_string( &info->text_status );
3236         size+=size_of_uint32( &info->status );
3237         size+=size_of_uint32( &info->priority );
3238         size+=size_of_uint32( &info->position );
3239         size+=size_of_uint32( &info->totalpages );
3240         size+=size_of_uint32( &info->pagesprinted );
3241         size+=size_of_systemtime( &info->submitted );
3242
3243         return size;
3244 }
3245
3246 /*******************************************************************
3247 return the size required by a struct in the stream
3248 ********************************************************************/  
3249
3250 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
3251 {
3252         int size=0;
3253
3254         size+=4; /* size of sec desc ptr */
3255
3256         size+=size_of_uint32( &info->jobid );
3257         size+=size_of_relative_string( &info->printername );
3258         size+=size_of_relative_string( &info->machinename );
3259         size+=size_of_relative_string( &info->username );
3260         size+=size_of_relative_string( &info->document );
3261         size+=size_of_relative_string( &info->notifyname );
3262         size+=size_of_relative_string( &info->datatype );
3263         size+=size_of_relative_string( &info->printprocessor );
3264         size+=size_of_relative_string( &info->parameters );
3265         size+=size_of_relative_string( &info->drivername );
3266         size+=size_of_device_mode( info->devmode );
3267         size+=size_of_relative_string( &info->text_status );
3268 /*      SEC_DESC sec_desc;*/
3269         size+=size_of_uint32( &info->status );
3270         size+=size_of_uint32( &info->priority );
3271         size+=size_of_uint32( &info->position );
3272         size+=size_of_uint32( &info->starttime );
3273         size+=size_of_uint32( &info->untiltime );
3274         size+=size_of_uint32( &info->totalpages );
3275         size+=size_of_uint32( &info->size );
3276         size+=size_of_systemtime( &info->submitted );
3277         size+=size_of_uint32( &info->timeelapsed );
3278         size+=size_of_uint32( &info->pagesprinted );
3279
3280         return size;
3281 }
3282
3283 /*******************************************************************
3284 return the size required by a struct in the stream
3285 ********************************************************************/
3286
3287 uint32 spoolss_size_form_1(FORM_1 *info)
3288 {
3289         int size=0;
3290
3291         size+=size_of_uint32( &info->flag );
3292         size+=size_of_relative_string( &info->name );
3293         size+=size_of_uint32( &info->width );
3294         size+=size_of_uint32( &info->length );
3295         size+=size_of_uint32( &info->left );
3296         size+=size_of_uint32( &info->top );
3297         size+=size_of_uint32( &info->right );
3298         size+=size_of_uint32( &info->bottom );
3299
3300         return size;
3301 }
3302
3303 /*******************************************************************
3304 return the size required by a struct in the stream
3305 ********************************************************************/  
3306
3307 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
3308 {
3309         int size=0;
3310
3311         size+=size_of_relative_string( &info->port_name );
3312
3313         return size;
3314 }
3315
3316 /*******************************************************************
3317 return the size required by a struct in the stream
3318 ********************************************************************/  
3319
3320 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
3321 {
3322         int size=0;
3323
3324         size=str_len_uni(&info->name);  /* the string length       */
3325         size=size+1;                    /* add the leading zero    */
3326         size=size*2;                    /* convert in char         */
3327
3328         return size;
3329 }
3330
3331 /*******************************************************************
3332 return the size required by a struct in the stream
3333 ********************************************************************/  
3334
3335 uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
3336 {
3337         int size=0;
3338
3339         size=str_len_uni(&info->name);  /* the string length       */
3340         size=size+1;                    /* add the leading zero    */
3341         size=size*2;                    /* convert in char         */
3342
3343         return size;
3344 }
3345
3346 /*******************************************************************
3347 return the size required by a struct in the stream
3348 ********************************************************************/  
3349
3350 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
3351 {
3352         int size=0;
3353
3354         size+=size_of_relative_string( &info->port_name );
3355         size+=size_of_relative_string( &info->monitor_name );
3356         size+=size_of_relative_string( &info->description );
3357
3358         size+=size_of_uint32( &info->port_type );
3359         size+=size_of_uint32( &info->reserved );
3360
3361         return size;
3362 }
3363
3364 /*******************************************************************
3365 return the size required by a struct in the stream
3366 ********************************************************************/  
3367
3368 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
3369 {
3370         int size=0;
3371         size+=size_of_relative_string( &info->name );
3372
3373         return size;
3374 }
3375
3376 /*******************************************************************
3377 return the size required by a struct in the stream
3378 ********************************************************************/  
3379
3380 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
3381 {
3382         int size=0;
3383         size+=size_of_relative_string( &info->name );
3384
3385         return size;
3386 }
3387
3388 /*******************************************************************
3389 return the size required by a struct in the stream
3390 ********************************************************************/  
3391 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
3392 {
3393         uint32  size = 0; 
3394         
3395         if (!p)
3396                 return 0;
3397         
3398         /* uint32(offset) + uint32(length) + length) */
3399         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
3400         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
3401         
3402         size += size_of_uint32(&p->type);
3403                        
3404         return size;
3405 }
3406
3407 /*******************************************************************
3408 return the size required by a struct in the stream
3409 ********************************************************************/  
3410
3411 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
3412 {
3413         int size=0;
3414         size+=size_of_relative_string( &info->name );
3415
3416         return size;
3417 }
3418
3419 /*******************************************************************
3420 return the size required by a struct in the stream
3421 ********************************************************************/  
3422
3423 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
3424 {
3425         int size=0;
3426         size+=size_of_relative_string( &info->name);
3427         size+=size_of_relative_string( &info->environment);
3428         size+=size_of_relative_string( &info->dll_name);
3429
3430         return size;
3431 }
3432
3433 /*******************************************************************
3434  * init a structure.
3435  ********************************************************************/
3436
3437 BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
3438                                const POLICY_HND *hnd,
3439                                const fstring architecture,
3440                                uint32 level, uint32 clientmajor, uint32 clientminor,
3441                                RPC_BUFFER *buffer, uint32 offered)
3442 {      
3443         if (q_u == NULL)
3444                 return False;
3445
3446         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3447
3448         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
3449
3450         q_u->level=level;
3451         q_u->clientmajorversion=clientmajor;
3452         q_u->clientminorversion=clientminor;
3453
3454         q_u->buffer=buffer;
3455         q_u->offered=offered;
3456
3457         return True;
3458 }
3459
3460 /*******************************************************************
3461  * read a structure.
3462  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3463  ********************************************************************/
3464
3465 BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
3466 {
3467         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
3468         depth++;
3469
3470         if(!prs_align(ps))
3471                 return False;
3472         
3473         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3474                 return False;
3475         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
3476                 return False;
3477         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
3478                 return False;
3479         
3480         if(!prs_align(ps))
3481                 return False;
3482         if(!prs_uint32("level", ps, depth, &q_u->level))
3483                 return False;
3484                 
3485         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3486                 return False;
3487
3488         if(!prs_align(ps))
3489                 return False;
3490
3491         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3492                 return False;
3493                 
3494         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
3495                 return False;
3496         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
3497                 return False;
3498
3499         return True;
3500 }
3501
3502 /*******************************************************************
3503  * read a structure.
3504  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3505  ********************************************************************/
3506
3507 BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
3508 {
3509         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
3510         depth++;
3511
3512         if (!prs_align(ps))
3513                 return False;
3514                 
3515         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3516                 return False;
3517
3518         if (!prs_align(ps))
3519                 return False;
3520         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3521                 return False;
3522         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
3523                 return False;
3524         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
3525                 return False;           
3526         if (!prs_werror("status", ps, depth, &r_u->status))
3527                 return False;
3528
3529         return True;            
3530 }
3531
3532 /*******************************************************************
3533  * init a structure.
3534  ********************************************************************/
3535
3536 BOOL make_spoolss_q_enumprinters(
3537         SPOOL_Q_ENUMPRINTERS *q_u, 
3538         uint32 flags, 
3539         char *servername, 
3540         uint32 level, 
3541         RPC_BUFFER *buffer, 
3542         uint32 offered
3543 )
3544 {
3545         q_u->flags=flags;
3546         
3547         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
3548         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
3549
3550         q_u->level=level;
3551         q_u->buffer=buffer;
3552         q_u->offered=offered;
3553
3554         return True;
3555 }
3556
3557 /*******************************************************************
3558  * init a structure.
3559  ********************************************************************/
3560
3561 BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
3562                                 fstring servername, uint32 level, 
3563                                 RPC_BUFFER *buffer, uint32 offered)
3564 {
3565         q_u->name_ptr = (servername != NULL) ? 1 : 0;
3566         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
3567
3568         q_u->level=level;
3569         q_u->buffer=buffer;
3570         q_u->offered=offered;
3571
3572         return True;
3573 }
3574
3575 /*******************************************************************
3576  * read a structure.
3577  * called from spoolss_enumprinters (srv_spoolss.c)
3578  ********************************************************************/
3579
3580 BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
3581 {
3582         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
3583         depth++;
3584
3585         if (!prs_align(ps))
3586                 return False;
3587
3588         if (!prs_uint32("flags", ps, depth, &q_u->flags))
3589                 return False;
3590         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
3591                 return False;
3592
3593         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
3594                 return False;
3595                 
3596         if (!prs_align(ps))
3597                 return False;
3598         if (!prs_uint32("level", ps, depth, &q_u->level))
3599                 return False;
3600
3601         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3602                 return False;
3603
3604         if (!prs_align(ps))
3605                 return False;
3606         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3607                 return False;
3608
3609         return True;
3610 }
3611
3612 /*******************************************************************
3613  Parse a SPOOL_R_ENUMPRINTERS structure.
3614  ********************************************************************/
3615
3616 BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
3617 {
3618         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
3619         depth++;
3620
3621         if (!prs_align(ps))
3622                 return False;
3623                 
3624         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3625                 return False;
3626
3627         if (!prs_align(ps))
3628                 return False;
3629                 
3630         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3631                 return False;
3632                 
3633         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3634                 return False;
3635                 
3636         if (!prs_werror("status", ps, depth, &r_u->status))
3637                 return False;
3638
3639         return True;            
3640 }
3641
3642 /*******************************************************************
3643  * write a structure.
3644  * called from spoolss_r_enum_printers (srv_spoolss.c)
3645  *
3646  ********************************************************************/
3647
3648 BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
3649 {       
3650         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
3651         depth++;
3652
3653         if (!prs_align(ps))
3654                 return False;
3655                 
3656         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3657                 return False;
3658
3659         if (!prs_align(ps))
3660                 return False;
3661
3662         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3663                 return False;
3664                 
3665         if (!prs_werror("status", ps, depth, &r_u->status))
3666                 return False;
3667
3668         return True;            
3669 }
3670
3671 /*******************************************************************
3672  * read a structure.
3673  * called from spoolss_getprinter (srv_spoolss.c)
3674  ********************************************************************/
3675
3676 BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
3677 {
3678         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
3679         depth++;
3680
3681         if (!prs_align(ps))
3682                 return False;
3683
3684         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3685                 return False;
3686         if (!prs_uint32("level", ps, depth, &q_u->level))
3687                 return False;
3688
3689         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3690                 return False;
3691
3692         if (!prs_align(ps))
3693                 return False;
3694         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3695                 return False;
3696
3697         return True;
3698 }
3699
3700 /*******************************************************************
3701  * init a structure.
3702  ********************************************************************/
3703
3704 BOOL make_spoolss_q_getprinter(
3705         TALLOC_CTX *mem_ctx,
3706         SPOOL_Q_GETPRINTER *q_u, 
3707         const POLICY_HND *hnd, 
3708         uint32 level, 
3709         RPC_BUFFER *buffer, 
3710         uint32 offered
3711 )
3712 {
3713         if (q_u == NULL)
3714         {
3715                 return False;
3716         }
3717         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3718
3719         q_u->level=level;
3720         q_u->buffer=buffer;
3721         q_u->offered=offered;
3722
3723         return True;
3724 }
3725
3726 /*******************************************************************
3727  * init a structure.
3728  ********************************************************************/
3729 BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
3730                                 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
3731                                 uint32 command)
3732 {
3733         SEC_DESC *secdesc;
3734         DEVICEMODE *devmode;
3735
3736         if (q_u == NULL)
3737                 return False;
3738         
3739         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3740
3741         q_u->level = level;
3742         q_u->info.level = level;
3743         q_u->info.info_ptr = (info != NULL) ? 1 : 0;
3744         switch (level) {
3745
3746           /* There's no such thing as a setprinter level 1 */
3747
3748         case 2:
3749                 secdesc = info->printers_2->secdesc;
3750                 devmode = info->printers_2->devmode;
3751                 
3752                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
3753 #if 1   /* JERRY TEST */
3754                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3755                 if (!q_u->secdesc_ctr)
3756                         return False;
3757                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3758                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3759                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3760                 q_u->secdesc_ctr->sec = secdesc;
3761
3762                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
3763                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
3764                 q_u->devmode_ctr.devmode = devmode;
3765 #else
3766                 q_u->secdesc_ctr = NULL;
3767         
3768                 q_u->devmode_ctr.devmode_ptr = 0;
3769                 q_u->devmode_ctr.size = 0;
3770                 q_u->devmode_ctr.devmode = NULL;
3771 #endif
3772                 break;
3773         case 3:
3774                 secdesc = info->printers_3->secdesc;
3775                 
3776                 make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
3777                 
3778                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3779                 if (!q_u->secdesc_ctr)
3780                         return False;
3781                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3782                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3783                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3784                 q_u->secdesc_ctr->sec = secdesc;
3785
3786                 break;
3787         case 7:
3788                 make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
3789                 break;
3790
3791         default: 
3792                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
3793                         break;
3794         }
3795
3796         
3797         q_u->command = command;
3798
3799         return True;
3800 }
3801
3802
3803 /*******************************************************************
3804 ********************************************************************/  
3805
3806 BOOL spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
3807 {               
3808         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
3809         depth++;
3810
3811         if(!prs_align(ps))
3812                 return False;
3813         
3814         if(!prs_werror("status", ps, depth, &r_u->status))
3815                 return False;
3816
3817         return True;
3818 }
3819
3820 /*******************************************************************
3821  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
3822 ********************************************************************/  
3823
3824 BOOL spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
3825 {
3826         uint32 ptr_sec_desc = 0;
3827
3828         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
3829         depth++;
3830
3831         if(!prs_align(ps))
3832                 return False;
3833
3834         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
3835                 return False;
3836         if(!prs_uint32("level", ps, depth, &q_u->level))
3837                 return False;
3838         
3839         /* check for supported levels and structures we know about */
3840                 
3841         switch ( q_u->level ) {
3842                 case 0:
3843                 case 2:
3844                 case 3:
3845                 case 7:
3846                         /* supported levels */
3847                         break;
3848                 default:
3849                         DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
3850                                 q_u->level));
3851                         return True;
3852         }
3853                         
3854
3855         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3856                 return False;
3857
3858         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3859                 return False;
3860         
3861         if(!prs_align(ps))
3862                 return False;
3863
3864         switch (q_u->level)
3865         {
3866                 case 2:
3867                 {
3868                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3869                         break;
3870                 }
3871                 case 3:
3872                 {
3873                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3874                         break;
3875                 }
3876         }
3877         if (ptr_sec_desc)
3878         {
3879                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3880                         return False;
3881         } else {
3882                 uint32 dummy = 0;
3883
3884                 /* Parse a NULL security descriptor.  This should really
3885                    happen inside the sec_io_desc_buf() function. */
3886
3887                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3888                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3889                         return False;
3890                 if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
3891                                                                        False;
3892         }
3893         
3894         if(!prs_uint32("command", ps, depth, &q_u->command))
3895                 return False;
3896
3897         return True;
3898 }
3899
3900 /*******************************************************************
3901 ********************************************************************/  
3902
3903 BOOL spoolss_io_r_fcpn(const char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
3904 {               
3905         prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
3906         depth++;
3907
3908         if(!prs_align(ps))
3909                 return False;
3910         
3911         if(!prs_werror("status", ps, depth, &r_u->status))
3912                 return False;
3913
3914         return True;
3915 }
3916
3917 /*******************************************************************
3918 ********************************************************************/  
3919
3920 BOOL spoolss_io_q_fcpn(const char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
3921 {
3922
3923         prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
3924         depth++;
3925
3926         if(!prs_align(ps))
3927                 return False;
3928
3929         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3930                 return False;
3931
3932         return True;
3933 }
3934
3935
3936 /*******************************************************************
3937 ********************************************************************/  
3938
3939 BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
3940 {               
3941         prs_debug(ps, depth, desc, "");
3942         depth++;
3943
3944         if(!prs_align(ps))
3945                 return False;
3946         
3947         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3948                 return False;
3949
3950         if(!prs_align(ps))
3951                 return False;
3952         
3953         if(!prs_uint32("needed", ps, depth, &r_u->needed))
3954                 return False;
3955
3956         if(!prs_werror("status", ps, depth, &r_u->status))
3957                 return False;
3958
3959         return True;
3960 }
3961
3962 /*******************************************************************
3963 ********************************************************************/  
3964
3965 BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
3966 {
3967         prs_debug(ps, depth, desc, "");
3968         depth++;
3969
3970         if(!prs_align(ps))
3971                 return False;
3972
3973         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3974                 return False;
3975         if(!prs_uint32("level", ps, depth, &q_u->level))
3976                 return False;
3977         
3978         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3979                 return False;
3980
3981         if(!prs_align(ps))
3982                 return False;
3983         
3984         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3985                 return False;
3986
3987         return True;
3988 }
3989
3990 /*******************************************************************
3991 ********************************************************************/  
3992
3993 BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
3994 {               
3995         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
3996         depth++;
3997
3998         if (!prs_align(ps))
3999                 return False;
4000                 
4001         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4002                 return False;
4003
4004         if (!prs_align(ps))
4005                 return False;
4006                 
4007         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4008                 return False;
4009                 
4010         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4011                 return False;
4012                 
4013         if (!prs_werror("status", ps, depth, &r_u->status))
4014                 return False;
4015
4016         return True;            
4017 }
4018
4019 /*******************************************************************
4020 ********************************************************************/  
4021
4022 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
4023                                 uint32 firstjob,
4024                                 uint32 numofjobs,
4025                                 uint32 level,
4026                                 RPC_BUFFER *buffer,
4027                                 uint32 offered)
4028 {
4029         if (q_u == NULL)
4030         {
4031                 return False;
4032         }
4033         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4034         q_u->firstjob = firstjob;
4035         q_u->numofjobs = numofjobs;
4036         q_u->level = level;
4037         q_u->buffer= buffer;
4038         q_u->offered = offered;
4039         return True;
4040 }
4041
4042 /*******************************************************************
4043 ********************************************************************/  
4044
4045 BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
4046 {
4047         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
4048         depth++;
4049
4050         if (!prs_align(ps))
4051                 return False;
4052
4053         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
4054                 return False;
4055                 
4056         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
4057                 return False;
4058         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
4059                 return False;
4060         if (!prs_uint32("level", ps, depth, &q_u->level))
4061                 return False;
4062
4063         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4064                 return False;   
4065
4066         if(!prs_align(ps))
4067                 return False;
4068
4069         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4070                 return False;
4071
4072         return True;
4073 }
4074
4075 /*******************************************************************
4076 ********************************************************************/  
4077
4078 BOOL spoolss_io_r_schedulejob(const char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
4079 {               
4080         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
4081         depth++;
4082
4083         if(!prs_align(ps))
4084                 return False;
4085         
4086         if(!prs_werror("status", ps, depth, &r_u->status))
4087                 return False;
4088
4089         return True;
4090 }
4091
4092 /*******************************************************************
4093 ********************************************************************/  
4094
4095 BOOL spoolss_io_q_schedulejob(const char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
4096 {
4097         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
4098         depth++;
4099
4100         if(!prs_align(ps))
4101                 return False;
4102
4103         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4104                 return False;
4105         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4106                 return False;
4107
4108         return True;
4109 }
4110
4111 /*******************************************************************
4112 ********************************************************************/  
4113
4114 BOOL spoolss_io_r_setjob(const char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
4115 {               
4116         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
4117         depth++;
4118
4119         if(!prs_align(ps))
4120                 return False;
4121         
4122         if(!prs_werror("status", ps, depth, &r_u->status))
4123                 return False;
4124
4125         return True;
4126 }
4127
4128 /*******************************************************************
4129 ********************************************************************/  
4130
4131 BOOL spoolss_io_q_setjob(const char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
4132 {
4133         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
4134         depth++;
4135
4136         if(!prs_align(ps))
4137                 return False;
4138
4139         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4140                 return False;
4141         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4142                 return False;
4143         /* 
4144          * level is usually 0. If (level!=0) then I'm in trouble !
4145          * I will try to generate setjob command with level!=0, one day.
4146          */
4147         if(!prs_uint32("level", ps, depth, &q_u->level))
4148                 return False;
4149         if(!prs_uint32("command", ps, depth, &q_u->command))
4150                 return False;
4151
4152         return True;
4153 }
4154
4155 /*******************************************************************
4156  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
4157 ********************************************************************/  
4158
4159 BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
4160 {
4161         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
4162         depth++;
4163
4164         if (!prs_align(ps))
4165                 return False;
4166                 
4167         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4168                 return False;
4169
4170         if (!prs_align(ps))
4171                 return False;
4172                 
4173         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4174                 return False;
4175                 
4176         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4177                 return False;
4178                 
4179         if (!prs_werror("status", ps, depth, &r_u->status))
4180                 return False;
4181
4182         return True;            
4183 }
4184
4185 /*******************************************************************
4186  * init a structure.
4187  ********************************************************************/
4188
4189 BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
4190                                 const char *name,
4191                                 const char *environment,
4192                                 uint32 level,
4193                                 RPC_BUFFER *buffer, uint32 offered)
4194 {
4195         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
4196         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
4197
4198         q_u->level=level;
4199         q_u->buffer=buffer;
4200         q_u->offered=offered;
4201
4202         return True;
4203 }
4204
4205 /*******************************************************************
4206  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
4207 ********************************************************************/  
4208
4209 BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
4210 {
4211
4212         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
4213         depth++;
4214
4215         if (!prs_align(ps))
4216                 return False;
4217                 
4218         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4219                 return False;
4220         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
4221                 return False;
4222                 
4223         if (!prs_align(ps))
4224                 return False;
4225         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
4226                 return False;
4227         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4228                 return False;
4229                 
4230         if (!prs_align(ps))
4231                 return False;
4232         if (!prs_uint32("level", ps, depth, &q_u->level))
4233                 return False;
4234                 
4235         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4236                 return False;
4237
4238         if (!prs_align(ps))
4239                 return False;
4240                 
4241         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4242                 return False;
4243
4244         return True;
4245 }
4246
4247 /*******************************************************************
4248 ********************************************************************/  
4249
4250 BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
4251 {
4252
4253         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
4254         depth++;
4255
4256         if (!prs_align(ps))
4257                 return False;                   
4258         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4259                 return False;           
4260         if (!prs_uint32("level", ps, depth, &q_u->level))
4261                 return False;   
4262         
4263         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4264                 return False;
4265
4266         if (!prs_align(ps))
4267                 return False;
4268         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4269                 return False;
4270
4271         return True;
4272 }
4273
4274 /*******************************************************************
4275 ********************************************************************/  
4276
4277 BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
4278 {
4279         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
4280         depth++;
4281
4282         if (!prs_align(ps))
4283                 return False;
4284                 
4285         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4286                 return False;
4287
4288         if (!prs_align(ps))
4289                 return False;
4290                 
4291         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4292                 return False;
4293                 
4294         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
4295                 return False;
4296                 
4297         if (!prs_werror("status", ps, depth, &r_u->status))
4298                 return False;
4299
4300         return True;
4301 }
4302
4303 /*******************************************************************
4304 ********************************************************************/  
4305
4306 BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
4307 {
4308
4309         prs_debug(ps, depth, desc, "spoolss_io_q_getform");
4310         depth++;
4311
4312         if (!prs_align(ps))
4313                 return False;                   
4314         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4315                 return False;           
4316         if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
4317                 return False;
4318
4319         if (!prs_align(ps))
4320                 return False;
4321
4322         if (!prs_uint32("level", ps, depth, &q_u->level))
4323                 return False;   
4324         
4325         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4326                 return False;
4327
4328         if (!prs_align(ps))
4329                 return False;
4330         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4331                 return False;
4332
4333         return True;
4334 }
4335
4336 /*******************************************************************
4337 ********************************************************************/  
4338
4339 BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
4340 {
4341         prs_debug(ps, depth, desc, "spoolss_io_r_getform");
4342         depth++;
4343
4344         if (!prs_align(ps))
4345                 return False;
4346                 
4347         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4348                 return False;
4349
4350         if (!prs_align(ps))
4351                 return False;
4352                 
4353         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4354                 return False;
4355                 
4356         if (!prs_werror("status", ps, depth, &r_u->status))
4357                 return False;
4358
4359         return True;
4360 }
4361
4362 /*******************************************************************
4363  Parse a SPOOL_R_ENUMPORTS structure.
4364 ********************************************************************/  
4365
4366 BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
4367 {
4368         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
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("needed", ps, depth, &r_u->needed))
4381                 return False;
4382                 
4383         if (!prs_uint32("returned", ps, depth, &r_u->returned))
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
4395 BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
4396 {
4397         prs_debug(ps, depth, desc, "");
4398         depth++;
4399
4400         if (!prs_align(ps))
4401                 return False;
4402
4403         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
4404                 return False;
4405         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
4406                 return False;
4407
4408         if (!prs_align(ps))
4409                 return False;
4410         if (!prs_uint32("level", ps, depth, &q_u->level))
4411                 return False;
4412                 
4413         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4414                 return False;
4415
4416         if (!prs_align(ps))
4417                 return False;
4418         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4419                 return False;
4420
4421         return True;
4422 }
4423
4424 /*******************************************************************
4425  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
4426 ********************************************************************/  
4427
4428 BOOL spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
4429 {       
4430         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
4431         depth++;
4432                 
4433         if(!prs_align(ps))
4434                 return False;
4435
4436         if(!prs_uint32("flags", ps, depth, &il->flags))
4437                 return False;
4438         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
4439                 return False;
4440         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4441                 return False;
4442         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4443                 return False;
4444                 
4445         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
4446                 return False;
4447         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4448                 return False;
4449         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4450                 return False;
4451
4452         return True;
4453 }
4454
4455 /*******************************************************************
4456  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
4457 ********************************************************************/  
4458
4459 BOOL spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
4460 {       
4461         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
4462         depth++;
4463                 
4464         if(!prs_align(ps))
4465                 return False;
4466
4467         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4468                 return False;
4469
4470         return True;
4471 }
4472
4473 /*******************************************************************
4474  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
4475 ********************************************************************/  
4476
4477 BOOL spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
4478 {       
4479         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
4480         depth++;
4481                 
4482         if(!prs_align(ps))
4483                 return False;
4484
4485         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
4486                 return False;
4487         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
4488                 return False;
4489         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
4490                 return False;
4491         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
4492                 return False;
4493
4494         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
4495                 return False;
4496         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4497                 return False;
4498         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
4499                 return False;
4500         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
4501                 return False;
4502         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
4503                 return False;
4504         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
4505                 return False;
4506         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
4507                 return False;
4508         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
4509                 return False;
4510         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4511                 return False;
4512
4513         if(!prs_uint32("attributes", ps, depth, &il->attributes))
4514                 return False;
4515         if(!prs_uint32("priority", ps, depth, &il->priority))
4516                 return False;
4517         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
4518                 return False;
4519         if(!prs_uint32("starttime", ps, depth, &il->starttime))
4520                 return False;
4521         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
4522                 return False;
4523         if(!prs_uint32("status", ps, depth, &il->status))
4524                 return False;
4525         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
4526                 return False;
4527         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
4528                 return False;
4529
4530         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
4531                 return False;
4532         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
4533                 return False;
4534         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
4535                 return False;
4536         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
4537                 return False;
4538         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
4539                 return False;
4540         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4541                 return False;
4542         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
4543                 return False;
4544         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
4545                 return False;
4546         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
4547                 return False;
4548         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
4549                 return False;
4550         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
4551                 return False;
4552
4553         return True;
4554 }
4555
4556 BOOL spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
4557 {       
4558         prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
4559         depth++;
4560                 
4561         if(!prs_align(ps))
4562                 return False;
4563
4564         if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
4565                 return False;
4566         if(!prs_uint32("action", ps, depth, &il->action))
4567                 return False;
4568
4569         if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
4570                 return False;
4571         return True;
4572 }
4573
4574 /*******************************************************************
4575 ********************************************************************/  
4576
4577 BOOL spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
4578 {
4579         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
4580         depth++;
4581
4582         if(!prs_align(ps))
4583                 return False;
4584         if(!prs_uint32("level", ps, depth, &il->level))
4585                 return False;
4586         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
4587                 return False;
4588         
4589         /* if no struct inside just return */
4590         if (il->info_ptr==0) {
4591                 if (UNMARSHALLING(ps)) {
4592                         il->info_1=NULL;
4593                         il->info_2=NULL;
4594                 }
4595                 return True;
4596         }
4597                         
4598         switch (il->level) {
4599                 /*
4600                  * level 0 is used by setprinter when managing the queue
4601                  * (hold, stop, start a queue)
4602                  */
4603                 case 0:
4604                         break;
4605                 /* DOCUMENT ME!!! What is level 1 used for? */
4606                 case 1:
4607                 {
4608                         if (UNMARSHALLING(ps)) {
4609                                 if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
4610                                         return False;
4611                         }
4612                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
4613                                 return False;
4614                         break;          
4615                 }
4616                 /* 
4617                  * level 2 is used by addprinter
4618                  * and by setprinter when updating printer's info
4619                  */     
4620                 case 2:
4621                         if (UNMARSHALLING(ps)) {
4622                                 if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
4623                                         return False;
4624                         }
4625                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
4626                                 return False;
4627                         break;          
4628                 /* DOCUMENT ME!!! What is level 3 used for? */
4629                 case 3:
4630                 {
4631                         if (UNMARSHALLING(ps)) {
4632                                 if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
4633                                         return False;
4634                         }
4635                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
4636                                 return False;
4637                         break;          
4638                 }
4639                 case 7:
4640                         if (UNMARSHALLING(ps))
4641                                 if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
4642                                         return False;
4643                         if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
4644                                 return False;
4645                         break;
4646         }
4647
4648         return True;
4649 }
4650
4651 /*******************************************************************
4652 ********************************************************************/  
4653
4654 BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
4655 {
4656         uint32 ptr_sec_desc = 0;
4657
4658         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
4659         depth++;
4660
4661         if(!prs_align(ps))
4662                 return False;
4663
4664         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
4665                 return False;
4666         if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
4667                 return False;
4668
4669         if(!prs_align(ps))
4670                 return False;
4671
4672         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4673                 return False;
4674         
4675         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4676                 return False;
4677         
4678         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4679                 return False;
4680
4681         if(!prs_align(ps))
4682                 return False;
4683
4684         switch (q_u->level) {
4685                 case 2:
4686                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4687                         break;
4688                 case 3:
4689                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4690                         break;
4691         }
4692         if (ptr_sec_desc) {
4693                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
4694                         return False;
4695         } else {
4696                 uint32 dummy;
4697
4698                 /* Parse a NULL security descriptor.  This should really
4699                         happen inside the sec_io_desc_buf() function. */
4700
4701                 prs_debug(ps, depth, "", "sec_io_desc_buf");
4702                 if (!prs_uint32("size", ps, depth + 1, &dummy))
4703                         return False;
4704                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
4705                         return False;
4706         }
4707
4708         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
4709                 return False;
4710         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
4711                 return False;
4712
4713         return True;
4714 }
4715
4716 /*******************************************************************
4717 ********************************************************************/  
4718
4719 BOOL spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
4720                                prs_struct *ps, int depth)
4721 {
4722         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
4723         depth++;
4724         
4725         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
4726                 return False;
4727
4728         if(!prs_werror("status", ps, depth, &r_u->status))
4729                 return False;
4730
4731         return True;
4732 }
4733
4734 /*******************************************************************
4735 ********************************************************************/  
4736
4737 BOOL spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
4738                                           prs_struct *ps, int depth)
4739 {       
4740         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
4741         
4742         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
4743         depth++;
4744                 
4745         /* reading */
4746         if (UNMARSHALLING(ps)) {
4747                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
4748                 if(il == NULL)
4749                         return False;
4750                 *q_u=il;
4751         }
4752         else {
4753                 il=*q_u;
4754         }
4755         
4756         if(!prs_align(ps))
4757                 return False;
4758
4759         if(!prs_uint32("cversion", ps, depth, &il->cversion))
4760                 return False;
4761         if(!prs_uint32("name", ps, depth, &il->name_ptr))
4762                 return False;
4763         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
4764                 return False;
4765         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
4766                 return False;
4767         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
4768                 return False;
4769         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
4770                 return False;
4771         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
4772                 return False;
4773         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
4774                 return False;
4775         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4776                 return False;
4777         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
4778                 return False;
4779         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
4780                 return False;
4781
4782         if(!prs_align(ps))
4783                 return False;
4784         
4785         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4786                 return False;
4787         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4788                 return False;
4789         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4790                 return False;
4791         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4792                 return False;
4793         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4794                 return False;
4795         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4796                 return False;
4797         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4798                 return False;
4799         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4800                 return False;
4801
4802         if(!prs_align(ps))
4803                 return False;
4804                 
4805         if (il->dependentfiles_ptr)
4806                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
4807
4808         return True;
4809 }
4810
4811 /*******************************************************************
4812 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
4813 ********************************************************************/  
4814
4815 BOOL spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
4816                                           prs_struct *ps, int depth)
4817 {       
4818         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
4819         
4820         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
4821         depth++;
4822                 
4823         /* reading */
4824         if (UNMARSHALLING(ps)) {
4825                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
4826                 if(il == NULL)
4827                         return False;
4828                 *q_u=il;
4829         }
4830         else {
4831                 il=*q_u;
4832         }
4833         
4834         if(!prs_align(ps))
4835                 return False;
4836
4837         /* 
4838          * I know this seems weird, but I have no other explanation.
4839          * This is observed behavior on both NT4 and 2K servers.
4840          * --jerry
4841          */
4842          
4843         if (!prs_align_uint64(ps))
4844                 return False;
4845
4846         /* parse the main elements the packet */
4847
4848         if(!prs_uint32("cversion       ", ps, depth, &il->version))
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("dependentfiles ", ps, depth, &il->dependentfiles_len))
4867                 return False;
4868         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
4869                 return False;
4870         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
4871                 return False;
4872         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
4873                 return False;
4874         if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
4875                 return False;
4876         if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
4877                 return False;
4878         if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
4879                 return False;
4880         if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
4881                 return False;
4882         if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
4883                 return False;
4884         if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
4885                 return False;
4886         if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
4887                 return False;
4888
4889         /* parse the structures in the packet */
4890
4891         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4892                 return False;
4893         if(!prs_align(ps))
4894                 return False;
4895
4896         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4897                 return False;
4898         if(!prs_align(ps))
4899                 return False;
4900
4901         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4902                 return False;
4903         if(!prs_align(ps))
4904                 return False;
4905
4906         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4907                 return False;
4908         if(!prs_align(ps))
4909                 return False;
4910
4911         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4912                 return False;
4913         if(!prs_align(ps))
4914                 return False;
4915
4916         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4917                 return False;
4918         if(!prs_align(ps))
4919                 return False;
4920
4921         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4922                 return False;
4923         if(!prs_align(ps))
4924                 return False;
4925
4926         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4927                 return False;
4928         if(!prs_align(ps))
4929                 return False;
4930         if (il->dependentfiles_ptr) {
4931                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
4932                         return False;
4933                 if(!prs_align(ps))
4934                         return False;
4935         }
4936         if (il->previousnames_ptr) {
4937                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
4938                         return False;
4939                 if(!prs_align(ps))
4940                         return False;
4941         }
4942         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
4943                 return False;
4944         if(!prs_align(ps))
4945                 return False;
4946         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
4947                 return False;
4948         if(!prs_align(ps))
4949                 return False;
4950         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
4951                 return False;
4952         if(!prs_align(ps))
4953                 return False;
4954         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
4955                 return False;
4956
4957         return True;
4958 }
4959
4960 /*******************************************************************
4961  convert a buffer of UNICODE strings null terminated
4962  the buffer is terminated by a NULL
4963  
4964  convert to an dos codepage array (null terminated)
4965  
4966  dynamically allocate memory
4967  
4968 ********************************************************************/  
4969 static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
4970 {
4971         fstring f;
4972         int n = 0;
4973         char *src;
4974
4975         if (buf5==NULL)
4976                 return False;
4977
4978         src = (char *)buf5->buffer;
4979         *ar = NULL;
4980
4981         while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
4982                 rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
4983                 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
4984                 *ar = SMB_REALLOC_ARRAY(*ar, fstring, n+2);
4985                 if (!*ar)
4986                         return False;
4987                 fstrcpy((*ar)[n], f);
4988                 n++;
4989         }
4990         fstrcpy((*ar)[n], "");
4991  
4992         return True;
4993 }
4994
4995
4996
4997
4998 /*******************************************************************
4999  read a UNICODE array with null terminated strings 
5000  and null terminated array 
5001  and size of array at beginning
5002 ********************************************************************/  
5003
5004 BOOL smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
5005 {
5006         if (buffer==NULL) return False;
5007
5008         buffer->offset=0;
5009         buffer->uni_str_len=buffer->uni_max_len;
5010         
5011         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
5012                 return False;
5013
5014         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
5015                 return False;
5016
5017         return True;
5018 }
5019
5020 /*******************************************************************
5021 ********************************************************************/  
5022
5023 BOOL spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
5024 {
5025         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
5026         depth++;
5027
5028         if(!prs_align(ps))
5029                 return False;
5030         if(!prs_uint32("level", ps, depth, &il->level))
5031                 return False;
5032         if(!prs_uint32("ptr", ps, depth, &il->ptr))
5033                 return False;
5034
5035         if (il->ptr==0)
5036                 return True;
5037                 
5038         switch (il->level) {
5039                 case 3:
5040                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
5041                                 return False;
5042                         break;          
5043                 case 6:
5044                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
5045                                 return False;
5046                         break;          
5047         default:
5048                 return False;
5049         }
5050
5051         return True;
5052 }
5053
5054 /*******************************************************************
5055  init a SPOOL_Q_ADDPRINTERDRIVER struct
5056  ******************************************************************/
5057
5058 BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
5059                                 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
5060                                 uint32 level, PRINTER_DRIVER_CTR *info)
5061 {
5062         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
5063         
5064         if (!srv_name || !info) {
5065                 return False;
5066         }
5067
5068         q_u->server_name_ptr = (srv_name!=NULL)?1:0;
5069         init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
5070         
5071         q_u->level = level;
5072         
5073         q_u->info.level = level;
5074         q_u->info.ptr = (info!=NULL)?1:0;
5075         switch (level)
5076         {
5077         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
5078         case 3 :
5079                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
5080                 break;
5081                 
5082         default:
5083                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
5084                 break;
5085         }
5086         
5087         return True;
5088 }
5089
5090 BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, 
5091         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
5092                                 DRIVER_INFO_3 *info3)
5093 {
5094         uint32          len = 0;
5095         uint16          *ptr = info3->dependentfiles;
5096         BOOL            done = False;
5097         BOOL            null_char = False;
5098         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
5099
5100         if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
5101                 return False;
5102         
5103         inf->cversion   = info3->version;
5104         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
5105         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
5106         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
5107         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
5108         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
5109         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
5110         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
5111         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
5112
5113         init_unistr2_from_unistr(&inf->name, &info3->name);
5114         init_unistr2_from_unistr(&inf->environment, &info3->architecture);
5115         init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
5116         init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
5117         init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
5118         init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
5119         init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
5120         init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
5121
5122         while (!done)
5123         {
5124                 switch (*ptr)
5125                 {
5126                         case 0:
5127                                 /* the null_char BOOL is used to help locate
5128                                    two '\0's back to back */
5129                                 if (null_char)
5130                                         done = True;
5131                                 else
5132                                         null_char = True;
5133                                 break;
5134                                         
5135                         default:
5136                                 null_char = False;
5137                                 ;;
5138                                 break;                          
5139                 }
5140                 len++;
5141                 ptr++;
5142         }
5143         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
5144         inf->dependentfilessize = len;
5145         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles))
5146         {
5147                 SAFE_FREE(inf);
5148                 return False;
5149         }
5150         
5151         *spool_drv_info = inf;
5152         
5153         return True;
5154 }
5155
5156 /*******************************************************************
5157  make a BUFFER5 struct from a uint16*
5158  ******************************************************************/
5159 BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
5160 {
5161
5162         buf5->buf_len = len;
5163         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
5164                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
5165                 return False;
5166         }
5167         
5168         return True;
5169 }
5170
5171 /*******************************************************************
5172  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5173  ********************************************************************/  
5174
5175 BOOL spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5176 {
5177         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
5178         depth++;
5179
5180         if(!prs_align(ps))
5181                 return False;
5182
5183         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5184                 return False;
5185         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5186                 return False;
5187                 
5188         if(!prs_align(ps))
5189                 return False;
5190         if(!prs_uint32("info_level", ps, depth, &q_u->level))
5191                 return False;
5192
5193         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5194                 return False;
5195
5196         return True;
5197 }
5198
5199 /*******************************************************************
5200 ********************************************************************/  
5201
5202 BOOL spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5203 {
5204         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
5205         depth++;
5206
5207         if(!prs_werror("status", ps, depth, &q_u->status))
5208                 return False;
5209
5210         return True;
5211 }
5212
5213 /*******************************************************************
5214  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5215  ********************************************************************/  
5216
5217 BOOL spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5218 {
5219         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
5220         depth++;
5221
5222         if(!prs_align(ps))
5223                 return False;
5224
5225         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5226                 return False;
5227         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5228                 return False;
5229                 
5230         if(!prs_align(ps))
5231                 return False;
5232         if(!prs_uint32("info_level", ps, depth, &q_u->level))
5233                 return False;
5234
5235         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5236                 return False;
5237
5238         if(!prs_align(ps))
5239                 return False;
5240         if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
5241                 return False;
5242                 
5243         return True;
5244 }
5245
5246 /*******************************************************************
5247 ********************************************************************/  
5248
5249 BOOL spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5250 {
5251         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
5252         depth++;
5253
5254         if(!prs_werror("status", ps, depth, &q_u->status))
5255                 return False;
5256
5257         return True;
5258 }
5259
5260 /*******************************************************************
5261 ********************************************************************/  
5262
5263 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
5264                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
5265 {
5266         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
5267         
5268         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
5269         
5270         if (*asc==NULL)
5271         {
5272                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
5273                 if(*asc == NULL)
5274                         return False;
5275                 ZERO_STRUCTP(*asc);
5276         }       
5277
5278         d=*asc;
5279
5280         d->cversion=uni->cversion;
5281
5282         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5283         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5284         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5285         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5286         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5287         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5288         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5289         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5290
5291         DEBUGADD(8,( "version:         %d\n", d->cversion));
5292         DEBUGADD(8,( "name:            %s\n", d->name));
5293         DEBUGADD(8,( "environment:     %s\n", d->environment));
5294         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5295         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5296         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5297         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5298         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5299         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5300
5301         if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5302                 return True;
5303         
5304         SAFE_FREE(*asc);
5305         return False;
5306 }
5307
5308 /*******************************************************************
5309 ********************************************************************/  
5310 BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
5311                                 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
5312 {
5313         NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
5314         
5315         DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
5316         
5317         if (*asc==NULL)
5318         {
5319                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
5320                 if(*asc == NULL)
5321                         return False;
5322                 ZERO_STRUCTP(*asc);
5323         }       
5324
5325         d=*asc;
5326
5327         d->version=uni->version;
5328
5329         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5330         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5331         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5332         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5333         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5334         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5335         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5336         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5337
5338         DEBUGADD(8,( "version:         %d\n", d->version));
5339         DEBUGADD(8,( "name:            %s\n", d->name));
5340         DEBUGADD(8,( "environment:     %s\n", d->environment));
5341         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5342         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5343         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5344         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5345         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5346         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5347
5348         if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5349                 goto error;
5350         if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
5351                 goto error;
5352         
5353         return True;
5354         
5355 error:
5356         SAFE_FREE(*asc);
5357         return False;
5358 }
5359
5360 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
5361                               NT_PRINTER_INFO_LEVEL_2  *d)
5362 {
5363         DEBUG(7,("Converting from UNICODE to ASCII\n"));
5364         
5365         d->attributes=uni->attributes;
5366         d->priority=uni->priority;
5367         d->default_priority=uni->default_priority;
5368         d->starttime=uni->starttime;
5369         d->untiltime=uni->untiltime;
5370         d->status=uni->status;
5371         d->cjobs=uni->cjobs;
5372         
5373         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
5374         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
5375         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
5376         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
5377         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
5378         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
5379         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
5380         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
5381         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
5382         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
5383         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
5384
5385         return True;
5386 }
5387
5388 /*******************************************************************
5389  * init a structure.
5390  ********************************************************************/
5391
5392 BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
5393                                 fstring servername, fstring env_name, uint32 level,
5394                                 RPC_BUFFER *buffer, uint32 offered)
5395 {
5396         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
5397         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
5398
5399         q_u->level=level;
5400         q_u->buffer=buffer;
5401         q_u->offered=offered;
5402
5403         return True;
5404 }
5405
5406 /*******************************************************************
5407  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
5408 ********************************************************************/  
5409
5410 BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
5411 {
5412         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
5413         depth++;
5414
5415         if(!prs_align(ps))
5416                 return False;
5417         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5418                 return False;
5419         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
5420                 return False;
5421
5422         if(!prs_align(ps))
5423                 return False;
5424                 
5425         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
5426                 return False;
5427         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5428                 return False;
5429                 
5430         if(!prs_align(ps))
5431                 return False;
5432
5433         if(!prs_uint32("level", ps, depth, &q_u->level))
5434                 return False;
5435                 
5436         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5437                 return False;
5438                 
5439         if(!prs_align(ps))
5440                 return False;
5441                 
5442         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5443                 return False;
5444
5445         return True;
5446 }
5447
5448 /*******************************************************************
5449  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
5450 ********************************************************************/  
5451
5452 BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
5453 {               
5454         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
5455         depth++;
5456
5457         if (!prs_align(ps))
5458                 return False;
5459                 
5460         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5461                 return False;
5462
5463         if (!prs_align(ps))
5464                 return False;
5465                 
5466         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5467                 return False;
5468                 
5469         if (!prs_werror("status", ps, depth, &r_u->status))
5470                 return False;
5471
5472         return True;            
5473 }
5474
5475 /*******************************************************************
5476 ********************************************************************/  
5477
5478 BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
5479 {               
5480         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
5481         depth++;
5482
5483         if (!prs_align(ps))
5484                 return False;
5485                 
5486         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5487                 return False;
5488
5489         if (!prs_align(ps))
5490                 return False;
5491                 
5492         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5493                 return False;
5494                 
5495         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5496                 return False;
5497                 
5498         if (!prs_werror("status", ps, depth, &r_u->status))
5499                 return False;
5500
5501         return True;            
5502 }
5503
5504 /*******************************************************************
5505 ********************************************************************/  
5506
5507 BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
5508 {
5509         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
5510         depth++;
5511
5512         if (!prs_align(ps))
5513                 return False;
5514                 
5515         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5516                 return False;
5517         if (!smb_io_unistr2("name", &q_u->name, True, 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 ********************************************************************/  
5548
5549 BOOL spoolss_io_q_addprintprocessor(const char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
5550 {
5551         prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
5552         depth++;
5553
5554         if (!prs_align(ps))
5555                 return False;
5556                 
5557         if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
5558                 return False;
5559         if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
5560                 return False;
5561                 
5562         if (!prs_align(ps))
5563                 return False;
5564         if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
5565                 return False;
5566                 
5567         if (!prs_align(ps))
5568                 return False;
5569         if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
5570                 return False;
5571
5572         if (!prs_align(ps))
5573                 return False;
5574         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5575                 return False;
5576
5577         return True;
5578 }
5579
5580 /*******************************************************************
5581 ********************************************************************/  
5582
5583 BOOL spoolss_io_r_addprintprocessor(const char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
5584 {               
5585         prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor");
5586         depth++;
5587
5588         if (!prs_align(ps))
5589                 return False;
5590                 
5591         if (!prs_werror("status", ps, depth, &r_u->status))
5592                 return False;
5593
5594         return True;            
5595 }
5596
5597 /*******************************************************************
5598 ********************************************************************/  
5599
5600 BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
5601 {               
5602         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
5603         depth++;
5604
5605         if (!prs_align(ps))
5606                 return False;
5607                 
5608         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5609                 return False;
5610
5611         if (!prs_align(ps))
5612                 return False;
5613                 
5614         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5615                 return False;
5616                 
5617         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5618                 return False;
5619                 
5620         if (!prs_werror("status", ps, depth, &r_u->status))
5621                 return False;
5622
5623         return True;            
5624 }
5625
5626 /*******************************************************************
5627 ********************************************************************/  
5628
5629 BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
5630 {
5631         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
5632         depth++;
5633
5634         if (!prs_align(ps))
5635                 return False;
5636                 
5637         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5638                 return False;
5639         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5640                 return False;
5641                 
5642         if (!prs_align(ps))
5643                 return False;
5644                 
5645         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
5646                 return False;
5647         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
5648                 return False;
5649         
5650         if (!prs_align(ps))
5651                 return False;
5652                 
5653         if (!prs_uint32("level", ps, depth, &q_u->level))
5654                 return False;
5655                 
5656         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
5657                 return False;
5658
5659         if (!prs_align(ps))
5660                 return False;
5661
5662         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5663                 return False;
5664
5665         return True;
5666 }
5667
5668 /*******************************************************************
5669  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
5670 ********************************************************************/  
5671
5672 BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
5673 {
5674         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
5675         depth++;
5676
5677         if (!prs_align(ps))
5678                 return False;
5679                 
5680         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5681                 return False;
5682         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5683                 return False;
5684                 
5685         if (!prs_align(ps))
5686                 return False;
5687                                 
5688         if (!prs_uint32("level", ps, depth, &q_u->level))
5689                 return False;
5690                 
5691         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5692                 return False;
5693
5694         if (!prs_align(ps))
5695                 return False;
5696
5697         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5698                 return False;
5699
5700         return True;
5701 }
5702
5703 /*******************************************************************
5704 ********************************************************************/  
5705
5706 BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
5707 {               
5708         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
5709         depth++;
5710
5711         if (!prs_align(ps))
5712                 return False;
5713                 
5714         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5715                 return False;
5716
5717         if (!prs_align(ps))
5718                 return False;
5719                 
5720         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5721                 return False;
5722                 
5723         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5724                 return False;
5725                 
5726         if (!prs_werror("status", ps, depth, &r_u->status))
5727                 return False;
5728
5729         return True;            
5730 }
5731
5732 /*******************************************************************
5733 ********************************************************************/  
5734
5735 BOOL spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
5736 {       
5737         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
5738         depth++;
5739
5740         if(!prs_align(ps))
5741                 return False;
5742         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
5743                 return False;
5744
5745         if (UNMARSHALLING(ps) && r_u->valuesize) {
5746                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
5747                 if (!r_u->value) {
5748                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
5749                         return False;
5750                 }
5751         }
5752
5753         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
5754                 return False;
5755
5756         if(!prs_align(ps))
5757                 return False;
5758
5759         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
5760                 return False;
5761
5762         if(!prs_uint32("type", ps, depth, &r_u->type))
5763                 return False;
5764
5765         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
5766                 return False;
5767
5768         if (UNMARSHALLING(ps) && r_u->datasize) {
5769                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
5770                 if (!r_u->data) {
5771                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
5772                         return False;
5773                 }
5774         }
5775
5776         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
5777                 return False;
5778         if(!prs_align(ps))
5779                 return False;
5780
5781         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
5782                 return False;
5783         if(!prs_werror("status", ps, depth, &r_u->status))
5784                 return False;
5785
5786         return True;
5787 }
5788
5789 /*******************************************************************
5790 ********************************************************************/  
5791
5792 BOOL spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
5793 {
5794         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
5795         depth++;
5796
5797         if(!prs_align(ps))
5798                 return False;
5799         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5800                 return False;
5801         if(!prs_uint32("index", ps, depth, &q_u->index))
5802                 return False;
5803         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
5804                 return False;
5805         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
5806                 return False;
5807
5808         return True;
5809 }
5810
5811 /*******************************************************************
5812 ********************************************************************/  
5813
5814 BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
5815                 const POLICY_HND *hnd,
5816                 uint32 idx, uint32 valuelen, uint32 datalen)
5817 {
5818         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5819         q_u->index=idx;
5820         q_u->valuesize=valuelen;
5821         q_u->datasize=datalen;
5822
5823         return True;
5824 }
5825
5826 /*******************************************************************
5827 ********************************************************************/  
5828
5829 BOOL make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
5830                                       const POLICY_HND *hnd, const char *key,
5831                                       uint32 size)
5832 {
5833         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5834         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5835         q_u->size = size;
5836
5837         return True;
5838 }
5839
5840 /*******************************************************************
5841 ********************************************************************/  
5842 BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
5843                                    char* value, uint32 data_type, char* data, uint32 data_size)
5844 {
5845         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5846         q_u->type = data_type;
5847         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
5848
5849         q_u->max_len = q_u->real_len = data_size;
5850         q_u->data = (unsigned char *)data;
5851         
5852         return True;
5853 }
5854
5855 /*******************************************************************
5856 ********************************************************************/  
5857 BOOL make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY_HND *hnd,
5858                                      char *key, char* value, uint32 data_type, char* data, 
5859                                      uint32 data_size)
5860 {
5861         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5862         q_u->type = data_type;
5863         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
5864         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5865
5866         q_u->max_len = q_u->real_len = data_size;
5867         q_u->data = (unsigned char *)data;
5868         
5869         return True;
5870 }
5871
5872 /*******************************************************************
5873 ********************************************************************/  
5874
5875 BOOL spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
5876 {
5877         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
5878         depth++;
5879
5880         if(!prs_align(ps))
5881                 return False;
5882         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5883                 return False;
5884         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
5885                 return False;
5886
5887         if(!prs_align(ps))
5888                 return False;
5889
5890         if(!prs_uint32("type", ps, depth, &q_u->type))
5891                 return False;
5892
5893         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
5894                 return False;
5895
5896         switch (q_u->type)
5897         {
5898                 case REG_SZ:
5899                 case REG_BINARY:
5900                 case REG_DWORD:
5901                 case REG_MULTI_SZ:
5902             if (q_u->max_len) {
5903                 if (UNMARSHALLING(ps))
5904                                 q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
5905                         if(q_u->data == NULL)
5906                                 return False;
5907                         if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
5908                                 return False;
5909             }
5910                         if(!prs_align(ps))
5911                                 return False;
5912                         break;
5913         }       
5914         
5915         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
5916                 return False;
5917
5918         return True;
5919 }
5920
5921 /*******************************************************************
5922 ********************************************************************/  
5923
5924 BOOL spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
5925 {
5926         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
5927         depth++;
5928
5929         if(!prs_align(ps))
5930                 return False;
5931         if(!prs_werror("status",     ps, depth, &r_u->status))
5932                 return False;
5933
5934         return True;
5935 }
5936
5937 /*******************************************************************
5938 ********************************************************************/  
5939 BOOL spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
5940 {
5941         prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
5942         depth++;
5943
5944         if (!prs_align(ps))
5945                 return False;
5946         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5947                 return False;
5948
5949         if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
5950                 return False;
5951                 
5952         if (q_u->datatype_ptr) {
5953                 if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
5954                 return False;
5955         }
5956
5957         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
5958                 return False;
5959
5960         return True;
5961 }
5962
5963
5964 /*******************************************************************
5965 ********************************************************************/  
5966 BOOL spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
5967 {
5968         prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
5969         depth++;
5970
5971         if(!prs_align(ps))
5972                 return False;
5973         if(!prs_werror("status",     ps, depth, &r_u->status))
5974                 return False;
5975
5976         return True;
5977 }
5978
5979 /*******************************************************************
5980 ********************************************************************/  
5981
5982 static BOOL spoolss_io_addform(const char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
5983 {
5984         prs_debug(ps, depth, desc, "spoolss_io_addform");
5985         depth++;
5986         if(!prs_align(ps))
5987                 return False;
5988
5989         if (ptr!=0)
5990         {
5991                 if(!prs_uint32("flags",    ps, depth, &f->flags))
5992                         return False;
5993                 if(!prs_uint32("name_ptr", ps, depth, &f->name_ptr))
5994                         return False;
5995                 if(!prs_uint32("size_x",   ps, depth, &f->size_x))
5996                         return False;
5997                 if(!prs_uint32("size_y",   ps, depth, &f->size_y))
5998                         return False;
5999                 if(!prs_uint32("left",     ps, depth, &f->left))
6000                         return False;
6001                 if(!prs_uint32("top",      ps, depth, &f->top))
6002                         return False;
6003                 if(!prs_uint32("right",    ps, depth, &f->right))
6004                         return False;
6005                 if(!prs_uint32("bottom",   ps, depth, &f->bottom))
6006                         return False;
6007
6008                 if(!smb_io_unistr2("", &f->name, f->name_ptr, ps, depth))
6009                         return False;
6010         }
6011
6012         return True;
6013 }
6014
6015 /*******************************************************************
6016 ********************************************************************/  
6017
6018 BOOL spoolss_io_q_deleteform(const char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth)
6019 {
6020         prs_debug(ps, depth, desc, "spoolss_io_q_deleteform");
6021         depth++;
6022
6023         if(!prs_align(ps))
6024                 return False;
6025         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6026                 return False;
6027         if(!smb_io_unistr2("form name", &q_u->name, True, ps, depth))
6028                 return False;
6029
6030         return True;
6031 }
6032
6033 /*******************************************************************
6034 ********************************************************************/  
6035
6036 BOOL spoolss_io_r_deleteform(const char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth)
6037 {
6038         prs_debug(ps, depth, desc, "spoolss_io_r_deleteform");
6039         depth++;
6040
6041         if(!prs_align(ps))
6042                 return False;
6043         if(!prs_werror("status",        ps, depth, &r_u->status))
6044                 return False;
6045
6046         return True;
6047 }
6048
6049 /*******************************************************************
6050 ********************************************************************/  
6051
6052 BOOL spoolss_io_q_addform(const char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
6053 {
6054         uint32 useless_ptr=1;
6055         prs_debug(ps, depth, desc, "spoolss_io_q_addform");
6056         depth++;
6057
6058         if(!prs_align(ps))
6059                 return False;
6060         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6061                 return False;
6062         if(!prs_uint32("level",  ps, depth, &q_u->level))
6063                 return False;
6064         if(!prs_uint32("level2", ps, depth, &q_u->level2))
6065                 return False;
6066
6067         if (q_u->level==1)
6068         {
6069                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6070                         return False;
6071                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6072                         return False;
6073         }
6074
6075         return True;
6076 }
6077
6078 /*******************************************************************
6079 ********************************************************************/  
6080
6081 BOOL spoolss_io_r_addform(const char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
6082 {
6083         prs_debug(ps, depth, desc, "spoolss_io_r_addform");
6084         depth++;
6085
6086         if(!prs_align(ps))
6087                 return False;
6088         if(!prs_werror("status",        ps, depth, &r_u->status))
6089                 return False;
6090
6091         return True;
6092 }
6093
6094 /*******************************************************************
6095 ********************************************************************/  
6096
6097 BOOL spoolss_io_q_setform(const char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
6098 {
6099         uint32 useless_ptr=1;
6100         prs_debug(ps, depth, desc, "spoolss_io_q_setform");
6101         depth++;
6102
6103         if(!prs_align(ps))
6104                 return False;
6105         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6106                 return False;
6107         if(!smb_io_unistr2("", &q_u->name, True, ps, depth))
6108                 return False;
6109               
6110         if(!prs_align(ps))
6111                 return False;
6112         
6113         if(!prs_uint32("level",  ps, depth, &q_u->level))
6114                 return False;
6115         if(!prs_uint32("level2", ps, depth, &q_u->level2))
6116                 return False;
6117
6118         if (q_u->level==1)
6119         {
6120                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6121                         return False;
6122                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6123                         return False;
6124         }
6125
6126         return True;
6127 }
6128
6129 /*******************************************************************
6130 ********************************************************************/  
6131
6132 BOOL spoolss_io_r_setform(const char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
6133 {
6134         prs_debug(ps, depth, desc, "spoolss_io_r_setform");
6135         depth++;
6136
6137         if(!prs_align(ps))
6138                 return False;
6139         if(!prs_werror("status",        ps, depth, &r_u->status))
6140                 return False;
6141
6142         return True;
6143 }
6144
6145 /*******************************************************************
6146  Parse a SPOOL_R_GETJOB structure.
6147 ********************************************************************/  
6148
6149 BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
6150 {               
6151         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
6152         depth++;
6153
6154         if (!prs_align(ps))
6155                 return False;
6156                 
6157         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
6158                 return False;
6159
6160         if (!prs_align(ps))
6161                 return False;
6162                 
6163         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6164                 return False;
6165                 
6166         if (!prs_werror("status", ps, depth, &r_u->status))
6167                 return False;
6168
6169         return True;            
6170 }
6171
6172 /*******************************************************************
6173  Parse a SPOOL_Q_GETJOB structure.
6174 ********************************************************************/  
6175
6176 BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
6177 {
6178         prs_debug(ps, depth, desc, "");
6179         depth++;
6180
6181         if(!prs_align(ps))
6182                 return False;
6183
6184         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6185                 return False;
6186         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
6187                 return False;
6188         if(!prs_uint32("level", ps, depth, &q_u->level))
6189                 return False;
6190         
6191         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
6192                 return False;
6193
6194         if(!prs_align(ps))
6195                 return False;
6196         
6197         if(!prs_uint32("offered", ps, depth, &q_u->offered))
6198                 return False;
6199
6200         return True;
6201 }
6202
6203 void free_devmode(DEVICEMODE *devmode)
6204 {
6205         if (devmode!=NULL) {
6206                 SAFE_FREE(devmode->dev_private);
6207                 SAFE_FREE(devmode);
6208         }
6209 }
6210
6211 void free_printer_info_1(PRINTER_INFO_1 *printer)
6212 {
6213         SAFE_FREE(printer);
6214 }
6215
6216 void free_printer_info_2(PRINTER_INFO_2 *printer)
6217 {
6218         if (printer!=NULL) {
6219                 free_devmode(printer->devmode);
6220                 printer->devmode = NULL;
6221                 SAFE_FREE(printer);
6222         }
6223 }
6224
6225 void free_printer_info_3(PRINTER_INFO_3 *printer)
6226 {
6227         SAFE_FREE(printer);
6228 }
6229
6230 void free_printer_info_4(PRINTER_INFO_4 *printer)
6231 {
6232         SAFE_FREE(printer);
6233 }
6234
6235 void free_printer_info_5(PRINTER_INFO_5 *printer)
6236 {
6237         SAFE_FREE(printer);
6238 }
6239
6240 void free_printer_info_7(PRINTER_INFO_7 *printer)
6241 {
6242         SAFE_FREE(printer);
6243 }
6244
6245 void free_job_info_2(JOB_INFO_2 *job)
6246 {
6247     if (job!=NULL)
6248         free_devmode(job->devmode);
6249 }
6250
6251 /*******************************************************************
6252  * init a structure.
6253  ********************************************************************/
6254
6255 BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u, 
6256                                const fstring string, uint32 printer, uint32 type)
6257 {      
6258         if (q_u == NULL)
6259                 return False;
6260
6261         init_unistr2(&q_u->string, string, UNI_STR_TERMINATE);
6262
6263         q_u->printer=printer;
6264         q_u->type=type;
6265
6266         q_u->unknown0=0x0;
6267         q_u->unknown1=0x0;
6268
6269         return True;
6270 }
6271
6272 /*******************************************************************
6273  Parse a SPOOL_Q_REPLYOPENPRINTER structure.
6274 ********************************************************************/  
6275
6276 BOOL spoolss_io_q_replyopenprinter(const char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
6277 {
6278         prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
6279         depth++;
6280
6281         if(!prs_align(ps))
6282                 return False;
6283
6284         if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
6285                 return False;
6286
6287         if(!prs_align(ps))
6288                 return False;
6289
6290         if(!prs_uint32("printer", ps, depth, &q_u->printer))
6291                 return False;
6292         if(!prs_uint32("type", ps, depth, &q_u->type))
6293                 return False;
6294         
6295         if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6296                 return False;
6297         if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6298                 return False;
6299
6300         return True;
6301 }
6302
6303 /*******************************************************************
6304  Parse a SPOOL_R_REPLYOPENPRINTER structure.
6305 ********************************************************************/  
6306
6307 BOOL spoolss_io_r_replyopenprinter(const char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
6308 {               
6309         prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
6310         depth++;
6311
6312         if (!prs_align(ps))
6313                 return False;
6314
6315         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6316                 return False;
6317
6318         if (!prs_werror("status", ps, depth, &r_u->status))
6319                 return False;
6320
6321         return True;            
6322 }
6323
6324 /*******************************************************************
6325  * init a structure.
6326  ********************************************************************/
6327 BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd, 
6328                                         uint32 condition, uint32 change_id)
6329 {
6330
6331         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6332
6333         q_u->condition = condition;
6334         q_u->change_id = change_id;
6335
6336         /* magic values */
6337         q_u->unknown1 = 0x1;
6338         memset(q_u->unknown2, 0x0, 5);
6339         q_u->unknown2[0] = 0x1;
6340
6341         return True;
6342 }
6343
6344 /*******************************************************************
6345  Parse a SPOOL_Q_ROUTERREPLYPRINTER structure.
6346 ********************************************************************/
6347 BOOL spoolss_io_q_routerreplyprinter (const char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth)
6348 {
6349
6350         prs_debug(ps, depth, desc, "spoolss_io_q_routerreplyprinter");
6351         depth++;
6352
6353         if (!prs_align(ps))
6354                 return False;
6355
6356         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6357                 return False;
6358
6359         if (!prs_uint32("condition", ps, depth, &q_u->condition))
6360                 return False;
6361
6362         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6363                 return False;
6364
6365         if (!prs_uint32("change_id", ps, depth, &q_u->change_id))
6366                 return False;
6367
6368         if (!prs_uint8s(False, "dev_private",  ps, depth, q_u->unknown2, 5))
6369                 return False;
6370
6371         return True;
6372 }
6373
6374 /*******************************************************************
6375  Parse a SPOOL_R_ROUTERREPLYPRINTER structure.
6376 ********************************************************************/
6377 BOOL spoolss_io_r_routerreplyprinter (const char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth)
6378 {
6379         prs_debug(ps, depth, desc, "spoolss_io_r_routerreplyprinter");
6380         depth++;
6381
6382         if (!prs_align(ps))
6383                 return False;
6384
6385         if (!prs_werror("status", ps, depth, &r_u->status))
6386                 return False;
6387
6388         return True;
6389 }
6390
6391 /*******************************************************************
6392  * init a structure.
6393  ********************************************************************/
6394
6395 BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd)
6396 {      
6397         if (q_u == NULL)
6398                 return False;
6399
6400         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6401
6402         return True;
6403 }
6404
6405 /*******************************************************************
6406  Parse a SPOOL_Q_REPLYCLOSEPRINTER structure.
6407 ********************************************************************/  
6408
6409 BOOL spoolss_io_q_replycloseprinter(const char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth)
6410 {
6411         prs_debug(ps, depth, desc, "spoolss_io_q_replycloseprinter");
6412         depth++;
6413
6414         if(!prs_align(ps))
6415                 return False;
6416
6417         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6418                 return False;
6419
6420         return True;
6421 }
6422
6423 /*******************************************************************
6424  Parse a SPOOL_R_REPLYCLOSEPRINTER structure.
6425 ********************************************************************/  
6426
6427 BOOL spoolss_io_r_replycloseprinter(const char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth)
6428 {               
6429         prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
6430         depth++;
6431
6432         if (!prs_align(ps))
6433                 return False;
6434
6435         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6436                 return False;
6437
6438         if (!prs_werror("status", ps, depth, &r_u->status))
6439                 return False;
6440
6441         return True;            
6442 }
6443
6444 #if 0   /* JERRY - not currently used but could be :-) */
6445
6446 /*******************************************************************
6447  Deep copy a SPOOL_NOTIFY_INFO_DATA structure
6448  ******************************************************************/
6449 static BOOL copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, 
6450                                 SPOOL_NOTIFY_INFO_DATA *src, int n)
6451 {
6452         int i;
6453
6454         memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
6455         
6456         for (i=0; i<n; i++) {
6457                 int len;
6458                 uint16 *s = NULL;
6459                 
6460                 if (src->size != POINTER) 
6461                         continue;
6462                 len = src->notify_data.data.length;
6463                 s = SMB_MALLOC_ARRAY(uint16, len);
6464                 if (s == NULL) {
6465                         DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
6466                         return False;
6467                 }
6468                 
6469                 memcpy(s, src->notify_data.data.string, len*2);
6470                 dst->notify_data.data.string = s;
6471         }
6472         
6473         return True;
6474 }
6475
6476 /*******************************************************************
6477  Deep copy a SPOOL_NOTIFY_INFO structure
6478  ******************************************************************/
6479 static BOOL copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
6480 {
6481         if (!dst) {
6482                 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
6483                 return False;
6484         }
6485                 
6486         dst->version = src->version;
6487         dst->flags   = src->flags;
6488         dst->count   = src->count;
6489         
6490         if (dst->count) 
6491         {
6492                 dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count);
6493                 
6494                 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
6495                         dst->count));
6496
6497                 if (dst->data == NULL) {
6498                         DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", 
6499                                 dst->count));
6500                         return False;
6501                 }
6502                 
6503                 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
6504         }
6505         
6506         return True;
6507 }
6508 #endif  /* JERRY */
6509
6510 /*******************************************************************
6511  * init a structure.
6512  ********************************************************************/
6513
6514 BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
6515                                 uint32 change_low, uint32 change_high,
6516                                 SPOOL_NOTIFY_INFO *info)
6517 {      
6518         if (q_u == NULL)
6519                 return False;
6520
6521         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6522
6523         q_u->change_low=change_low;
6524         q_u->change_high=change_high;
6525
6526         q_u->unknown0=0x0;
6527         q_u->unknown1=0x0;
6528
6529         q_u->info_ptr=0x0FF0ADDE;
6530
6531         q_u->info.version=2;
6532         
6533         if (info->count) {
6534                 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
6535                         info->count));
6536                 q_u->info.version = info->version;
6537                 q_u->info.flags   = info->flags;
6538                 q_u->info.count   = info->count;
6539                 /* pointer field - be careful! */
6540                 q_u->info.data    = info->data;
6541         }
6542         else  {
6543         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
6544         q_u->info.count=0;
6545         }
6546
6547         return True;
6548 }
6549
6550 /*******************************************************************
6551  Parse a SPOOL_Q_REPLY_RRPCN structure.
6552 ********************************************************************/  
6553
6554 BOOL spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
6555 {
6556         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
6557         depth++;
6558
6559         if(!prs_align(ps))
6560                 return False;
6561
6562         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6563                 return False;
6564
6565         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
6566                 return False;
6567
6568         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
6569                 return False;
6570
6571         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6572                 return False;
6573
6574         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6575                 return False;
6576
6577         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
6578                 return False;
6579
6580         if(q_u->info_ptr!=0)
6581                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
6582                         return False;
6583                 
6584         return True;
6585 }
6586
6587 /*******************************************************************
6588  Parse a SPOOL_R_REPLY_RRPCN structure.
6589 ********************************************************************/  
6590
6591 BOOL spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
6592 {               
6593         prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
6594         depth++;
6595
6596         if (!prs_align(ps))
6597                 return False;
6598
6599         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
6600                 return False;
6601
6602         if (!prs_werror("status", ps, depth, &r_u->status))
6603                 return False;
6604
6605         return True;            
6606 }
6607
6608 /*******************************************************************
6609  * read a structure.
6610  * called from spoolss_q_getprinterdataex (srv_spoolss.c)
6611  ********************************************************************/
6612
6613 BOOL spoolss_io_q_getprinterdataex(const char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6614 {
6615         if (q_u == NULL)
6616                 return False;
6617
6618         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
6619         depth++;
6620
6621         if (!prs_align(ps))
6622                 return False;
6623         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6624                 return False;
6625         if (!prs_align(ps))
6626                 return False;
6627         if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
6628                 return False;
6629         if (!prs_align(ps))
6630                 return False;
6631         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
6632                 return False;
6633         if (!prs_align(ps))
6634                 return False;
6635         if (!prs_uint32("size", ps, depth, &q_u->size))
6636                 return False;
6637
6638         return True;
6639 }
6640
6641 /*******************************************************************
6642  * write a structure.
6643  * called from spoolss_r_getprinterdataex (srv_spoolss.c)
6644  ********************************************************************/
6645
6646 BOOL spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6647 {
6648         if (r_u == NULL)
6649                 return False;
6650
6651         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
6652         depth++;
6653
6654         if (!prs_align(ps))
6655                 return False;
6656         if (!prs_uint32("type", ps, depth, &r_u->type))
6657                 return False;
6658         if (!prs_uint32("size", ps, depth, &r_u->size))
6659                 return False;
6660         
6661         if (UNMARSHALLING(ps) && r_u->size) {
6662                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
6663                 if(!r_u->data)
6664                         return False;
6665         }
6666
6667         if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
6668                 return False;
6669                 
6670         if (!prs_align(ps))
6671                 return False;
6672         
6673         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6674                 return False;
6675         if (!prs_werror("status", ps, depth, &r_u->status))
6676                 return False;
6677                 
6678         return True;
6679 }
6680
6681 /*******************************************************************
6682  * read a structure.
6683  ********************************************************************/  
6684
6685 BOOL spoolss_io_q_setprinterdataex(const char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6686 {
6687         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
6688         depth++;
6689
6690         if(!prs_align(ps))
6691                 return False;
6692         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6693                 return False;
6694         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6695                 return False;
6696
6697         if(!prs_align(ps))
6698                 return False;
6699
6700         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
6701                 return False;
6702
6703         if(!prs_align(ps))
6704                 return False;
6705
6706         if(!prs_uint32("type", ps, depth, &q_u->type))
6707                 return False;
6708
6709         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
6710                 return False;
6711
6712         switch (q_u->type)
6713         {
6714                 case 0x1:
6715                 case 0x3:
6716                 case 0x4:
6717                 case 0x7:
6718                         if (q_u->max_len) {
6719                                 if (UNMARSHALLING(ps))
6720                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
6721                                 if(q_u->data == NULL)
6722                                         return False;
6723                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
6724                                         return False;
6725                         }
6726                         if(!prs_align(ps))
6727                                 return False;
6728                         break;
6729         }       
6730         
6731         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
6732                 return False;
6733
6734         return True;
6735 }
6736
6737 /*******************************************************************
6738  * write a structure.
6739  ********************************************************************/  
6740
6741 BOOL spoolss_io_r_setprinterdataex(const char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6742 {
6743         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
6744         depth++;
6745
6746         if(!prs_align(ps))
6747                 return False;
6748         if(!prs_werror("status",     ps, depth, &r_u->status))
6749                 return False;
6750
6751         return True;
6752 }
6753
6754 /*******************************************************************
6755  * read a structure.
6756  ********************************************************************/  
6757 BOOL make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
6758                                    POLICY_HND *hnd, const char *key, 
6759                                    uint32 size)
6760 {
6761         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
6762
6763         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6764         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
6765         q_u->size = size;
6766
6767         return True;
6768 }
6769
6770 /*******************************************************************
6771  * read a structure.
6772  ********************************************************************/  
6773
6774 BOOL spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
6775 {
6776         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
6777         depth++;
6778
6779         if(!prs_align(ps))
6780                 return False;
6781         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6782                 return False;
6783                 
6784         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6785                 return False;
6786
6787         if(!prs_align(ps))
6788                 return False;
6789         
6790         if(!prs_uint32("size", ps, depth, &q_u->size))
6791                 return False;
6792
6793         return True;
6794 }
6795
6796 /*******************************************************************
6797  * write a structure.
6798  ********************************************************************/  
6799
6800 BOOL spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
6801 {
6802         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
6803         depth++;
6804
6805         if(!prs_align(ps))
6806                 return False;
6807
6808         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
6809                 return False;
6810         
6811         if(!prs_align(ps))
6812                 return False;
6813
6814         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
6815                 return False;
6816
6817         if(!prs_werror("status",     ps, depth, &r_u->status))
6818                 return False;
6819
6820         return True;
6821 }
6822
6823 /*******************************************************************
6824  * read a structure.
6825  ********************************************************************/  
6826
6827 BOOL make_spoolss_q_deleteprinterkey(SPOOL_Q_DELETEPRINTERKEY *q_u, 
6828                                      POLICY_HND *hnd, char *keyname)
6829 {
6830         DEBUG(5,("make_spoolss_q_deleteprinterkey\n"));
6831
6832         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6833         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
6834
6835         return True;
6836 }
6837
6838 /*******************************************************************
6839  * read a structure.
6840  ********************************************************************/  
6841
6842 BOOL spoolss_io_q_deleteprinterkey(const char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth)
6843 {
6844         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey");
6845         depth++;
6846
6847         if(!prs_align(ps))
6848                 return False;
6849         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6850                 return False;
6851                 
6852         if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth))
6853                 return False;
6854
6855         return True;
6856 }
6857
6858 /*******************************************************************
6859  * write a structure.
6860  ********************************************************************/  
6861
6862 BOOL spoolss_io_r_deleteprinterkey(const char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth)
6863 {
6864         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey");
6865         depth++;
6866
6867         if(!prs_align(ps))
6868                 return False;
6869                 
6870         if(!prs_werror("status",     ps, depth, &r_u->status))
6871                 return False;
6872
6873         return True;
6874 }
6875
6876
6877 /*******************************************************************
6878  * read a structure.
6879  ********************************************************************/  
6880
6881 BOOL spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6882 {
6883         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
6884         depth++;
6885
6886         if(!prs_align(ps))
6887                 return False;
6888         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6889                 return False;
6890                 
6891         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6892                 return False;
6893
6894         if(!prs_align(ps))
6895                 return False;
6896         
6897         if(!prs_uint32("size", ps, depth, &q_u->size))
6898                 return False;
6899
6900         return True;
6901 }
6902
6903 /*******************************************************************
6904 ********************************************************************/  
6905
6906 static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
6907                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
6908 {
6909         int     i;
6910         uint32  valuename_offset,
6911                 data_offset,
6912                 current_offset;
6913         const uint32 basic_unit = 20; /* size of static portion of enum_values */
6914         
6915         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
6916         depth++;        
6917         
6918         /* 
6919          * offset data begins at 20 bytes per structure * size_of_array.
6920          * Don't forget the uint32 at the beginning 
6921          * */
6922         
6923         current_offset = basic_unit * ctr->size_of_array;
6924         
6925         /* first loop to write basic enum_value information */
6926         
6927         if (UNMARSHALLING(ps)) {
6928                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
6929                 if (!ctr->values)
6930                         return False;
6931         }
6932
6933         for (i=0; i<ctr->size_of_array; i++) {
6934                 valuename_offset = current_offset;
6935                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
6936                         return False;
6937
6938                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
6939                         return False;
6940         
6941                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
6942                         return False;
6943         
6944                 data_offset = ctr->values[i].value_len + valuename_offset;
6945                 
6946                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
6947                         return False;
6948
6949                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
6950                         return False;
6951                         
6952                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
6953                 /* account for 2 byte alignment */
6954                 current_offset += (current_offset % 2);
6955         }
6956
6957         /* 
6958          * loop #2 for writing the dynamically size objects; pay 
6959          * attention to 2-byte alignment here....
6960          */
6961         
6962         for (i=0; i<ctr->size_of_array; i++) {
6963         
6964                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
6965                         return False;
6966                 
6967                 if ( ctr->values[i].data_len ) {
6968                         if ( UNMARSHALLING(ps) ) {
6969                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
6970                                 if (!ctr->values[i].data)
6971                                         return False;
6972                         }
6973                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
6974                                 return False;
6975                 }
6976                         
6977                 if ( !prs_align_uint16(ps) )
6978                         return False;
6979         }
6980
6981         return True;    
6982 }
6983
6984 /*******************************************************************
6985  * write a structure.
6986  ********************************************************************/  
6987
6988 BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6989 {
6990         uint32 data_offset, end_offset;
6991         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
6992         depth++;
6993
6994         if(!prs_align(ps))
6995                 return False;
6996
6997         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
6998                 return False;
6999
7000         data_offset = prs_offset(ps);
7001
7002         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
7003                 return False;
7004
7005         if(!prs_align(ps))
7006                 return False;
7007
7008         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7009                 return False;
7010
7011         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
7012                 return False;
7013
7014         if(!prs_werror("status",     ps, depth, &r_u->status))
7015                 return False;
7016
7017         r_u->ctr.size_of_array = r_u->returned;
7018
7019         end_offset = prs_offset(ps);
7020
7021         if (!prs_set_offset(ps, data_offset))
7022                 return False;
7023
7024         if (r_u->ctr.size)
7025                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
7026                         return False;
7027
7028         if (!prs_set_offset(ps, end_offset))
7029                 return False;
7030         return True;
7031 }
7032
7033 /*******************************************************************
7034  * write a structure.
7035  ********************************************************************/  
7036
7037 /* 
7038    uint32 GetPrintProcessorDirectory(
7039        [in] unistr2 *name,
7040        [in] unistr2 *environment,
7041        [in] uint32 level,
7042        [in,out] RPC_BUFFER buffer,
7043        [in] uint32 offered,
7044        [out] uint32 needed,
7045        [out] uint32 returned
7046    );
7047
7048 */
7049
7050 BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered)
7051 {
7052         DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
7053
7054         init_unistr2(&q_u->name, name, UNI_STR_TERMINATE);
7055         init_unistr2(&q_u->environment, environment, UNI_STR_TERMINATE);
7056
7057         q_u->level = level;
7058
7059         q_u->buffer = buffer;
7060         q_u->offered = offered;
7061
7062         return True;
7063 }
7064
7065 BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
7066 {
7067         uint32 ptr;
7068
7069         prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
7070         depth++;
7071
7072         if(!prs_align(ps))
7073                 return False;   
7074
7075         if (!prs_uint32("ptr", ps, depth, &ptr)) 
7076                 return False;
7077
7078         if (ptr) {
7079                 if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
7080                         return False;
7081         }
7082
7083         if (!prs_align(ps))
7084                 return False;
7085
7086         if (!prs_uint32("ptr", ps, depth, &ptr))
7087                 return False;
7088
7089         if (ptr) {
7090                 if(!smb_io_unistr2("environment", &q_u->environment, True, 
7091                                    ps, depth))
7092                         return False;
7093         }
7094
7095         if (!prs_align(ps))
7096                 return False;
7097
7098         if(!prs_uint32("level",   ps, depth, &q_u->level))
7099                 return False;
7100
7101         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
7102                 return False;
7103         
7104         if(!prs_align(ps))
7105                 return False;
7106
7107         if(!prs_uint32("offered", ps, depth, &q_u->offered))
7108                 return False;
7109
7110         return True;
7111 }
7112
7113 /*******************************************************************
7114  * write a structure.
7115  ********************************************************************/  
7116
7117 BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
7118 {
7119         prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
7120         depth++;
7121
7122         if(!prs_align(ps))
7123                 return False;
7124
7125         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
7126                 return False;
7127         
7128         if(!prs_align(ps))
7129                 return False;
7130
7131         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7132                 return False;
7133                 
7134         if(!prs_werror("status",     ps, depth, &r_u->status))
7135                 return False;
7136
7137         return True;
7138 }
7139
7140 BOOL smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
7141 {
7142         prs_struct *ps=&buffer->prs;
7143
7144         prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
7145         depth++;
7146
7147         buffer->struct_start=prs_offset(ps);
7148
7149         if (!smb_io_unistr(desc, &info->name, ps, depth))
7150                 return False;
7151
7152         return True;
7153 }
7154
7155 /*******************************************************************
7156  * init a structure.
7157  ********************************************************************/
7158
7159 BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle, 
7160                             int level, FORM *form)
7161 {
7162         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7163         q_u->level = level;
7164         q_u->level2 = level;
7165         memcpy(&q_u->form, form, sizeof(FORM));
7166
7167         return True;
7168 }
7169
7170 /*******************************************************************
7171  * init a structure.
7172  ********************************************************************/
7173
7174 BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle, 
7175                             int level, const char *form_name, FORM *form)
7176 {
7177         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7178         q_u->level = level;
7179         q_u->level2 = level;
7180         memcpy(&q_u->form, form, sizeof(FORM));
7181         init_unistr2(&q_u->name, form_name, UNI_STR_TERMINATE);
7182
7183         return True;
7184 }
7185
7186 /*******************************************************************
7187  * init a structure.
7188  ********************************************************************/
7189
7190 BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, 
7191                                const char *form)
7192 {
7193         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7194         init_unistr2(&q_u->name, form, UNI_STR_TERMINATE);
7195         return True;
7196 }
7197
7198 /*******************************************************************
7199  * init a structure.
7200  ********************************************************************/
7201
7202 BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle, 
7203                             const char *formname, uint32 level, 
7204                             RPC_BUFFER *buffer, uint32 offered)
7205 {
7206         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7207         q_u->level = level;
7208         init_unistr2(&q_u->formname, formname, UNI_STR_TERMINATE);
7209         q_u->buffer=buffer;
7210         q_u->offered=offered;
7211
7212         return True;
7213 }
7214
7215 /*******************************************************************
7216  * init a structure.
7217  ********************************************************************/
7218
7219 BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
7220                               uint32 level, RPC_BUFFER *buffer,
7221                               uint32 offered)
7222 {
7223         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7224         q_u->level = level;
7225         q_u->buffer=buffer;
7226         q_u->offered=offered;
7227
7228         return True;
7229 }
7230
7231 /*******************************************************************
7232  * init a structure.
7233  ********************************************************************/
7234
7235 BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle, 
7236                            uint32 jobid, uint32 level, uint32 command)
7237 {
7238         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7239         q_u->jobid = jobid;
7240         q_u->level = level;
7241
7242         /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
7243            the server side code has it marked as unused. */
7244
7245         q_u->command = command;
7246
7247         return True;
7248 }
7249
7250 /*******************************************************************
7251  * init a structure.
7252  ********************************************************************/
7253
7254 BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
7255                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
7256                            uint32 offered)
7257 {
7258         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7259         q_u->jobid = jobid;
7260         q_u->level = level;
7261         q_u->buffer = buffer;
7262         q_u->offered = offered;
7263
7264         return True;
7265 }
7266
7267 /*******************************************************************
7268  * init a structure.
7269  ********************************************************************/
7270
7271 BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u, 
7272                                      POLICY_HND *handle)
7273 {
7274         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7275
7276         return True;
7277 }
7278
7279 /*******************************************************************
7280  * init a structure.
7281  ********************************************************************/
7282
7283 BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u, 
7284                                    POLICY_HND *handle)
7285 {
7286         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7287
7288         return True;
7289 }
7290
7291 /*******************************************************************
7292  * init a structure.
7293  ********************************************************************/
7294
7295 BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u, 
7296                                     POLICY_HND *handle, uint32 level,
7297                                     char *docname, char *outputfile,
7298                                     char *datatype)
7299 {
7300         DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container;
7301
7302         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7303
7304         ctr->level = level;
7305
7306         switch (level) {
7307         case 1:
7308                 ctr->docinfo.switch_value = level;
7309
7310                 ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0;
7311                 ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0;
7312                 ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0;
7313
7314                 init_unistr2(&ctr->docinfo.doc_info_1.docname, docname, UNI_STR_TERMINATE);
7315                 init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile, UNI_STR_TERMINATE);
7316                 init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype, UNI_STR_TERMINATE);
7317
7318                 break;
7319         case 2:
7320                 /* DOC_INFO_2 is only used by Windows 9x and since it
7321                    doesn't do printing over RPC we don't have to worry
7322                    about it. */
7323         default:
7324                 DEBUG(3, ("unsupported info level %d\n", level));
7325                 return False;
7326         }
7327
7328         return True;
7329 }
7330
7331 /*******************************************************************
7332  * init a structure.
7333  ********************************************************************/
7334
7335 BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u, 
7336                                   POLICY_HND *handle)
7337 {
7338         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7339
7340         return True;
7341 }
7342
7343 /*******************************************************************
7344  * init a structure.
7345  ********************************************************************/
7346
7347 BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u, 
7348                                  POLICY_HND *handle, uint32 data_size,
7349                                  char *data)
7350 {
7351         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7352         q_u->buffer_size = q_u->buffer_size2 = data_size;
7353         q_u->buffer = (unsigned char *)data;
7354         return True;
7355 }
7356
7357 /*******************************************************************
7358  * init a structure.
7359  ********************************************************************/
7360
7361 BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u, 
7362                                  POLICY_HND *handle, char *valuename)
7363 {
7364         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7365         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
7366
7367         return True;
7368 }
7369
7370 /*******************************************************************
7371  * init a structure.
7372  ********************************************************************/
7373
7374 BOOL make_spoolss_q_deleteprinterdataex(SPOOL_Q_DELETEPRINTERDATAEX *q_u, 
7375                                         POLICY_HND *handle, char *key,
7376                                         char *value)
7377 {
7378         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7379         init_unistr2(&q_u->valuename, value, UNI_STR_TERMINATE);
7380         init_unistr2(&q_u->keyname, key, UNI_STR_TERMINATE);
7381
7382         return True;
7383 }
7384
7385 /*******************************************************************
7386  * init a structure.
7387  ********************************************************************/
7388
7389 BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
7390                              uint32 flags, uint32 options, const char *localmachine,
7391                              uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
7392 {
7393         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7394
7395         q_u->flags = flags;
7396         q_u->options = options;
7397
7398         q_u->localmachine_ptr = 1;
7399
7400         init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
7401
7402         q_u->printerlocal = printerlocal;
7403
7404         if (option)
7405                 q_u->option_ptr = 1;
7406
7407         q_u->option = option;
7408
7409         return True;
7410 }
7411
7412
7413 /*******************************************************************
7414  ********************************************************************/  
7415
7416 BOOL spoolss_io_q_xcvdataport(const char *desc, SPOOL_Q_XCVDATAPORT *q_u, prs_struct *ps, int depth)
7417 {
7418         prs_debug(ps, depth, desc, "spoolss_io_q_xcvdataport");
7419         depth++;
7420
7421         if(!prs_align(ps))
7422                 return False;   
7423
7424         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
7425                 return False;
7426                 
7427         if(!smb_io_unistr2("", &q_u->dataname, True, ps, depth))
7428                 return False;
7429
7430         if (!prs_align(ps))
7431                 return False;
7432
7433         if(!prs_rpcbuffer("", ps, depth, &q_u->indata))
7434                 return False;
7435                 
7436         if (!prs_align(ps))
7437                 return False;
7438
7439         if (!prs_uint32("indata_len", ps, depth, &q_u->indata_len))
7440                 return False;
7441         if (!prs_uint32("offered", ps, depth, &q_u->offered))
7442                 return False;
7443         if (!prs_uint32("unknown", ps, depth, &q_u->unknown))
7444                 return False;
7445         
7446         return True;
7447 }
7448
7449 /*******************************************************************
7450  ********************************************************************/  
7451
7452 BOOL spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_struct *ps, int depth)
7453 {
7454         prs_debug(ps, depth, desc, "spoolss_io_r_xcvdataport");
7455         depth++;
7456
7457         if(!prs_align(ps))
7458                 return False;
7459         if(!prs_rpcbuffer("", ps, depth, &r_u->outdata))
7460                 return False;
7461                 
7462         if (!prs_align(ps))
7463                 return False;
7464
7465         if (!prs_uint32("needed", ps, depth, &r_u->needed))
7466                 return False;
7467         if (!prs_uint32("unknown", ps, depth, &r_u->unknown))
7468                 return False;
7469
7470         if(!prs_werror("status", ps, depth, &r_u->status))
7471                 return False;
7472
7473         return True;
7474 }
7475
7476 /*******************************************************************
7477  ********************************************************************/  
7478
7479 BOOL make_monitorui_buf( RPC_BUFFER *buf, const char *dllname )
7480 {
7481         UNISTR string;
7482         
7483         if ( !buf )
7484                 return False;
7485
7486         init_unistr( &string, dllname );
7487
7488         if ( !prs_unistr( "ui_dll", &buf->prs, 0, &string ) )
7489                 return False;
7490
7491         return True;
7492 }
7493
7494 /*******************************************************************
7495  ********************************************************************/  
7496  
7497 #define PORT_DATA_1_PAD    540
7498
7499 static BOOL smb_io_port_data_1( const char *desc, RPC_BUFFER *buf, int depth, SPOOL_PORT_DATA_1 *p1 )
7500 {
7501         prs_struct *ps = &buf->prs;
7502         uint8 padding[PORT_DATA_1_PAD];
7503
7504         prs_debug(ps, depth, desc, "smb_io_port_data_1");
7505         depth++;
7506
7507         if(!prs_align(ps))
7508                 return False;   
7509
7510         if( !prs_uint16s(True, "portname", ps, depth, p1->portname, MAX_PORTNAME))
7511                 return False;
7512
7513         if (!prs_uint32("version", ps, depth, &p1->version))
7514                 return False;
7515         if (!prs_uint32("protocol", ps, depth, &p1->protocol))
7516                 return False;
7517         if (!prs_uint32("size", ps, depth, &p1->size))
7518                 return False;
7519         if (!prs_uint32("reserved", ps, depth, &p1->reserved))
7520                 return False;
7521
7522         if( !prs_uint16s(True, "hostaddress", ps, depth, p1->hostaddress, MAX_NETWORK_NAME))
7523                 return False;
7524         if( !prs_uint16s(True, "snmpcommunity", ps, depth, p1->snmpcommunity, MAX_SNMP_COMM_NAME))
7525                 return False;
7526
7527         if (!prs_uint32("dblspool", ps, depth, &p1->dblspool))
7528                 return False;
7529                 
7530         if( !prs_uint16s(True, "queue", ps, depth, p1->queue, MAX_QUEUE_NAME))
7531                 return False;
7532         if( !prs_uint16s(True, "ipaddress", ps, depth, p1->ipaddress, MAX_IPADDR_STRING))
7533                 return False;
7534
7535         if( !prs_uint8s(False, "", ps, depth, padding, PORT_DATA_1_PAD))
7536                 return False;
7537                 
7538         if (!prs_uint32("port", ps, depth, &p1->port))
7539                 return False;
7540         if (!prs_uint32("snmpenabled", ps, depth, &p1->snmpenabled))
7541                 return False;
7542         if (!prs_uint32("snmpdevindex", ps, depth, &p1->snmpdevindex))
7543                 return False;
7544                 
7545         return True;
7546 }
7547
7548 /*******************************************************************
7549  ********************************************************************/  
7550
7551 BOOL convert_port_data_1( NT_PORT_DATA_1 *port1, RPC_BUFFER *buf ) 
7552 {
7553         SPOOL_PORT_DATA_1 spdata_1;
7554         
7555         ZERO_STRUCT( spdata_1 );
7556         
7557         if ( !smb_io_port_data_1( "port_data_1", buf, 0, &spdata_1 ) )
7558                 return False;
7559                 
7560         rpcstr_pull(port1->name, spdata_1.portname, sizeof(port1->name), -1, 0);
7561         rpcstr_pull(port1->queue, spdata_1.queue, sizeof(port1->queue), -1, 0);
7562         rpcstr_pull(port1->hostaddr, spdata_1.hostaddress, sizeof(port1->hostaddr), -1, 0);
7563         
7564         port1->port = spdata_1.port;
7565         
7566         switch ( spdata_1.protocol ) {
7567         case 1:
7568                 port1->protocol = PORT_PROTOCOL_DIRECT;
7569                 break;
7570         case 2:
7571                 port1->protocol = PORT_PROTOCOL_LPR;
7572                 break;
7573         default:
7574                 DEBUG(3,("convert_port_data_1: unknown protocol [%d]!\n", 
7575                         spdata_1.protocol));
7576                 return False;
7577         }
7578
7579         return True;
7580 }
7581