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