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