38141515dc1fa8aa73884c8c26c077fe62cac34b
[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 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_PARSE
29
30
31 /*******************************************************************
32 This should be moved in a more generic lib.
33 ********************************************************************/  
34
35 BOOL spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
36 {
37         if(!prs_uint16("year", ps, depth, &systime->year))
38                 return False;
39         if(!prs_uint16("month", ps, depth, &systime->month))
40                 return False;
41         if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
42                 return False;
43         if(!prs_uint16("day", ps, depth, &systime->day))
44                 return False;
45         if(!prs_uint16("hour", ps, depth, &systime->hour))
46                 return False;
47         if(!prs_uint16("minute", ps, depth, &systime->minute))
48                 return False;
49         if(!prs_uint16("second", ps, depth, &systime->second))
50                 return False;
51         if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
52                 return False;
53
54         return True;
55 }
56
57 /*******************************************************************
58 ********************************************************************/  
59
60 BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
61 {
62         systime->year=unixtime->tm_year+1900;
63         systime->month=unixtime->tm_mon+1;
64         systime->dayofweek=unixtime->tm_wday;
65         systime->day=unixtime->tm_mday;
66         systime->hour=unixtime->tm_hour;
67         systime->minute=unixtime->tm_min;
68         systime->second=unixtime->tm_sec;
69         systime->milliseconds=0;
70
71         return True;
72 }
73
74 /*******************************************************************
75 reads or writes an DOC_INFO structure.
76 ********************************************************************/  
77
78 static BOOL smb_io_doc_info_1(const char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
79 {
80         if (info_1 == NULL) return False;
81
82         prs_debug(ps, depth, desc, "smb_io_doc_info_1");
83         depth++;
84  
85         if(!prs_align(ps))
86                 return False;
87         
88         if(!prs_uint32("p_docname",    ps, depth, &info_1->p_docname))
89                 return False;
90         if(!prs_uint32("p_outputfile", ps, depth, &info_1->p_outputfile))
91                 return False;
92         if(!prs_uint32("p_datatype",   ps, depth, &info_1->p_datatype))
93                 return False;
94
95         if(!smb_io_unistr2("", &info_1->docname,    info_1->p_docname,    ps, depth))
96                 return False;
97         if(!smb_io_unistr2("", &info_1->outputfile, info_1->p_outputfile, ps, depth))
98                 return False;
99         if(!smb_io_unistr2("", &info_1->datatype,   info_1->p_datatype,   ps, depth))
100                 return False;
101
102         return True;
103 }
104
105 /*******************************************************************
106 reads or writes an DOC_INFO structure.
107 ********************************************************************/  
108
109 static BOOL smb_io_doc_info(const char *desc, DOC_INFO *info, prs_struct *ps, int depth)
110 {
111         uint32 useless_ptr=0;
112         
113         if (info == NULL) return False;
114
115         prs_debug(ps, depth, desc, "smb_io_doc_info");
116         depth++;
117  
118         if(!prs_align(ps))
119                 return False;
120         
121         if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
122                 return False;
123         
124         if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
125                 return False;
126
127         switch (info->switch_value)
128         {
129                 case 1: 
130                         if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
131                                 return False;
132                         break;
133                 case 2:
134                         /*
135                           this is just a placeholder
136                           
137                           MSDN July 1998 says doc_info_2 is only on
138                           Windows 95, and as Win95 doesn't do RPC to print
139                           this case is nearly impossible
140                           
141                           Maybe one day with Windows for dishwasher 2037 ...
142                           
143                         */
144                         /* smb_io_doc_info_2("",&info->doc_info_2, ps, depth); */
145                         break;
146                 default:
147                         DEBUG(0,("Something is obviously wrong somewhere !\n"));
148                         break;
149         }
150
151         return True;
152 }
153
154 /*******************************************************************
155 reads or writes an DOC_INFO_CONTAINER structure.
156 ********************************************************************/  
157
158 static BOOL smb_io_doc_info_container(const char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
159 {
160         if (cont == NULL) return False;
161
162         prs_debug(ps, depth, desc, "smb_io_doc_info_container");
163         depth++;
164  
165         if(!prs_align(ps))
166                 return False;
167         
168         if(!prs_uint32("level", ps, depth, &cont->level))
169                 return False;
170         
171         if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
172                 return False;
173
174         return True;
175 }
176
177 /*******************************************************************
178 reads or writes an NOTIFY OPTION TYPE structure.
179 ********************************************************************/  
180
181 /* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
182    structure.  The _TYPE structure is really the deferred referrants (i.e
183    the notify fields array) of the _TYPE structure. -tpot */
184
185 static BOOL smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
186 {
187         prs_debug(ps, depth, desc, "smb_io_notify_option_type");
188         depth++;
189  
190         if (!prs_align(ps))
191                 return False;
192
193         if(!prs_uint16("type", ps, depth, &type->type))
194                 return False;
195         if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
196                 return False;
197         if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
198                 return False;
199         if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
200                 return False;
201         if(!prs_uint32("count", ps, depth, &type->count))
202                 return False;
203         if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
204                 return False;
205
206         return True;
207 }
208
209 /*******************************************************************
210 reads or writes an NOTIFY OPTION TYPE DATA.
211 ********************************************************************/  
212
213 static BOOL smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
214 {
215         int i;
216
217         prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
218         depth++;
219  
220         /* if there are no fields just return */
221         if (type->fields_ptr==0)
222                 return True;
223
224         if(!prs_align(ps))
225                 return False;
226
227         if(!prs_uint32("count2", ps, depth, &type->count2))
228                 return False;
229         
230         if (type->count2 != type->count)
231                 DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
232
233         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->ptr = (secdesc != NULL) ? 1: 0;
3846                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3847                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3848                 q_u->secdesc_ctr->sec = secdesc;
3849
3850                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
3851                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
3852                 q_u->devmode_ctr.devmode = devmode;
3853 #else
3854                 q_u->secdesc_ctr = NULL;
3855         
3856                 q_u->devmode_ctr.devmode_ptr = 0;
3857                 q_u->devmode_ctr.size = 0;
3858                 q_u->devmode_ctr.devmode = NULL;
3859 #endif
3860                 break;
3861         case 3:
3862                 secdesc = info->printers_3->secdesc;
3863                 
3864                 make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
3865                 
3866                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3867                 if (!q_u->secdesc_ctr)
3868                         return False;
3869                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3870                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3871                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3872                 q_u->secdesc_ctr->sec = secdesc;
3873
3874                 break;
3875         case 7:
3876                 make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
3877                 break;
3878
3879         default: 
3880                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
3881                         break;
3882         }
3883
3884         
3885         q_u->command = command;
3886
3887         return True;
3888 }
3889
3890
3891 /*******************************************************************
3892 ********************************************************************/  
3893
3894 BOOL spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
3895 {               
3896         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
3897         depth++;
3898
3899         if(!prs_align(ps))
3900                 return False;
3901         
3902         if(!prs_werror("status", ps, depth, &r_u->status))
3903                 return False;
3904
3905         return True;
3906 }
3907
3908 /*******************************************************************
3909  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
3910 ********************************************************************/  
3911
3912 BOOL spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
3913 {
3914         uint32 ptr_sec_desc = 0;
3915
3916         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
3917         depth++;
3918
3919         if(!prs_align(ps))
3920                 return False;
3921
3922         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
3923                 return False;
3924         if(!prs_uint32("level", ps, depth, &q_u->level))
3925                 return False;
3926         
3927         /* check for supported levels and structures we know about */
3928                 
3929         switch ( q_u->level ) {
3930                 case 0:
3931                 case 2:
3932                 case 3:
3933                 case 7:
3934                         /* supported levels */
3935                         break;
3936                 default:
3937                         DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
3938                                 q_u->level));
3939                         return True;
3940         }
3941                         
3942
3943         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3944                 return False;
3945
3946         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3947                 return False;
3948         
3949         if(!prs_align(ps))
3950                 return False;
3951
3952         switch (q_u->level)
3953         {
3954                 case 2:
3955                 {
3956                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3957                         break;
3958                 }
3959                 case 3:
3960                 {
3961                         /* FIXME ! Our parsing here is wrong I think,
3962                          * but for a level3 it makes no sense for
3963                          * ptr_sec_desc to be NULL. JRA. Based on
3964                          * a Vista sniff from Martin Zielinski <mz@seh.de>.
3965                          */
3966                         if (UNMARSHALLING(ps)) {
3967                                 ptr_sec_desc = 1;
3968                         } else {
3969                                 ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3970                         }
3971                         break;
3972                 }
3973         }
3974         if (ptr_sec_desc)
3975         {
3976                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3977                         return False;
3978         } else {
3979                 uint32 dummy = 0;
3980
3981                 /* Parse a NULL security descriptor.  This should really
3982                    happen inside the sec_io_desc_buf() function. */
3983
3984                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3985                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3986                         return False;
3987                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3988                         return False;
3989         }
3990         
3991         if(!prs_uint32("command", ps, depth, &q_u->command))
3992                 return False;
3993
3994         return True;
3995 }
3996
3997 /*******************************************************************
3998 ********************************************************************/  
3999
4000 BOOL spoolss_io_r_fcpn(const char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
4001 {               
4002         prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
4003         depth++;
4004
4005         if(!prs_align(ps))
4006                 return False;
4007         
4008         if(!prs_werror("status", ps, depth, &r_u->status))
4009                 return False;
4010
4011         return True;
4012 }
4013
4014 /*******************************************************************
4015 ********************************************************************/  
4016
4017 BOOL spoolss_io_q_fcpn(const char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
4018 {
4019
4020         prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
4021         depth++;
4022
4023         if(!prs_align(ps))
4024                 return False;
4025
4026         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4027                 return False;
4028
4029         return True;
4030 }
4031
4032
4033 /*******************************************************************
4034 ********************************************************************/  
4035
4036 BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
4037 {               
4038         prs_debug(ps, depth, desc, "");
4039         depth++;
4040
4041         if(!prs_align(ps))
4042                 return False;
4043         
4044         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4045                 return False;
4046
4047         if(!prs_align(ps))
4048                 return False;
4049         
4050         if(!prs_uint32("needed", ps, depth, &r_u->needed))
4051                 return False;
4052
4053         if(!prs_werror("status", ps, depth, &r_u->status))
4054                 return False;
4055
4056         return True;
4057 }
4058
4059 /*******************************************************************
4060 ********************************************************************/  
4061
4062 BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
4063 {
4064         prs_debug(ps, depth, desc, "");
4065         depth++;
4066
4067         if(!prs_align(ps))
4068                 return False;
4069
4070         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4071                 return False;
4072         if(!prs_uint32("level", ps, depth, &q_u->level))
4073                 return False;
4074         
4075         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4076                 return False;
4077
4078         if(!prs_align(ps))
4079                 return False;
4080         
4081         if(!prs_uint32("offered", ps, depth, &q_u->offered))
4082                 return False;
4083
4084         return True;
4085 }
4086
4087 /*******************************************************************
4088 ********************************************************************/  
4089
4090 BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
4091 {               
4092         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
4093         depth++;
4094
4095         if (!prs_align(ps))
4096                 return False;
4097                 
4098         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4099                 return False;
4100
4101         if (!prs_align(ps))
4102                 return False;
4103                 
4104         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4105                 return False;
4106                 
4107         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4108                 return False;
4109                 
4110         if (!prs_werror("status", ps, depth, &r_u->status))
4111                 return False;
4112
4113         return True;            
4114 }
4115
4116 /*******************************************************************
4117 ********************************************************************/  
4118
4119 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
4120                                 uint32 firstjob,
4121                                 uint32 numofjobs,
4122                                 uint32 level,
4123                                 RPC_BUFFER *buffer,
4124                                 uint32 offered)
4125 {
4126         if (q_u == NULL)
4127         {
4128                 return False;
4129         }
4130         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4131         q_u->firstjob = firstjob;
4132         q_u->numofjobs = numofjobs;
4133         q_u->level = level;
4134         q_u->buffer= buffer;
4135         q_u->offered = offered;
4136         return True;
4137 }
4138
4139 /*******************************************************************
4140 ********************************************************************/  
4141
4142 BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
4143 {
4144         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
4145         depth++;
4146
4147         if (!prs_align(ps))
4148                 return False;
4149
4150         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
4151                 return False;
4152                 
4153         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
4154                 return False;
4155         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
4156                 return False;
4157         if (!prs_uint32("level", ps, depth, &q_u->level))
4158                 return False;
4159
4160         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4161                 return False;   
4162
4163         if(!prs_align(ps))
4164                 return False;
4165
4166         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4167                 return False;
4168
4169         return True;
4170 }
4171
4172 /*******************************************************************
4173 ********************************************************************/  
4174
4175 BOOL spoolss_io_r_schedulejob(const char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
4176 {               
4177         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
4178         depth++;
4179
4180         if(!prs_align(ps))
4181                 return False;
4182         
4183         if(!prs_werror("status", ps, depth, &r_u->status))
4184                 return False;
4185
4186         return True;
4187 }
4188
4189 /*******************************************************************
4190 ********************************************************************/  
4191
4192 BOOL spoolss_io_q_schedulejob(const char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
4193 {
4194         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
4195         depth++;
4196
4197         if(!prs_align(ps))
4198                 return False;
4199
4200         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4201                 return False;
4202         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4203                 return False;
4204
4205         return True;
4206 }
4207
4208 /*******************************************************************
4209 ********************************************************************/  
4210
4211 BOOL spoolss_io_r_setjob(const char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
4212 {               
4213         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
4214         depth++;
4215
4216         if(!prs_align(ps))
4217                 return False;
4218         
4219         if(!prs_werror("status", ps, depth, &r_u->status))
4220                 return False;
4221
4222         return True;
4223 }
4224
4225 /*******************************************************************
4226 ********************************************************************/  
4227
4228 BOOL spoolss_io_q_setjob(const char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
4229 {
4230         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
4231         depth++;
4232
4233         if(!prs_align(ps))
4234                 return False;
4235
4236         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4237                 return False;
4238         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4239                 return False;
4240         /* 
4241          * level is usually 0. If (level!=0) then I'm in trouble !
4242          * I will try to generate setjob command with level!=0, one day.
4243          */
4244         if(!prs_uint32("level", ps, depth, &q_u->level))
4245                 return False;
4246         if(!prs_uint32("command", ps, depth, &q_u->command))
4247                 return False;
4248
4249         return True;
4250 }
4251
4252 /*******************************************************************
4253  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
4254 ********************************************************************/  
4255
4256 BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
4257 {
4258         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
4259         depth++;
4260
4261         if (!prs_align(ps))
4262                 return False;
4263                 
4264         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4265                 return False;
4266
4267         if (!prs_align(ps))
4268                 return False;
4269                 
4270         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4271                 return False;
4272                 
4273         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4274                 return False;
4275                 
4276         if (!prs_werror("status", ps, depth, &r_u->status))
4277                 return False;
4278
4279         return True;            
4280 }
4281
4282 /*******************************************************************
4283  * init a structure.
4284  ********************************************************************/
4285
4286 BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
4287                                 const char *name,
4288                                 const char *environment,
4289                                 uint32 level,
4290                                 RPC_BUFFER *buffer, uint32 offered)
4291 {
4292         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
4293         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
4294
4295         q_u->level=level;
4296         q_u->buffer=buffer;
4297         q_u->offered=offered;
4298
4299         return True;
4300 }
4301
4302 /*******************************************************************
4303  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
4304 ********************************************************************/  
4305
4306 BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
4307 {
4308
4309         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
4310         depth++;
4311
4312         if (!prs_align(ps))
4313                 return False;
4314                 
4315         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4316                 return False;
4317         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
4318                 return False;
4319                 
4320         if (!prs_align(ps))
4321                 return False;
4322         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
4323                 return False;
4324         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4325                 return False;
4326                 
4327         if (!prs_align(ps))
4328                 return False;
4329         if (!prs_uint32("level", ps, depth, &q_u->level))
4330                 return False;
4331                 
4332         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4333                 return False;
4334
4335         if (!prs_align(ps))
4336                 return False;
4337                 
4338         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4339                 return False;
4340
4341         return True;
4342 }
4343
4344 /*******************************************************************
4345 ********************************************************************/  
4346
4347 BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
4348 {
4349
4350         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
4351         depth++;
4352
4353         if (!prs_align(ps))
4354                 return False;                   
4355         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4356                 return False;           
4357         if (!prs_uint32("level", ps, depth, &q_u->level))
4358                 return False;   
4359         
4360         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4361                 return False;
4362
4363         if (!prs_align(ps))
4364                 return False;
4365         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4366                 return False;
4367
4368         return True;
4369 }
4370
4371 /*******************************************************************
4372 ********************************************************************/  
4373
4374 BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
4375 {
4376         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
4377         depth++;
4378
4379         if (!prs_align(ps))
4380                 return False;
4381                 
4382         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4383                 return False;
4384
4385         if (!prs_align(ps))
4386                 return False;
4387                 
4388         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4389                 return False;
4390                 
4391         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
4392                 return False;
4393                 
4394         if (!prs_werror("status", ps, depth, &r_u->status))
4395                 return False;
4396
4397         return True;
4398 }
4399
4400 /*******************************************************************
4401 ********************************************************************/  
4402
4403 BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
4404 {
4405
4406         prs_debug(ps, depth, desc, "spoolss_io_q_getform");
4407         depth++;
4408
4409         if (!prs_align(ps))
4410                 return False;                   
4411         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4412                 return False;           
4413         if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
4414                 return False;
4415
4416         if (!prs_align(ps))
4417                 return False;
4418
4419         if (!prs_uint32("level", ps, depth, &q_u->level))
4420                 return False;   
4421         
4422         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4423                 return False;
4424
4425         if (!prs_align(ps))
4426                 return False;
4427         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4428                 return False;
4429
4430         return True;
4431 }
4432
4433 /*******************************************************************
4434 ********************************************************************/  
4435
4436 BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
4437 {
4438         prs_debug(ps, depth, desc, "spoolss_io_r_getform");
4439         depth++;
4440
4441         if (!prs_align(ps))
4442                 return False;
4443                 
4444         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4445                 return False;
4446
4447         if (!prs_align(ps))
4448                 return False;
4449                 
4450         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4451                 return False;
4452                 
4453         if (!prs_werror("status", ps, depth, &r_u->status))
4454                 return False;
4455
4456         return True;
4457 }
4458
4459 /*******************************************************************
4460  Parse a SPOOL_R_ENUMPORTS structure.
4461 ********************************************************************/  
4462
4463 BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
4464 {
4465         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
4466         depth++;
4467
4468         if (!prs_align(ps))
4469                 return False;
4470                 
4471         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4472                 return False;
4473
4474         if (!prs_align(ps))
4475                 return False;
4476                 
4477         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4478                 return False;
4479                 
4480         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4481                 return False;
4482                 
4483         if (!prs_werror("status", ps, depth, &r_u->status))
4484                 return False;
4485
4486         return True;            
4487 }
4488
4489 /*******************************************************************
4490 ********************************************************************/  
4491
4492 BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
4493 {
4494         prs_debug(ps, depth, desc, "");
4495         depth++;
4496
4497         if (!prs_align(ps))
4498                 return False;
4499
4500         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
4501                 return False;
4502         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
4503                 return False;
4504
4505         if (!prs_align(ps))
4506                 return False;
4507         if (!prs_uint32("level", ps, depth, &q_u->level))
4508                 return False;
4509                 
4510         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4511                 return False;
4512
4513         if (!prs_align(ps))
4514                 return False;
4515         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4516                 return False;
4517
4518         return True;
4519 }
4520
4521 /*******************************************************************
4522  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
4523 ********************************************************************/  
4524
4525 BOOL spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
4526 {       
4527         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
4528         depth++;
4529                 
4530         if(!prs_align(ps))
4531                 return False;
4532
4533         if(!prs_uint32("flags", ps, depth, &il->flags))
4534                 return False;
4535         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
4536                 return False;
4537         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4538                 return False;
4539         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4540                 return False;
4541                 
4542         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
4543                 return False;
4544         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4545                 return False;
4546         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4547                 return False;
4548
4549         return True;
4550 }
4551
4552 /*******************************************************************
4553  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
4554 ********************************************************************/  
4555
4556 BOOL spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
4557 {       
4558         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
4559         depth++;
4560                 
4561         if(!prs_align(ps))
4562                 return False;
4563
4564         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4565                 return False;
4566
4567         return True;
4568 }
4569
4570 /*******************************************************************
4571  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
4572 ********************************************************************/  
4573
4574 BOOL spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
4575 {       
4576         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
4577         depth++;
4578                 
4579         if(!prs_align(ps))
4580                 return False;
4581
4582         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
4583                 return False;
4584         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
4585                 return False;
4586         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
4587                 return False;
4588         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
4589                 return False;
4590
4591         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
4592                 return False;
4593         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4594                 return False;
4595         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
4596                 return False;
4597         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
4598                 return False;
4599         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
4600                 return False;
4601         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
4602                 return False;
4603         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
4604                 return False;
4605         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
4606                 return False;
4607         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4608                 return False;
4609
4610         if(!prs_uint32("attributes", ps, depth, &il->attributes))
4611                 return False;
4612         if(!prs_uint32("priority", ps, depth, &il->priority))
4613                 return False;
4614         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
4615                 return False;
4616         if(!prs_uint32("starttime", ps, depth, &il->starttime))
4617                 return False;
4618         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
4619                 return False;
4620         if(!prs_uint32("status", ps, depth, &il->status))
4621                 return False;
4622         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
4623                 return False;
4624         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
4625                 return False;
4626
4627         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
4628                 return False;
4629         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
4630                 return False;
4631         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
4632                 return False;
4633         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
4634                 return False;
4635         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
4636                 return False;
4637         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4638                 return False;
4639         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
4640                 return False;
4641         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
4642                 return False;
4643         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
4644                 return False;
4645         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
4646                 return False;
4647         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
4648                 return False;
4649
4650         return True;
4651 }
4652
4653 BOOL spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
4654 {       
4655         prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
4656         depth++;
4657                 
4658         if(!prs_align(ps))
4659                 return False;
4660
4661         if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
4662                 return False;
4663         if(!prs_uint32("action", ps, depth, &il->action))
4664                 return False;
4665
4666         if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
4667                 return False;
4668         return True;
4669 }
4670
4671 /*******************************************************************
4672 ********************************************************************/  
4673
4674 BOOL spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
4675 {
4676         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
4677         depth++;
4678
4679         if(!prs_align(ps))
4680                 return False;
4681         if(!prs_uint32("level", ps, depth, &il->level))
4682                 return False;
4683         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
4684                 return False;
4685         
4686         /* if no struct inside just return */
4687         if (il->info_ptr==0) {
4688                 if (UNMARSHALLING(ps)) {
4689                         il->info_1=NULL;
4690                         il->info_2=NULL;
4691                 }
4692                 return True;
4693         }
4694                         
4695         switch (il->level) {
4696                 /*
4697                  * level 0 is used by setprinter when managing the queue
4698                  * (hold, stop, start a queue)
4699                  */
4700                 case 0:
4701                         break;
4702                 /* DOCUMENT ME!!! What is level 1 used for? */
4703                 case 1:
4704                 {
4705                         if (UNMARSHALLING(ps)) {
4706                                 if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
4707                                         return False;
4708                         }
4709                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
4710                                 return False;
4711                         break;          
4712                 }
4713                 /* 
4714                  * level 2 is used by addprinter
4715                  * and by setprinter when updating printer's info
4716                  */     
4717                 case 2:
4718                         if (UNMARSHALLING(ps)) {
4719                                 if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
4720                                         return False;
4721                         }
4722                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
4723                                 return False;
4724                         break;          
4725                 /* DOCUMENT ME!!! What is level 3 used for? */
4726                 case 3:
4727                 {
4728                         if (UNMARSHALLING(ps)) {
4729                                 if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
4730                                         return False;
4731                         }
4732                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
4733                                 return False;
4734                         break;          
4735                 }
4736                 case 7:
4737                         if (UNMARSHALLING(ps))
4738                                 if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
4739                                         return False;
4740                         if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
4741                                 return False;
4742                         break;
4743         }
4744
4745         return True;
4746 }
4747
4748 /*******************************************************************
4749 ********************************************************************/  
4750
4751 BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
4752 {
4753         uint32 ptr_sec_desc = 0;
4754
4755         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
4756         depth++;
4757
4758         if(!prs_align(ps))
4759                 return False;
4760
4761         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
4762                 return False;
4763         if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
4764                 return False;
4765
4766         if(!prs_align(ps))
4767                 return False;
4768
4769         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4770                 return False;
4771         
4772         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4773                 return False;
4774         
4775         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4776                 return False;
4777
4778         if(!prs_align(ps))
4779                 return False;
4780
4781         switch (q_u->level) {
4782                 case 2:
4783                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4784                         break;
4785                 case 3:
4786                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4787                         break;
4788         }
4789         if (ptr_sec_desc) {
4790                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
4791                         return False;
4792         } else {
4793                 uint32 dummy;
4794
4795                 /* Parse a NULL security descriptor.  This should really
4796                         happen inside the sec_io_desc_buf() function. */
4797
4798                 prs_debug(ps, depth, "", "sec_io_desc_buf");
4799                 if (!prs_uint32("size", ps, depth + 1, &dummy))
4800                         return False;
4801                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
4802                         return False;
4803         }
4804
4805         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
4806                 return False;
4807         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
4808                 return False;
4809
4810         return True;
4811 }
4812
4813 /*******************************************************************
4814 ********************************************************************/  
4815
4816 BOOL spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
4817                                prs_struct *ps, int depth)
4818 {
4819         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
4820         depth++;
4821         
4822         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
4823                 return False;
4824
4825         if(!prs_werror("status", ps, depth, &r_u->status))
4826                 return False;
4827
4828         return True;
4829 }
4830
4831 /*******************************************************************
4832 ********************************************************************/  
4833
4834 BOOL spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
4835                                           prs_struct *ps, int depth)
4836 {       
4837         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
4838         
4839         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
4840         depth++;
4841                 
4842         /* reading */
4843         if (UNMARSHALLING(ps)) {
4844                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
4845                 if(il == NULL)
4846                         return False;
4847                 *q_u=il;
4848         }
4849         else {
4850                 il=*q_u;
4851         }
4852         
4853         if(!prs_align(ps))
4854                 return False;
4855
4856         if(!prs_uint32("cversion", ps, depth, &il->cversion))
4857                 return False;
4858         if(!prs_uint32("name", ps, depth, &il->name_ptr))
4859                 return False;
4860         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
4861                 return False;
4862         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
4863                 return False;
4864         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
4865                 return False;
4866         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
4867                 return False;
4868         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
4869                 return False;
4870         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
4871                 return False;
4872         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4873                 return False;
4874         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
4875                 return False;
4876         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
4877                 return False;
4878
4879         if(!prs_align(ps))
4880                 return False;
4881         
4882         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4883                 return False;
4884         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4885                 return False;
4886         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4887                 return False;
4888         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4889                 return False;
4890         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4891                 return False;
4892         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4893                 return False;
4894         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4895                 return False;
4896         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4897                 return False;
4898
4899         if(!prs_align(ps))
4900                 return False;
4901                 
4902         if (il->dependentfiles_ptr)
4903                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
4904
4905         return True;
4906 }
4907
4908 /*******************************************************************
4909 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
4910 ********************************************************************/  
4911
4912 BOOL spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
4913                                           prs_struct *ps, int depth)
4914 {       
4915         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
4916         
4917         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
4918         depth++;
4919                 
4920         /* reading */
4921         if (UNMARSHALLING(ps)) {
4922                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
4923                 if(il == NULL)
4924                         return False;
4925                 *q_u=il;
4926         }
4927         else {
4928                 il=*q_u;
4929         }
4930         
4931         if(!prs_align(ps))
4932                 return False;
4933
4934         /* 
4935          * I know this seems weird, but I have no other explanation.
4936          * This is observed behavior on both NT4 and 2K servers.
4937          * --jerry
4938          */
4939          
4940         if (!prs_align_uint64(ps))
4941                 return False;
4942
4943         /* parse the main elements the packet */
4944
4945         if(!prs_uint32("cversion       ", ps, depth, &il->version))
4946                 return False;
4947         if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
4948                 return False;
4949         if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
4950                 return False;
4951         if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
4952                 return False;
4953         if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
4954                 return False;
4955         if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
4956                 return False;
4957         if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
4958                 return False;
4959         if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
4960                 return False;
4961         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4962                 return False;
4963         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
4964                 return False;
4965         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
4966                 return False;
4967         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
4968                 return False;
4969         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
4970                 return False;
4971         if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
4972                 return False;
4973         if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
4974                 return False;
4975         if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
4976                 return False;
4977         if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
4978                 return False;
4979         if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
4980                 return False;
4981         if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
4982                 return False;
4983         if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
4984                 return False;
4985
4986         /* parse the structures in the packet */
4987
4988         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4989                 return False;
4990         if(!prs_align(ps))
4991                 return False;
4992
4993         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4994                 return False;
4995         if(!prs_align(ps))
4996                 return False;
4997
4998         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4999                 return False;
5000         if(!prs_align(ps))
5001                 return False;
5002
5003         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
5004                 return False;
5005         if(!prs_align(ps))
5006                 return False;
5007
5008         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
5009                 return False;
5010         if(!prs_align(ps))
5011                 return False;
5012
5013         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
5014                 return False;
5015         if(!prs_align(ps))
5016                 return False;
5017
5018         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
5019                 return False;
5020         if(!prs_align(ps))
5021                 return False;
5022
5023         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
5024                 return False;
5025         if(!prs_align(ps))
5026                 return False;
5027         if (il->dependentfiles_ptr) {
5028                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
5029                         return False;
5030                 if(!prs_align(ps))
5031                         return False;
5032         }
5033         if (il->previousnames_ptr) {
5034                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
5035                         return False;
5036                 if(!prs_align(ps))
5037                         return False;
5038         }
5039         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
5040                 return False;
5041         if(!prs_align(ps))
5042                 return False;
5043         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
5044                 return False;
5045         if(!prs_align(ps))
5046                 return False;
5047         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
5048                 return False;
5049         if(!prs_align(ps))
5050                 return False;
5051         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
5052                 return False;
5053
5054         return True;
5055 }
5056
5057 /*******************************************************************
5058  convert a buffer of UNICODE strings null terminated
5059  the buffer is terminated by a NULL
5060  
5061  convert to an dos codepage array (null terminated)
5062  
5063  dynamically allocate memory
5064  
5065 ********************************************************************/  
5066
5067 static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
5068 {
5069         fstring f;
5070         int n = 0;
5071         char *src;
5072
5073         if (buf5==NULL)
5074                 return False;
5075
5076         src = (char *)buf5->buffer;
5077         *ar = SMB_MALLOC_ARRAY(fstring, 1);
5078         if (!*ar) {
5079                 return False;
5080         }
5081
5082         while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
5083                 rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
5084                 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
5085                 *ar = SMB_REALLOC_ARRAY(*ar, fstring, n+2);
5086                 if (!*ar) {
5087                         return False;
5088                 }
5089                 fstrcpy((*ar)[n], f);
5090                 n++;
5091         }
5092
5093         fstrcpy((*ar)[n], "");
5094  
5095         return True;
5096 }
5097
5098 /*******************************************************************
5099  read a UNICODE array with null terminated strings 
5100  and null terminated array 
5101  and size of array at beginning
5102 ********************************************************************/  
5103
5104 BOOL smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
5105 {
5106         if (buffer==NULL) return False;
5107
5108         buffer->offset=0;
5109         buffer->uni_str_len=buffer->uni_max_len;
5110         
5111         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
5112                 return False;
5113
5114         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
5115                 return False;
5116
5117         return True;
5118 }
5119
5120 /*******************************************************************
5121 ********************************************************************/  
5122
5123 BOOL spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
5124 {
5125         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
5126         depth++;
5127
5128         if(!prs_align(ps))
5129                 return False;
5130         if(!prs_uint32("level", ps, depth, &il->level))
5131                 return False;
5132         if(!prs_uint32("ptr", ps, depth, &il->ptr))
5133                 return False;
5134
5135         if (il->ptr==0)
5136                 return True;
5137                 
5138         switch (il->level) {
5139                 case 3:
5140                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
5141                                 return False;
5142                         break;          
5143                 case 6:
5144                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
5145                                 return False;
5146                         break;          
5147         default:
5148                 return False;
5149         }
5150
5151         return True;
5152 }
5153
5154 /*******************************************************************
5155  init a SPOOL_Q_ADDPRINTERDRIVER struct
5156  ******************************************************************/
5157
5158 BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
5159                                 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
5160                                 uint32 level, PRINTER_DRIVER_CTR *info)
5161 {
5162         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
5163         
5164         if (!srv_name || !info) {
5165                 return False;
5166         }
5167
5168         q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */
5169         init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
5170         
5171         q_u->level = level;
5172         
5173         q_u->info.level = level;
5174         q_u->info.ptr = 1;      /* Info is != NULL, see above */
5175         switch (level)
5176         {
5177         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
5178         case 3 :
5179                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
5180                 break;
5181                 
5182         default:
5183                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
5184                 break;
5185         }
5186         
5187         return True;
5188 }
5189
5190 BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, 
5191         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
5192                                 DRIVER_INFO_3 *info3)
5193 {
5194         uint32          len = 0;
5195         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
5196
5197         if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
5198                 return False;
5199         
5200         inf->cversion   = info3->version;
5201         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
5202         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
5203         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
5204         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
5205         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
5206         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
5207         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
5208         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
5209
5210         init_unistr2_from_unistr(&inf->name, &info3->name);
5211         init_unistr2_from_unistr(&inf->environment, &info3->architecture);
5212         init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
5213         init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
5214         init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
5215         init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
5216         init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
5217         init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
5218
5219         if (info3->dependentfiles) {
5220                 BOOL done = False;
5221                 BOOL null_char = False;
5222                 uint16 *ptr = info3->dependentfiles;
5223
5224                 while (!done) {
5225                         switch (*ptr) {
5226                                 case 0:
5227                                         /* the null_char BOOL is used to help locate
5228                                            two '\0's back to back */
5229                                         if (null_char) {
5230                                                 done = True;
5231                                         } else {
5232                                                 null_char = True;
5233                                         }
5234                                         break;
5235                                         
5236                                 default:
5237                                         null_char = False;
5238                                         break;                          
5239                         }
5240                         len++;
5241                         ptr++;
5242                 }
5243         }
5244
5245         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
5246         inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0;
5247         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) {
5248                 SAFE_FREE(inf);
5249                 return False;
5250         }
5251         
5252         *spool_drv_info = inf;
5253         
5254         return True;
5255 }
5256
5257 /*******************************************************************
5258  make a BUFFER5 struct from a uint16*
5259  ******************************************************************/
5260
5261 BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
5262 {
5263
5264         buf5->buf_len = len;
5265         if (src) {
5266                 if (len) {
5267                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
5268                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
5269                                 return False;
5270                         }
5271                 } else {
5272                         buf5->buffer = NULL;
5273                 }
5274         } else {
5275                 buf5->buffer=NULL;
5276         }
5277         
5278         return True;
5279 }
5280
5281 /*******************************************************************
5282  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5283  ********************************************************************/  
5284
5285 BOOL spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5286 {
5287         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
5288         depth++;
5289
5290         if(!prs_align(ps))
5291                 return False;
5292
5293         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5294                 return False;
5295         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5296                 return False;
5297                 
5298         if(!prs_align(ps))
5299                 return False;
5300         if(!prs_uint32("info_level", ps, depth, &q_u->level))
5301                 return False;
5302
5303         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5304                 return False;
5305
5306         return True;
5307 }
5308
5309 /*******************************************************************
5310 ********************************************************************/  
5311
5312 BOOL spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5313 {
5314         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
5315         depth++;
5316
5317         if(!prs_werror("status", ps, depth, &q_u->status))
5318                 return False;
5319
5320         return True;
5321 }
5322
5323 /*******************************************************************
5324  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5325  ********************************************************************/  
5326
5327 BOOL spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5328 {
5329         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
5330         depth++;
5331
5332         if(!prs_align(ps))
5333                 return False;
5334
5335         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5336                 return False;
5337         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5338                 return False;
5339                 
5340         if(!prs_align(ps))
5341                 return False;
5342         if(!prs_uint32("info_level", ps, depth, &q_u->level))
5343                 return False;
5344
5345         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5346                 return False;
5347
5348         if(!prs_align(ps))
5349                 return False;
5350         if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
5351                 return False;
5352                 
5353         return True;
5354 }
5355
5356 /*******************************************************************
5357 ********************************************************************/  
5358
5359 BOOL spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5360 {
5361         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
5362         depth++;
5363
5364         if(!prs_werror("status", ps, depth, &q_u->status))
5365                 return False;
5366
5367         return True;
5368 }
5369
5370 /*******************************************************************
5371 ********************************************************************/  
5372
5373 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
5374                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
5375 {
5376         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
5377         
5378         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
5379         
5380         if (*asc==NULL)
5381         {
5382                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
5383                 if(*asc == NULL)
5384                         return False;
5385                 ZERO_STRUCTP(*asc);
5386         }       
5387
5388         d=*asc;
5389
5390         d->cversion=uni->cversion;
5391
5392         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5393         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5394         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5395         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5396         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5397         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5398         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5399         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5400
5401         DEBUGADD(8,( "version:         %d\n", d->cversion));
5402         DEBUGADD(8,( "name:            %s\n", d->name));
5403         DEBUGADD(8,( "environment:     %s\n", d->environment));
5404         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5405         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5406         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5407         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5408         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5409         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5410
5411         if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5412                 return True;
5413         
5414         SAFE_FREE(*asc);
5415         return False;
5416 }
5417
5418 /*******************************************************************
5419 ********************************************************************/  
5420 BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
5421                                 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
5422 {
5423         NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
5424         
5425         DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
5426         
5427         if (*asc==NULL)
5428         {
5429                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
5430                 if(*asc == NULL)
5431                         return False;
5432                 ZERO_STRUCTP(*asc);
5433         }       
5434
5435         d=*asc;
5436
5437         d->version=uni->version;
5438
5439         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5440         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5441         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5442         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5443         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5444         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5445         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5446         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5447
5448         DEBUGADD(8,( "version:         %d\n", d->version));
5449         DEBUGADD(8,( "name:            %s\n", d->name));
5450         DEBUGADD(8,( "environment:     %s\n", d->environment));
5451         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5452         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5453         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5454         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5455         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5456         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5457
5458         if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5459                 goto error;
5460         if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
5461                 goto error;
5462         
5463         return True;
5464         
5465 error:
5466         SAFE_FREE(*asc);
5467         return False;
5468 }
5469
5470 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
5471                               NT_PRINTER_INFO_LEVEL_2  *d)
5472 {
5473         DEBUG(7,("Converting from UNICODE to ASCII\n"));
5474         
5475         d->attributes=uni->attributes;
5476         d->priority=uni->priority;
5477         d->default_priority=uni->default_priority;
5478         d->starttime=uni->starttime;
5479         d->untiltime=uni->untiltime;
5480         d->status=uni->status;
5481         d->cjobs=uni->cjobs;
5482         
5483         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
5484         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
5485         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
5486         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
5487         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
5488         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
5489         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
5490         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
5491         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
5492         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
5493         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
5494
5495         return True;
5496 }
5497
5498 /*******************************************************************
5499  * init a structure.
5500  ********************************************************************/
5501
5502 BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
5503                                 fstring servername, fstring env_name, uint32 level,
5504                                 RPC_BUFFER *buffer, uint32 offered)
5505 {
5506         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
5507         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
5508
5509         q_u->level=level;
5510         q_u->buffer=buffer;
5511         q_u->offered=offered;
5512
5513         return True;
5514 }
5515
5516 /*******************************************************************
5517  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
5518 ********************************************************************/  
5519
5520 BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
5521 {
5522         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
5523         depth++;
5524
5525         if(!prs_align(ps))
5526                 return False;
5527         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5528                 return False;
5529         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
5530                 return False;
5531
5532         if(!prs_align(ps))
5533                 return False;
5534                 
5535         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
5536                 return False;
5537         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5538                 return False;
5539                 
5540         if(!prs_align(ps))
5541                 return False;
5542
5543         if(!prs_uint32("level", ps, depth, &q_u->level))
5544                 return False;
5545                 
5546         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5547                 return False;
5548                 
5549         if(!prs_align(ps))
5550                 return False;
5551                 
5552         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5553                 return False;
5554
5555         return True;
5556 }
5557
5558 /*******************************************************************
5559  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
5560 ********************************************************************/  
5561
5562 BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
5563 {               
5564         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
5565         depth++;
5566
5567         if (!prs_align(ps))
5568                 return False;
5569                 
5570         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5571                 return False;
5572
5573         if (!prs_align(ps))
5574                 return False;
5575                 
5576         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5577                 return False;
5578                 
5579         if (!prs_werror("status", ps, depth, &r_u->status))
5580                 return False;
5581
5582         return True;            
5583 }
5584
5585 /*******************************************************************
5586 ********************************************************************/  
5587
5588 BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
5589 {               
5590         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
5591         depth++;
5592
5593         if (!prs_align(ps))
5594                 return False;
5595                 
5596         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5597                 return False;
5598
5599         if (!prs_align(ps))
5600                 return False;
5601                 
5602         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5603                 return False;
5604                 
5605         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5606                 return False;
5607                 
5608         if (!prs_werror("status", ps, depth, &r_u->status))
5609                 return False;
5610
5611         return True;            
5612 }
5613
5614 /*******************************************************************
5615 ********************************************************************/  
5616
5617 BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
5618 {
5619         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
5620         depth++;
5621
5622         if (!prs_align(ps))
5623                 return False;
5624                 
5625         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5626                 return False;
5627         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5628                 return False;
5629                 
5630         if (!prs_align(ps))
5631                 return False;
5632                 
5633         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
5634                 return False;
5635         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5636                 return False;
5637         
5638         if (!prs_align(ps))
5639                 return False;
5640                 
5641         if (!prs_uint32("level", ps, depth, &q_u->level))
5642                 return False;
5643                 
5644         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5645                 return False;
5646
5647         if (!prs_align(ps))
5648                 return False;
5649
5650         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5651                 return False;
5652
5653         return True;
5654 }
5655
5656 /*******************************************************************
5657 ********************************************************************/  
5658
5659 BOOL spoolss_io_q_addprintprocessor(const char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
5660 {
5661         prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
5662         depth++;
5663
5664         if (!prs_align(ps))
5665                 return False;
5666                 
5667         if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
5668                 return False;
5669         if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
5670                 return False;
5671                 
5672         if (!prs_align(ps))
5673                 return False;
5674         if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
5675                 return False;
5676                 
5677         if (!prs_align(ps))
5678                 return False;
5679         if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
5680                 return False;
5681
5682         if (!prs_align(ps))
5683                 return False;
5684         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5685                 return False;
5686
5687         return True;
5688 }
5689
5690 /*******************************************************************
5691 ********************************************************************/  
5692
5693 BOOL spoolss_io_r_addprintprocessor(const char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
5694 {               
5695         prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor");
5696         depth++;
5697
5698         if (!prs_align(ps))
5699                 return False;
5700                 
5701         if (!prs_werror("status", ps, depth, &r_u->status))
5702                 return False;
5703
5704         return True;            
5705 }
5706
5707 /*******************************************************************
5708 ********************************************************************/  
5709
5710 BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
5711 {               
5712         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
5713         depth++;
5714
5715         if (!prs_align(ps))
5716                 return False;
5717                 
5718         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5719                 return False;
5720
5721         if (!prs_align(ps))
5722                 return False;
5723                 
5724         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5725                 return False;
5726                 
5727         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5728                 return False;
5729                 
5730         if (!prs_werror("status", ps, depth, &r_u->status))
5731                 return False;
5732
5733         return True;            
5734 }
5735
5736 /*******************************************************************
5737 ********************************************************************/  
5738
5739 BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
5740 {
5741         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
5742         depth++;
5743
5744         if (!prs_align(ps))
5745                 return False;
5746                 
5747         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5748                 return False;
5749         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5750                 return False;
5751                 
5752         if (!prs_align(ps))
5753                 return False;
5754                 
5755         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
5756                 return False;
5757         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
5758                 return False;
5759         
5760         if (!prs_align(ps))
5761                 return False;
5762                 
5763         if (!prs_uint32("level", ps, depth, &q_u->level))
5764                 return False;
5765                 
5766         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
5767                 return False;
5768
5769         if (!prs_align(ps))
5770                 return False;
5771
5772         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5773                 return False;
5774
5775         return True;
5776 }
5777
5778 /*******************************************************************
5779  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
5780 ********************************************************************/  
5781
5782 BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
5783 {
5784         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
5785         depth++;
5786
5787         if (!prs_align(ps))
5788                 return False;
5789                 
5790         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5791                 return False;
5792         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5793                 return False;
5794                 
5795         if (!prs_align(ps))
5796                 return False;
5797                                 
5798         if (!prs_uint32("level", ps, depth, &q_u->level))
5799                 return False;
5800                 
5801         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5802                 return False;
5803
5804         if (!prs_align(ps))
5805                 return False;
5806
5807         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5808                 return False;
5809
5810         return True;
5811 }
5812
5813 /*******************************************************************
5814 ********************************************************************/  
5815
5816 BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
5817 {               
5818         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
5819         depth++;
5820
5821         if (!prs_align(ps))
5822                 return False;
5823                 
5824         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5825                 return False;
5826
5827         if (!prs_align(ps))
5828                 return False;
5829                 
5830         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5831                 return False;
5832                 
5833         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5834                 return False;
5835                 
5836         if (!prs_werror("status", ps, depth, &r_u->status))
5837                 return False;
5838
5839         return True;            
5840 }
5841
5842 /*******************************************************************
5843 ********************************************************************/  
5844
5845 BOOL spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
5846 {       
5847         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
5848         depth++;
5849
5850         if(!prs_align(ps))
5851                 return False;
5852         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
5853                 return False;
5854
5855         if (UNMARSHALLING(ps) && r_u->valuesize) {
5856                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
5857                 if (!r_u->value) {
5858                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
5859                         return False;
5860                 }
5861         }
5862
5863         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
5864                 return False;
5865
5866         if(!prs_align(ps))
5867                 return False;
5868
5869         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
5870                 return False;
5871
5872         if(!prs_uint32("type", ps, depth, &r_u->type))
5873                 return False;
5874
5875         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
5876                 return False;
5877
5878         if (UNMARSHALLING(ps) && r_u->datasize) {
5879                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
5880                 if (!r_u->data) {
5881                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
5882                         return False;
5883                 }
5884         }
5885
5886         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
5887                 return False;
5888         if(!prs_align(ps))
5889                 return False;
5890
5891         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
5892                 return False;
5893         if(!prs_werror("status", ps, depth, &r_u->status))
5894                 return False;
5895
5896         return True;
5897 }
5898
5899 /*******************************************************************
5900 ********************************************************************/  
5901
5902 BOOL spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
5903 {
5904         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
5905         depth++;
5906
5907         if(!prs_align(ps))
5908                 return False;
5909         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5910                 return False;
5911         if(!prs_uint32("index", ps, depth, &q_u->index))
5912                 return False;
5913         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
5914                 return False;
5915         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
5916                 return False;
5917
5918         return True;
5919 }
5920
5921 /*******************************************************************
5922 ********************************************************************/  
5923
5924 BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
5925                 const POLICY_HND *hnd,
5926                 uint32 idx, uint32 valuelen, uint32 datalen)
5927 {
5928         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5929         q_u->index=idx;
5930         q_u->valuesize=valuelen;
5931         q_u->datasize=datalen;
5932
5933         return True;
5934 }
5935
5936 /*******************************************************************
5937 ********************************************************************/  
5938
5939 BOOL make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
5940                                       const POLICY_HND *hnd, const char *key,
5941                                       uint32 size)
5942 {
5943         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5944         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5945         q_u->size = size;
5946
5947         return True;
5948 }
5949
5950 /*******************************************************************
5951 ********************************************************************/  
5952 BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
5953                                    char* value, uint32 data_type, char* data, uint32 data_size)
5954 {
5955         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5956         q_u->type = data_type;
5957         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
5958
5959         q_u->max_len = q_u->real_len = data_size;
5960         q_u->data = (unsigned char *)data;
5961         
5962         return True;
5963 }
5964
5965 /*******************************************************************
5966 ********************************************************************/  
5967 BOOL make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY_HND *hnd,
5968                                      char *key, char* value, uint32 data_type, char* data, 
5969                                      uint32 data_size)
5970 {
5971         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5972         q_u->type = data_type;
5973         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
5974         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5975
5976         q_u->max_len = q_u->real_len = data_size;
5977         q_u->data = (unsigned char *)data;
5978         
5979         return True;
5980 }
5981
5982 /*******************************************************************
5983 ********************************************************************/  
5984
5985 BOOL spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
5986 {
5987         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
5988         depth++;
5989
5990         if(!prs_align(ps))
5991                 return False;
5992         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5993                 return False;
5994         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
5995                 return False;
5996
5997         if(!prs_align(ps))
5998                 return False;
5999
6000         if(!prs_uint32("type", ps, depth, &q_u->type))
6001                 return False;
6002
6003         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
6004                 return False;
6005
6006         switch (q_u->type)
6007         {
6008                 case REG_SZ:
6009                 case REG_BINARY:
6010                 case REG_DWORD:
6011                 case REG_MULTI_SZ:
6012                         if (q_u->max_len) {
6013                                 if (UNMARSHALLING(ps))
6014                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
6015                                 if(q_u->data == NULL)
6016                                         return False;
6017                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
6018                                         return False;
6019                         }
6020                         if(!prs_align(ps))
6021                                 return False;
6022                         break;
6023         }       
6024         
6025         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
6026                 return False;
6027
6028         return True;
6029 }
6030
6031 /*******************************************************************
6032 ********************************************************************/  
6033
6034 BOOL spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
6035 {
6036         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
6037         depth++;
6038
6039         if(!prs_align(ps))
6040                 return False;
6041         if(!prs_werror("status",     ps, depth, &r_u->status))
6042                 return False;
6043
6044         return True;
6045 }
6046
6047 /*******************************************************************
6048 ********************************************************************/  
6049 BOOL spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
6050 {
6051         prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
6052         depth++;
6053
6054         if (!prs_align(ps))
6055                 return False;
6056         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6057                 return False;
6058
6059         if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
6060                 return False;
6061                 
6062         if (q_u->datatype_ptr) {
6063                 if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
6064                 return False;
6065         }
6066
6067         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
6068                 return False;
6069
6070         return True;
6071 }
6072
6073
6074 /*******************************************************************
6075 ********************************************************************/  
6076 BOOL spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
6077 {
6078         prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
6079         depth++;
6080
6081         if(!prs_align(ps))
6082                 return False;
6083         if(!prs_werror("status",     ps, depth, &r_u->status))
6084                 return False;
6085
6086         return True;
6087 }
6088
6089 /*******************************************************************
6090 ********************************************************************/  
6091
6092 static BOOL spoolss_io_addform(const char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
6093 {
6094         prs_debug(ps, depth, desc, "spoolss_io_addform");
6095         depth++;
6096         if(!prs_align(ps))
6097                 return False;
6098
6099         if (ptr!=0)
6100         {
6101                 if(!prs_uint32("flags",    ps, depth, &f->flags))
6102                         return False;
6103                 if(!prs_uint32("name_ptr", ps, depth, &f->name_ptr))
6104                         return False;
6105                 if(!prs_uint32("size_x",   ps, depth, &f->size_x))
6106                         return False;
6107                 if(!prs_uint32("size_y",   ps, depth, &f->size_y))
6108                         return False;
6109                 if(!prs_uint32("left",     ps, depth, &f->left))
6110                         return False;
6111                 if(!prs_uint32("top",      ps, depth, &f->top))
6112                         return False;
6113                 if(!prs_uint32("right",    ps, depth, &f->right))
6114                         return False;
6115                 if(!prs_uint32("bottom",   ps, depth, &f->bottom))
6116                         return False;
6117
6118                 if(!smb_io_unistr2("", &f->name, f->name_ptr, ps, depth))
6119                         return False;
6120         }
6121
6122         return True;
6123 }
6124
6125 /*******************************************************************
6126 ********************************************************************/  
6127
6128 BOOL spoolss_io_q_deleteform(const char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth)
6129 {
6130         prs_debug(ps, depth, desc, "spoolss_io_q_deleteform");
6131         depth++;
6132
6133         if(!prs_align(ps))
6134                 return False;
6135         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6136                 return False;
6137         if(!smb_io_unistr2("form name", &q_u->name, True, ps, depth))
6138                 return False;
6139
6140         return True;
6141 }
6142
6143 /*******************************************************************
6144 ********************************************************************/  
6145
6146 BOOL spoolss_io_r_deleteform(const char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth)
6147 {
6148         prs_debug(ps, depth, desc, "spoolss_io_r_deleteform");
6149         depth++;
6150
6151         if(!prs_align(ps))
6152                 return False;
6153         if(!prs_werror("status",        ps, depth, &r_u->status))
6154                 return False;
6155
6156         return True;
6157 }
6158
6159 /*******************************************************************
6160 ********************************************************************/  
6161
6162 BOOL spoolss_io_q_addform(const char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
6163 {
6164         uint32 useless_ptr=1;
6165         prs_debug(ps, depth, desc, "spoolss_io_q_addform");
6166         depth++;
6167
6168         if(!prs_align(ps))
6169                 return False;
6170         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6171                 return False;
6172         if(!prs_uint32("level",  ps, depth, &q_u->level))
6173                 return False;
6174         if(!prs_uint32("level2", ps, depth, &q_u->level2))
6175                 return False;
6176
6177         if (q_u->level==1)
6178         {
6179                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6180                         return False;
6181                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6182                         return False;
6183         }
6184
6185         return True;
6186 }
6187
6188 /*******************************************************************
6189 ********************************************************************/  
6190
6191 BOOL spoolss_io_r_addform(const char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
6192 {
6193         prs_debug(ps, depth, desc, "spoolss_io_r_addform");
6194         depth++;
6195
6196         if(!prs_align(ps))
6197                 return False;
6198         if(!prs_werror("status",        ps, depth, &r_u->status))
6199                 return False;
6200
6201         return True;
6202 }
6203
6204 /*******************************************************************
6205 ********************************************************************/  
6206
6207 BOOL spoolss_io_q_setform(const char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
6208 {
6209         uint32 useless_ptr=1;
6210         prs_debug(ps, depth, desc, "spoolss_io_q_setform");
6211         depth++;
6212
6213         if(!prs_align(ps))
6214                 return False;
6215         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6216                 return False;
6217         if(!smb_io_unistr2("", &q_u->name, True, ps, depth))
6218                 return False;
6219               
6220         if(!prs_align(ps))
6221                 return False;
6222         
6223         if(!prs_uint32("level",  ps, depth, &q_u->level))
6224                 return False;
6225         if(!prs_uint32("level2", ps, depth, &q_u->level2))
6226                 return False;
6227
6228         if (q_u->level==1)
6229         {
6230                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6231                         return False;
6232                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6233                         return False;
6234         }
6235
6236         return True;
6237 }
6238
6239 /*******************************************************************
6240 ********************************************************************/  
6241
6242 BOOL spoolss_io_r_setform(const char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
6243 {
6244         prs_debug(ps, depth, desc, "spoolss_io_r_setform");
6245         depth++;
6246
6247         if(!prs_align(ps))
6248                 return False;
6249         if(!prs_werror("status",        ps, depth, &r_u->status))
6250                 return False;
6251
6252         return True;
6253 }
6254
6255 /*******************************************************************
6256  Parse a SPOOL_R_GETJOB structure.
6257 ********************************************************************/  
6258
6259 BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
6260 {               
6261         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
6262         depth++;
6263
6264         if (!prs_align(ps))
6265                 return False;
6266                 
6267         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
6268                 return False;
6269
6270         if (!prs_align(ps))
6271                 return False;
6272                 
6273         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6274                 return False;
6275                 
6276         if (!prs_werror("status", ps, depth, &r_u->status))
6277                 return False;
6278
6279         return True;            
6280 }
6281
6282 /*******************************************************************
6283  Parse a SPOOL_Q_GETJOB structure.
6284 ********************************************************************/  
6285
6286 BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
6287 {
6288         prs_debug(ps, depth, desc, "");
6289         depth++;
6290
6291         if(!prs_align(ps))
6292                 return False;
6293
6294         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6295                 return False;
6296         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
6297                 return False;
6298         if(!prs_uint32("level", ps, depth, &q_u->level))
6299                 return False;
6300         
6301         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
6302                 return False;
6303
6304         if(!prs_align(ps))
6305                 return False;
6306         
6307         if(!prs_uint32("offered", ps, depth, &q_u->offered))
6308                 return False;
6309
6310         return True;
6311 }
6312
6313 void free_devmode(DEVICEMODE *devmode)
6314 {
6315         if (devmode!=NULL) {
6316                 SAFE_FREE(devmode->dev_private);
6317                 SAFE_FREE(devmode);
6318         }
6319 }
6320
6321 void free_printer_info_1(PRINTER_INFO_1 *printer)
6322 {
6323         SAFE_FREE(printer);
6324 }
6325
6326 void free_printer_info_2(PRINTER_INFO_2 *printer)
6327 {
6328         if (printer!=NULL) {
6329                 free_devmode(printer->devmode);
6330                 printer->devmode = NULL;
6331                 SAFE_FREE(printer);
6332         }
6333 }
6334
6335 void free_printer_info_3(PRINTER_INFO_3 *printer)
6336 {
6337         SAFE_FREE(printer);
6338 }
6339
6340 void free_printer_info_4(PRINTER_INFO_4 *printer)
6341 {
6342         SAFE_FREE(printer);
6343 }
6344
6345 void free_printer_info_5(PRINTER_INFO_5 *printer)
6346 {
6347         SAFE_FREE(printer);
6348 }
6349
6350 void free_printer_info_6(PRINTER_INFO_6 *printer)
6351 {
6352         SAFE_FREE(printer);
6353 }
6354
6355 void free_printer_info_7(PRINTER_INFO_7 *printer)
6356 {
6357         SAFE_FREE(printer);
6358 }
6359
6360 void free_job_info_2(JOB_INFO_2 *job)
6361 {
6362     if (job!=NULL)
6363         free_devmode(job->devmode);
6364 }
6365
6366 /*******************************************************************
6367  * init a structure.
6368  ********************************************************************/
6369
6370 BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u, 
6371                                const fstring string, uint32 printer, uint32 type)
6372 {      
6373         if (q_u == NULL)
6374                 return False;
6375
6376         init_unistr2(&q_u->string, string, UNI_STR_TERMINATE);
6377
6378         q_u->printer=printer;
6379         q_u->type=type;
6380
6381         q_u->unknown0=0x0;
6382         q_u->unknown1=0x0;
6383
6384         return True;
6385 }
6386
6387 /*******************************************************************
6388  Parse a SPOOL_Q_REPLYOPENPRINTER structure.
6389 ********************************************************************/  
6390
6391 BOOL spoolss_io_q_replyopenprinter(const char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
6392 {
6393         prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
6394         depth++;
6395
6396         if(!prs_align(ps))
6397                 return False;
6398
6399         if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
6400                 return False;
6401
6402         if(!prs_align(ps))
6403                 return False;
6404
6405         if(!prs_uint32("printer", ps, depth, &q_u->printer))
6406                 return False;
6407         if(!prs_uint32("type", ps, depth, &q_u->type))
6408                 return False;
6409         
6410         if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6411                 return False;
6412         if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6413                 return False;
6414
6415         return True;
6416 }
6417
6418 /*******************************************************************
6419  Parse a SPOOL_R_REPLYOPENPRINTER structure.
6420 ********************************************************************/  
6421
6422 BOOL spoolss_io_r_replyopenprinter(const char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
6423 {               
6424         prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
6425         depth++;
6426
6427         if (!prs_align(ps))
6428                 return False;
6429
6430         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6431                 return False;
6432
6433         if (!prs_werror("status", ps, depth, &r_u->status))
6434                 return False;
6435
6436         return True;            
6437 }
6438
6439 /*******************************************************************
6440  * init a structure.
6441  ********************************************************************/
6442 BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd, 
6443                                         uint32 condition, uint32 change_id)
6444 {
6445
6446         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6447
6448         q_u->condition = condition;
6449         q_u->change_id = change_id;
6450
6451         /* magic values */
6452         q_u->unknown1 = 0x1;
6453         memset(q_u->unknown2, 0x0, 5);
6454         q_u->unknown2[0] = 0x1;
6455
6456         return True;
6457 }
6458
6459 /*******************************************************************
6460  Parse a SPOOL_Q_ROUTERREPLYPRINTER structure.
6461 ********************************************************************/
6462 BOOL spoolss_io_q_routerreplyprinter (const char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth)
6463 {
6464
6465         prs_debug(ps, depth, desc, "spoolss_io_q_routerreplyprinter");
6466         depth++;
6467
6468         if (!prs_align(ps))
6469                 return False;
6470
6471         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6472                 return False;
6473
6474         if (!prs_uint32("condition", ps, depth, &q_u->condition))
6475                 return False;
6476
6477         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6478                 return False;
6479
6480         if (!prs_uint32("change_id", ps, depth, &q_u->change_id))
6481                 return False;
6482
6483         if (!prs_uint8s(False, "dev_private",  ps, depth, q_u->unknown2, 5))
6484                 return False;
6485
6486         return True;
6487 }
6488
6489 /*******************************************************************
6490  Parse a SPOOL_R_ROUTERREPLYPRINTER structure.
6491 ********************************************************************/
6492 BOOL spoolss_io_r_routerreplyprinter (const char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth)
6493 {
6494         prs_debug(ps, depth, desc, "spoolss_io_r_routerreplyprinter");
6495         depth++;
6496
6497         if (!prs_align(ps))
6498                 return False;
6499
6500         if (!prs_werror("status", ps, depth, &r_u->status))
6501                 return False;
6502
6503         return True;
6504 }
6505
6506 /*******************************************************************
6507  * init a structure.
6508  ********************************************************************/
6509
6510 BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd)
6511 {      
6512         if (q_u == NULL)
6513                 return False;
6514
6515         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6516
6517         return True;
6518 }
6519
6520 /*******************************************************************
6521  Parse a SPOOL_Q_REPLYCLOSEPRINTER structure.
6522 ********************************************************************/  
6523
6524 BOOL spoolss_io_q_replycloseprinter(const char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth)
6525 {
6526         prs_debug(ps, depth, desc, "spoolss_io_q_replycloseprinter");
6527         depth++;
6528
6529         if(!prs_align(ps))
6530                 return False;
6531
6532         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6533                 return False;
6534
6535         return True;
6536 }
6537
6538 /*******************************************************************
6539  Parse a SPOOL_R_REPLYCLOSEPRINTER structure.
6540 ********************************************************************/  
6541
6542 BOOL spoolss_io_r_replycloseprinter(const char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth)
6543 {               
6544         prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
6545         depth++;
6546
6547         if (!prs_align(ps))
6548                 return False;
6549
6550         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6551                 return False;
6552
6553         if (!prs_werror("status", ps, depth, &r_u->status))
6554                 return False;
6555
6556         return True;            
6557 }
6558
6559 #if 0   /* JERRY - not currently used but could be :-) */
6560
6561 /*******************************************************************
6562  Deep copy a SPOOL_NOTIFY_INFO_DATA structure
6563  ******************************************************************/
6564 static BOOL copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, 
6565                                 SPOOL_NOTIFY_INFO_DATA *src, int n)
6566 {
6567         int i;
6568
6569         memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
6570         
6571         for (i=0; i<n; i++) {
6572                 int len;
6573                 uint16 *s = NULL;
6574                 
6575                 if (src->size != POINTER) 
6576                         continue;
6577                 len = src->notify_data.data.length;
6578                 s = SMB_MALLOC_ARRAY(uint16, len);
6579                 if (s == NULL) {
6580                         DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
6581                         return False;
6582                 }
6583                 
6584                 memcpy(s, src->notify_data.data.string, len*2);
6585                 dst->notify_data.data.string = s;
6586         }
6587         
6588         return True;
6589 }
6590
6591 /*******************************************************************
6592  Deep copy a SPOOL_NOTIFY_INFO structure
6593  ******************************************************************/
6594 static BOOL copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
6595 {
6596         if (!dst) {
6597                 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
6598                 return False;
6599         }
6600                 
6601         dst->version = src->version;
6602         dst->flags   = src->flags;
6603         dst->count   = src->count;
6604         
6605         if (dst->count) 
6606         {
6607                 dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count);
6608                 
6609                 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
6610                         dst->count));
6611
6612                 if (dst->data == NULL) {
6613                         DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", 
6614                                 dst->count));
6615                         return False;
6616                 }
6617                 
6618                 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
6619         }
6620         
6621         return True;
6622 }
6623 #endif  /* JERRY */
6624
6625 /*******************************************************************
6626  * init a structure.
6627  ********************************************************************/
6628
6629 BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
6630                                 uint32 change_low, uint32 change_high,
6631                                 SPOOL_NOTIFY_INFO *info)
6632 {      
6633         if (q_u == NULL)
6634                 return False;
6635
6636         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6637
6638         q_u->change_low=change_low;
6639         q_u->change_high=change_high;
6640
6641         q_u->unknown0=0x0;
6642         q_u->unknown1=0x0;
6643
6644         q_u->info_ptr=0x0FF0ADDE;
6645
6646         q_u->info.version=2;
6647         
6648         if (info->count) {
6649                 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
6650                         info->count));
6651                 q_u->info.version = info->version;
6652                 q_u->info.flags   = info->flags;
6653                 q_u->info.count   = info->count;
6654                 /* pointer field - be careful! */
6655                 q_u->info.data    = info->data;
6656         }
6657         else  {
6658         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
6659         q_u->info.count=0;
6660         }
6661
6662         return True;
6663 }
6664
6665 /*******************************************************************
6666  Parse a SPOOL_Q_REPLY_RRPCN structure.
6667 ********************************************************************/  
6668
6669 BOOL spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
6670 {
6671         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
6672         depth++;
6673
6674         if(!prs_align(ps))
6675                 return False;
6676
6677         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6678                 return False;
6679
6680         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
6681                 return False;
6682
6683         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
6684                 return False;
6685
6686         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6687                 return False;
6688
6689         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6690                 return False;
6691
6692         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
6693                 return False;
6694
6695         if(q_u->info_ptr!=0)
6696                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
6697                         return False;
6698                 
6699         return True;
6700 }
6701
6702 /*******************************************************************
6703  Parse a SPOOL_R_REPLY_RRPCN structure.
6704 ********************************************************************/  
6705
6706 BOOL spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
6707 {               
6708         prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
6709         depth++;
6710
6711         if (!prs_align(ps))
6712                 return False;
6713
6714         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
6715                 return False;
6716
6717         if (!prs_werror("status", ps, depth, &r_u->status))
6718                 return False;
6719
6720         return True;            
6721 }
6722
6723 /*******************************************************************
6724  * read a structure.
6725  * called from spoolss_q_getprinterdataex (srv_spoolss.c)
6726  ********************************************************************/
6727
6728 BOOL spoolss_io_q_getprinterdataex(const char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6729 {
6730         if (q_u == NULL)
6731                 return False;
6732
6733         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
6734         depth++;
6735
6736         if (!prs_align(ps))
6737                 return False;
6738         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6739                 return False;
6740         if (!prs_align(ps))
6741                 return False;
6742         if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
6743                 return False;
6744         if (!prs_align(ps))
6745                 return False;
6746         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
6747                 return False;
6748         if (!prs_align(ps))
6749                 return False;
6750         if (!prs_uint32("size", ps, depth, &q_u->size))
6751                 return False;
6752
6753         return True;
6754 }
6755
6756 /*******************************************************************
6757  * write a structure.
6758  * called from spoolss_r_getprinterdataex (srv_spoolss.c)
6759  ********************************************************************/
6760
6761 BOOL spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6762 {
6763         if (r_u == NULL)
6764                 return False;
6765
6766         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
6767         depth++;
6768
6769         if (!prs_align(ps))
6770                 return False;
6771         if (!prs_uint32("type", ps, depth, &r_u->type))
6772                 return False;
6773         if (!prs_uint32("size", ps, depth, &r_u->size))
6774                 return False;
6775         
6776         if (UNMARSHALLING(ps) && r_u->size) {
6777                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
6778                 if(!r_u->data)
6779                         return False;
6780         }
6781
6782         if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
6783                 return False;
6784                 
6785         if (!prs_align(ps))
6786                 return False;
6787         
6788         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6789                 return False;
6790         if (!prs_werror("status", ps, depth, &r_u->status))
6791                 return False;
6792                 
6793         return True;
6794 }
6795
6796 /*******************************************************************
6797  * read a structure.
6798  ********************************************************************/  
6799
6800 BOOL spoolss_io_q_setprinterdataex(const char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6801 {
6802         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
6803         depth++;
6804
6805         if(!prs_align(ps))
6806                 return False;
6807         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6808                 return False;
6809         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6810                 return False;
6811
6812         if(!prs_align(ps))
6813                 return False;
6814
6815         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
6816                 return False;
6817
6818         if(!prs_align(ps))
6819                 return False;
6820
6821         if(!prs_uint32("type", ps, depth, &q_u->type))
6822                 return False;
6823
6824         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
6825                 return False;
6826
6827         switch (q_u->type)
6828         {
6829                 case 0x1:
6830                 case 0x3:
6831                 case 0x4:
6832                 case 0x7:
6833                         if (q_u->max_len) {
6834                                 if (UNMARSHALLING(ps))
6835                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
6836                                 if(q_u->data == NULL)
6837                                         return False;
6838                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
6839                                         return False;
6840                         }
6841                         if(!prs_align(ps))
6842                                 return False;
6843                         break;
6844         }       
6845         
6846         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
6847                 return False;
6848
6849         return True;
6850 }
6851
6852 /*******************************************************************
6853  * write a structure.
6854  ********************************************************************/  
6855
6856 BOOL spoolss_io_r_setprinterdataex(const char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6857 {
6858         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
6859         depth++;
6860
6861         if(!prs_align(ps))
6862                 return False;
6863         if(!prs_werror("status",     ps, depth, &r_u->status))
6864                 return False;
6865
6866         return True;
6867 }
6868
6869 /*******************************************************************
6870  * read a structure.
6871  ********************************************************************/  
6872 BOOL make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
6873                                    POLICY_HND *hnd, const char *key, 
6874                                    uint32 size)
6875 {
6876         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
6877
6878         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6879         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
6880         q_u->size = size;
6881
6882         return True;
6883 }
6884
6885 /*******************************************************************
6886  * read a structure.
6887  ********************************************************************/  
6888
6889 BOOL spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
6890 {
6891         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
6892         depth++;
6893
6894         if(!prs_align(ps))
6895                 return False;
6896         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6897                 return False;
6898                 
6899         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6900                 return False;
6901
6902         if(!prs_align(ps))
6903                 return False;
6904         
6905         if(!prs_uint32("size", ps, depth, &q_u->size))
6906                 return False;
6907
6908         return True;
6909 }
6910
6911 /*******************************************************************
6912  * write a structure.
6913  ********************************************************************/  
6914
6915 BOOL spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
6916 {
6917         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
6918         depth++;
6919
6920         if(!prs_align(ps))
6921                 return False;
6922
6923         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
6924                 return False;
6925         
6926         if(!prs_align(ps))
6927                 return False;
6928
6929         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
6930                 return False;
6931
6932         if(!prs_werror("status",     ps, depth, &r_u->status))
6933                 return False;
6934
6935         return True;
6936 }
6937
6938 /*******************************************************************
6939  * read a structure.
6940  ********************************************************************/  
6941
6942 BOOL make_spoolss_q_deleteprinterkey(SPOOL_Q_DELETEPRINTERKEY *q_u, 
6943                                      POLICY_HND *hnd, char *keyname)
6944 {
6945         DEBUG(5,("make_spoolss_q_deleteprinterkey\n"));
6946
6947         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6948         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
6949
6950         return True;
6951 }
6952
6953 /*******************************************************************
6954  * read a structure.
6955  ********************************************************************/  
6956
6957 BOOL spoolss_io_q_deleteprinterkey(const char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth)
6958 {
6959         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey");
6960         depth++;
6961
6962         if(!prs_align(ps))
6963                 return False;
6964         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6965                 return False;
6966                 
6967         if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth))
6968                 return False;
6969
6970         return True;
6971 }
6972
6973 /*******************************************************************
6974  * write a structure.
6975  ********************************************************************/  
6976
6977 BOOL spoolss_io_r_deleteprinterkey(const char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth)
6978 {
6979         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey");
6980         depth++;
6981
6982         if(!prs_align(ps))
6983                 return False;
6984                 
6985         if(!prs_werror("status",     ps, depth, &r_u->status))
6986                 return False;
6987
6988         return True;
6989 }
6990
6991
6992 /*******************************************************************
6993  * read a structure.
6994  ********************************************************************/  
6995
6996 BOOL spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6997 {
6998         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
6999         depth++;
7000
7001         if(!prs_align(ps))
7002                 return False;
7003         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
7004                 return False;
7005                 
7006         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
7007                 return False;
7008
7009         if(!prs_align(ps))
7010                 return False;
7011         
7012         if(!prs_uint32("size", ps, depth, &q_u->size))
7013                 return False;
7014
7015         return True;
7016 }
7017
7018 /*******************************************************************
7019 ********************************************************************/  
7020
7021 static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
7022                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
7023 {
7024         int     i;
7025         uint32  valuename_offset,
7026                 data_offset,
7027                 current_offset;
7028         const uint32 basic_unit = 20; /* size of static portion of enum_values */
7029
7030         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
7031         depth++;        
7032
7033         /* 
7034          * offset data begins at 20 bytes per structure * size_of_array.
7035          * Don't forget the uint32 at the beginning 
7036          * */
7037         
7038         current_offset = basic_unit * ctr->size_of_array;
7039         
7040         /* first loop to write basic enum_value information */
7041         
7042         if (UNMARSHALLING(ps) && ctr->size_of_array) {
7043                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
7044                 if (!ctr->values)
7045                         return False;
7046         }
7047
7048         for (i=0; i<ctr->size_of_array; i++) {
7049                 uint32 base_offset, return_offset;
7050
7051                 base_offset = prs_offset(ps);
7052
7053                 valuename_offset = current_offset;
7054                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
7055                         return False;
7056
7057                 /* Read or write the value. */
7058
7059                 return_offset = prs_offset(ps);
7060
7061                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
7062                         return False;
7063                 }
7064
7065                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
7066                         return False;
7067
7068                 /* And go back. */
7069                 if (!prs_set_offset(ps, return_offset))
7070                         return False;
7071
7072                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
7073                         return False;
7074         
7075                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
7076                         return False;
7077         
7078                 data_offset = ctr->values[i].value_len + valuename_offset;
7079                 
7080                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
7081                         return False;
7082
7083                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
7084                         return False;
7085                         
7086                 /* Read or write the data. */
7087
7088                 return_offset = prs_offset(ps);
7089
7090                 if (!prs_set_offset(ps, base_offset + data_offset)) {
7091                         return False;
7092                 }
7093
7094                 if ( ctr->values[i].data_len ) {
7095                         if ( UNMARSHALLING(ps) ) {
7096                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
7097                                 if (!ctr->values[i].data)
7098                                         return False;
7099                         }
7100                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
7101                                 return False;
7102                 }
7103
7104                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
7105                 /* account for 2 byte alignment */
7106                 current_offset += (current_offset % 2);
7107
7108                 /* Remember how far we got. */
7109                 data_offset = prs_offset(ps);
7110
7111                 /* And go back. */
7112                 if (!prs_set_offset(ps, return_offset))
7113                         return False;
7114
7115         }
7116
7117         /* Go to the last data offset we got to. */
7118
7119         if (!prs_set_offset(ps, data_offset))
7120                 return False;
7121
7122         /* And ensure we're 2 byte aligned. */
7123
7124         if ( !prs_align_uint16(ps) )
7125                 return False;
7126
7127         return True;    
7128 }
7129
7130 /*******************************************************************
7131  * write a structure.
7132  ********************************************************************/  
7133
7134 BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
7135 {
7136         uint32 data_offset, end_offset;
7137         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
7138         depth++;
7139
7140         if(!prs_align(ps))
7141                 return False;
7142
7143         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
7144                 return False;
7145
7146         data_offset = prs_offset(ps);
7147
7148         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
7149                 return False;
7150
7151         if(!prs_align(ps))
7152                 return False;
7153
7154         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7155                 return False;
7156
7157         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
7158                 return False;
7159
7160         if(!prs_werror("status",     ps, depth, &r_u->status))
7161                 return False;
7162
7163         r_u->ctr.size_of_array = r_u->returned;
7164
7165         end_offset = prs_offset(ps);
7166
7167         if (!prs_set_offset(ps, data_offset))
7168                 return False;
7169
7170         if (r_u->ctr.size)
7171                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
7172                         return False;
7173
7174         if (!prs_set_offset(ps, end_offset))
7175                 return False;
7176         return True;
7177 }
7178
7179 /*******************************************************************
7180  * write a structure.
7181  ********************************************************************/  
7182
7183 /* 
7184    uint32 GetPrintProcessorDirectory(
7185        [in] unistr2 *name,
7186        [in] unistr2 *environment,
7187        [in] uint32 level,
7188        [in,out] RPC_BUFFER buffer,
7189        [in] uint32 offered,
7190        [out] uint32 needed,
7191        [out] uint32 returned
7192    );
7193
7194 */
7195
7196 BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered)
7197 {
7198         DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
7199
7200         init_unistr2(&q_u->name, name, UNI_STR_TERMINATE);
7201         init_unistr2(&q_u->environment, environment, UNI_STR_TERMINATE);
7202
7203         q_u->level = level;
7204
7205         q_u->buffer = buffer;
7206         q_u->offered = offered;
7207
7208         return True;
7209 }
7210
7211 BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
7212 {
7213         uint32 ptr;
7214
7215         prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
7216         depth++;
7217
7218         if(!prs_align(ps))
7219                 return False;   
7220
7221         if (!prs_uint32("ptr", ps, depth, &ptr)) 
7222                 return False;
7223
7224         if (ptr) {
7225                 if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
7226                         return False;
7227         }
7228
7229         if (!prs_align(ps))
7230                 return False;
7231
7232         if (!prs_uint32("ptr", ps, depth, &ptr))
7233                 return False;
7234
7235         if (ptr) {
7236                 if(!smb_io_unistr2("environment", &q_u->environment, True, 
7237                                    ps, depth))
7238                         return False;
7239         }
7240
7241         if (!prs_align(ps))
7242                 return False;
7243
7244         if(!prs_uint32("level",   ps, depth, &q_u->level))
7245                 return False;
7246
7247         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
7248                 return False;
7249         
7250         if(!prs_align(ps))
7251                 return False;
7252
7253         if(!prs_uint32("offered", ps, depth, &q_u->offered))
7254                 return False;
7255
7256         return True;
7257 }
7258
7259 /*******************************************************************
7260  * write a structure.
7261  ********************************************************************/  
7262
7263 BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
7264 {
7265         prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
7266         depth++;
7267
7268         if(!prs_align(ps))
7269                 return False;
7270
7271         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
7272                 return False;
7273         
7274         if(!prs_align(ps))
7275                 return False;
7276
7277         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7278                 return False;
7279                 
7280         if(!prs_werror("status",     ps, depth, &r_u->status))
7281                 return False;
7282
7283         return True;
7284 }
7285
7286 BOOL smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
7287 {
7288         prs_struct *ps=&buffer->prs;
7289
7290         prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
7291         depth++;
7292
7293         buffer->struct_start=prs_offset(ps);
7294
7295         if (!smb_io_unistr(desc, &info->name, ps, depth))
7296                 return False;
7297
7298         return True;
7299 }
7300
7301 /*******************************************************************
7302  * init a structure.
7303  ********************************************************************/
7304
7305 BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle, 
7306                             int level, FORM *form)
7307 {
7308         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7309         q_u->level = level;
7310         q_u->level2 = level;
7311         memcpy(&q_u->form, form, sizeof(FORM));
7312
7313         return True;
7314 }
7315
7316 /*******************************************************************
7317  * init a structure.
7318  ********************************************************************/
7319
7320 BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle, 
7321                             int level, const char *form_name, FORM *form)
7322 {
7323         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7324         q_u->level = level;
7325         q_u->level2 = level;
7326         memcpy(&q_u->form, form, sizeof(FORM));
7327         init_unistr2(&q_u->name, form_name, UNI_STR_TERMINATE);
7328
7329         return True;
7330 }
7331
7332 /*******************************************************************
7333  * init a structure.
7334  ********************************************************************/
7335
7336 BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, 
7337                                const char *form)
7338 {
7339         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7340         init_unistr2(&q_u->name, form, UNI_STR_TERMINATE);
7341         return True;
7342 }
7343
7344 /*******************************************************************
7345  * init a structure.
7346  ********************************************************************/
7347
7348 BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle, 
7349                             const char *formname, uint32 level, 
7350                             RPC_BUFFER *buffer, uint32 offered)
7351 {
7352         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7353         q_u->level = level;
7354         init_unistr2(&q_u->formname, formname, UNI_STR_TERMINATE);
7355         q_u->buffer=buffer;
7356         q_u->offered=offered;
7357
7358         return True;
7359 }
7360
7361 /*******************************************************************
7362  * init a structure.
7363  ********************************************************************/
7364
7365 BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
7366                               uint32 level, RPC_BUFFER *buffer,
7367                               uint32 offered)
7368 {
7369         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7370         q_u->level = level;
7371         q_u->buffer=buffer;
7372         q_u->offered=offered;
7373
7374         return True;
7375 }
7376
7377 /*******************************************************************
7378  * init a structure.
7379  ********************************************************************/
7380
7381 BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle, 
7382                            uint32 jobid, uint32 level, uint32 command)
7383 {
7384         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7385         q_u->jobid = jobid;
7386         q_u->level = level;
7387
7388         /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
7389            the server side code has it marked as unused. */
7390
7391         q_u->command = command;
7392
7393         return True;
7394 }
7395
7396 /*******************************************************************
7397  * init a structure.
7398  ********************************************************************/
7399
7400 BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
7401                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
7402                            uint32 offered)
7403 {
7404         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7405         q_u->jobid = jobid;
7406         q_u->level = level;
7407         q_u->buffer = buffer;
7408         q_u->offered = offered;
7409
7410         return True;
7411 }
7412
7413 /*******************************************************************
7414  * init a structure.
7415  ********************************************************************/
7416
7417 BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u, 
7418                                      POLICY_HND *handle)
7419 {
7420         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7421
7422         return True;
7423 }
7424
7425 /*******************************************************************
7426  * init a structure.
7427  ********************************************************************/
7428
7429 BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u, 
7430                                    POLICY_HND *handle)
7431 {
7432         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7433
7434         return True;
7435 }
7436
7437 /*******************************************************************
7438  * init a structure.
7439  ********************************************************************/
7440
7441 BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u, 
7442                                     POLICY_HND *handle, uint32 level,
7443                                     char *docname, char *outputfile,
7444                                     char *datatype)
7445 {
7446         DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container;
7447
7448         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7449
7450         ctr->level = level;
7451
7452         switch (level) {
7453         case 1:
7454                 ctr->docinfo.switch_value = level;
7455
7456                 ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0;
7457                 ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0;
7458                 ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0;
7459
7460                 init_unistr2(&ctr->docinfo.doc_info_1.docname, docname, UNI_STR_TERMINATE);
7461                 init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile, UNI_STR_TERMINATE);
7462                 init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype, UNI_STR_TERMINATE);
7463
7464                 break;
7465         case 2:
7466                 /* DOC_INFO_2 is only used by Windows 9x and since it
7467                    doesn't do printing over RPC we don't have to worry
7468                    about it. */
7469         default:
7470                 DEBUG(3, ("unsupported info level %d\n", level));
7471                 return False;
7472         }
7473
7474         return True;
7475 }
7476
7477 /*******************************************************************
7478  * init a structure.
7479  ********************************************************************/
7480
7481 BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u, 
7482                                   POLICY_HND *handle)
7483 {
7484         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7485
7486         return True;
7487 }
7488
7489 /*******************************************************************
7490  * init a structure.
7491  ********************************************************************/
7492
7493 BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u, 
7494                                  POLICY_HND *handle, uint32 data_size,
7495                                  char *data)
7496 {
7497         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7498         q_u->buffer_size = q_u->buffer_size2 = data_size;
7499         q_u->buffer = (unsigned char *)data;
7500         return True;
7501 }
7502
7503 /*******************************************************************
7504  * init a structure.
7505  ********************************************************************/
7506
7507 BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u, 
7508                                  POLICY_HND *handle, char *valuename)
7509 {
7510         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7511         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
7512
7513         return True;
7514 }
7515
7516 /*******************************************************************
7517  * init a structure.
7518  ********************************************************************/
7519
7520 BOOL make_spoolss_q_deleteprinterdataex(SPOOL_Q_DELETEPRINTERDATAEX *q_u, 
7521                                         POLICY_HND *handle, char *key,
7522                                         char *value)
7523 {
7524         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7525         init_unistr2(&q_u->valuename, value, UNI_STR_TERMINATE);
7526         init_unistr2(&q_u->keyname, key, UNI_STR_TERMINATE);
7527
7528         return True;
7529 }
7530
7531 /*******************************************************************
7532  * init a structure.
7533  ********************************************************************/
7534
7535 BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
7536                              uint32 flags, uint32 options, const char *localmachine,
7537                              uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
7538 {
7539         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7540
7541         q_u->flags = flags;
7542         q_u->options = options;
7543
7544         q_u->localmachine_ptr = 1;
7545
7546         init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
7547
7548         q_u->printerlocal = printerlocal;
7549
7550         if (option)
7551                 q_u->option_ptr = 1;
7552
7553         q_u->option = option;
7554
7555         return True;
7556 }
7557
7558
7559 /*******************************************************************
7560  ********************************************************************/  
7561
7562 BOOL spoolss_io_q_xcvdataport(const char *desc, SPOOL_Q_XCVDATAPORT *q_u, prs_struct *ps, int depth)
7563 {
7564         prs_debug(ps, depth, desc, "spoolss_io_q_xcvdataport");
7565         depth++;
7566
7567         if(!prs_align(ps))
7568                 return False;   
7569
7570         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
7571                 return False;
7572                 
7573         if(!smb_io_unistr2("", &q_u->dataname, True, ps, depth))
7574                 return False;
7575
7576         if (!prs_align(ps))
7577                 return False;
7578
7579         if(!prs_rpcbuffer("", ps, depth, &q_u->indata))
7580                 return False;
7581                 
7582         if (!prs_align(ps))
7583                 return False;
7584
7585         if (!prs_uint32("indata_len", ps, depth, &q_u->indata_len))
7586                 return False;
7587         if (!prs_uint32("offered", ps, depth, &q_u->offered))
7588                 return False;
7589         if (!prs_uint32("unknown", ps, depth, &q_u->unknown))
7590                 return False;
7591         
7592         return True;
7593 }
7594
7595 /*******************************************************************
7596  ********************************************************************/  
7597
7598 BOOL spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_struct *ps, int depth)
7599 {
7600         prs_debug(ps, depth, desc, "spoolss_io_r_xcvdataport");
7601         depth++;
7602
7603         if(!prs_align(ps))
7604                 return False;
7605         if(!prs_rpcbuffer("", ps, depth, &r_u->outdata))
7606                 return False;
7607                 
7608         if (!prs_align(ps))
7609                 return False;
7610
7611         if (!prs_uint32("needed", ps, depth, &r_u->needed))
7612                 return False;
7613         if (!prs_uint32("unknown", ps, depth, &r_u->unknown))
7614                 return False;
7615
7616         if(!prs_werror("status", ps, depth, &r_u->status))
7617                 return False;
7618
7619         return True;
7620 }
7621
7622 /*******************************************************************
7623  ********************************************************************/  
7624
7625 BOOL make_monitorui_buf( RPC_BUFFER *buf, const char *dllname )
7626 {
7627         UNISTR string;
7628         
7629         if ( !buf )
7630                 return False;
7631
7632         init_unistr( &string, dllname );
7633
7634         if ( !prs_unistr( "ui_dll", &buf->prs, 0, &string ) )
7635                 return False;
7636
7637         return True;
7638 }
7639
7640 /*******************************************************************
7641  ********************************************************************/  
7642  
7643 #define PORT_DATA_1_PAD    540
7644
7645 static BOOL smb_io_port_data_1( const char *desc, RPC_BUFFER *buf, int depth, SPOOL_PORT_DATA_1 *p1 )
7646 {
7647         prs_struct *ps = &buf->prs;
7648         uint8 padding[PORT_DATA_1_PAD];
7649
7650         prs_debug(ps, depth, desc, "smb_io_port_data_1");
7651         depth++;
7652
7653         if(!prs_align(ps))
7654                 return False;   
7655
7656         if( !prs_uint16s(True, "portname", ps, depth, p1->portname, MAX_PORTNAME))
7657                 return False;
7658
7659         if (!prs_uint32("version", ps, depth, &p1->version))
7660                 return False;
7661         if (!prs_uint32("protocol", ps, depth, &p1->protocol))
7662                 return False;
7663         if (!prs_uint32("size", ps, depth, &p1->size))
7664                 return False;
7665         if (!prs_uint32("reserved", ps, depth, &p1->reserved))
7666                 return False;
7667
7668         if( !prs_uint16s(True, "hostaddress", ps, depth, p1->hostaddress, MAX_NETWORK_NAME))
7669                 return False;
7670         if( !prs_uint16s(True, "snmpcommunity", ps, depth, p1->snmpcommunity, MAX_SNMP_COMM_NAME))
7671                 return False;
7672
7673         if (!prs_uint32("dblspool", ps, depth, &p1->dblspool))
7674                 return False;
7675                 
7676         if( !prs_uint16s(True, "queue", ps, depth, p1->queue, MAX_QUEUE_NAME))
7677                 return False;
7678         if( !prs_uint16s(True, "ipaddress", ps, depth, p1->ipaddress, MAX_IPADDR_STRING))
7679                 return False;
7680
7681         if( !prs_uint8s(False, "", ps, depth, padding, PORT_DATA_1_PAD))
7682                 return False;
7683                 
7684         if (!prs_uint32("port", ps, depth, &p1->port))
7685                 return False;
7686         if (!prs_uint32("snmpenabled", ps, depth, &p1->snmpenabled))
7687                 return False;
7688         if (!prs_uint32("snmpdevindex", ps, depth, &p1->snmpdevindex))
7689                 return False;
7690                 
7691         return True;
7692 }
7693
7694 /*******************************************************************
7695  ********************************************************************/  
7696
7697 BOOL convert_port_data_1( NT_PORT_DATA_1 *port1, RPC_BUFFER *buf ) 
7698 {
7699         SPOOL_PORT_DATA_1 spdata_1;
7700         
7701         ZERO_STRUCT( spdata_1 );
7702         
7703         if ( !smb_io_port_data_1( "port_data_1", buf, 0, &spdata_1 ) )
7704                 return False;
7705                 
7706         rpcstr_pull(port1->name, spdata_1.portname, sizeof(port1->name), -1, 0);
7707         rpcstr_pull(port1->queue, spdata_1.queue, sizeof(port1->queue), -1, 0);
7708         rpcstr_pull(port1->hostaddr, spdata_1.hostaddress, sizeof(port1->hostaddr), -1, 0);
7709         
7710         port1->port = spdata_1.port;
7711         
7712         switch ( spdata_1.protocol ) {
7713         case 1:
7714                 port1->protocol = PORT_PROTOCOL_DIRECT;
7715                 break;
7716         case 2:
7717                 port1->protocol = PORT_PROTOCOL_LPR;
7718                 break;
7719         default:
7720                 DEBUG(3,("convert_port_data_1: unknown protocol [%d]!\n", 
7721                         spdata_1.protocol));
7722                 return False;
7723         }
7724
7725         return True;
7726 }
7727