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