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