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