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