s3-spoolss: remove old spoolss_AddPrinterDriver{Ex}.
[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 NOTIFY OPTION TYPE structure.
75 ********************************************************************/  
76
77 /* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
78    structure.  The _TYPE structure is really the deferred referrants (i.e
79    the notify fields array) of the _TYPE structure. -tpot */
80
81 static bool smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
82 {
83         prs_debug(ps, depth, desc, "smb_io_notify_option_type");
84         depth++;
85  
86         if (!prs_align(ps))
87                 return False;
88
89         if(!prs_uint16("type", ps, depth, &type->type))
90                 return False;
91         if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
92                 return False;
93         if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
94                 return False;
95         if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
96                 return False;
97         if(!prs_uint32("count", ps, depth, &type->count))
98                 return False;
99         if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
100                 return False;
101
102         return True;
103 }
104
105 /*******************************************************************
106 reads or writes an NOTIFY OPTION TYPE DATA.
107 ********************************************************************/  
108
109 static bool smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
110 {
111         int i;
112
113         prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
114         depth++;
115  
116         /* if there are no fields just return */
117         if (type->fields_ptr==0)
118                 return True;
119
120         if(!prs_align(ps))
121                 return False;
122
123         if(!prs_uint32("count2", ps, depth, &type->count2))
124                 return False;
125         
126         if (type->count2 != type->count)
127                 DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
128
129         if (type->count2 > MAX_NOTIFY_TYPE_FOR_NOW) {
130                 return False;
131         }
132
133         /* parse the option type data */
134         for(i=0;i<type->count2;i++)
135                 if(!prs_uint16("fields",ps,depth,&type->fields[i]))
136                         return False;
137         return True;
138 }
139
140 /*******************************************************************
141 reads or writes an NOTIFY OPTION structure.
142 ********************************************************************/  
143
144 static bool smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
145 {               
146         int i;
147         
148         prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
149         depth++;
150  
151         if(!prs_uint32("count", ps, depth, &ctr->count))
152                 return False;
153
154         /* reading */
155         if (UNMARSHALLING(ps) && ctr->count)
156                 if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL)
157                         return False;
158                 
159         /* the option type struct */
160         for(i=0;i<ctr->count;i++)
161                 if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
162                         return False;
163
164         /* the type associated with the option type struct */
165         for(i=0;i<ctr->count;i++)
166                 if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
167                         return False;
168         
169         return True;
170 }
171
172 /*******************************************************************
173 reads or writes an NOTIFY OPTION structure.
174 ********************************************************************/  
175
176 static bool smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
177 {
178         prs_debug(ps, depth, desc, "smb_io_notify_option");
179         depth++;
180         
181         if(!prs_uint32("version", ps, depth, &option->version))
182                 return False;
183         if(!prs_uint32("flags", ps, depth, &option->flags))
184                 return False;
185         if(!prs_uint32("count", ps, depth, &option->count))
186                 return False;
187         if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
188                 return False;
189         
190         /* marshalling or unmarshalling, that would work */     
191         if (option->option_type_ptr!=0) {
192                 if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
193                         return False;
194         }
195         else {
196                 option->ctr.type=NULL;
197                 option->ctr.count=0;
198         }
199         
200         return True;
201 }
202
203 /*******************************************************************
204 reads or writes an NOTIFY INFO DATA structure.
205 ********************************************************************/  
206
207 static bool smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
208 {
209         uint32 useless_ptr=0x0FF0ADDE;
210
211         prs_debug(ps, depth, desc, "smb_io_notify_info_data");
212         depth++;
213
214         if(!prs_align(ps))
215                 return False;
216         if(!prs_uint16("type",           ps, depth, &data->type))
217                 return False;
218         if(!prs_uint16("field",          ps, depth, &data->field))
219                 return False;
220
221         if(!prs_uint32("how many words", ps, depth, &data->size))
222                 return False;
223         if(!prs_uint32("id",             ps, depth, &data->id))
224                 return False;
225         if(!prs_uint32("how many words", ps, depth, &data->size))
226                 return False;
227
228         switch (data->enc_type) {
229
230                 /* One and two value data has two uint32 values */
231
232         case NOTIFY_ONE_VALUE:
233         case NOTIFY_TWO_VALUE:
234
235                 if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
236                         return False;
237                 if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
238                         return False;
239                 break;
240
241                 /* Pointers and strings have a string length and a
242                    pointer.  For a string the length is expressed as
243                    the number of uint16 characters plus a trailing
244                    \0\0. */
245
246         case NOTIFY_POINTER:
247
248                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
249                         return False;
250                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
251                         return False;
252
253                 break;
254
255         case NOTIFY_STRING:
256
257                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
258                         return False;
259
260                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
261                         return False;
262
263                 break;
264
265         case NOTIFY_SECDESC:
266                 if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
267                         return False;
268                 if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
269                         return False;
270                 
271                 break;
272
273         default:
274                 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
275                           data->enc_type));
276                 break;
277         }
278
279         return True;
280 }
281
282 /*******************************************************************
283 reads or writes an NOTIFY INFO DATA structure.
284 ********************************************************************/  
285
286 bool smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
287                                      prs_struct *ps, int depth)
288 {
289         prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
290         depth++;
291         
292         if(!prs_align(ps))
293                 return False;
294
295         switch(data->enc_type) {
296
297                 /* No data for values */
298
299         case NOTIFY_ONE_VALUE:
300         case NOTIFY_TWO_VALUE:
301
302                 break;
303
304                 /* Strings start with a length in uint16s */
305
306         case NOTIFY_STRING:
307
308                 if (MARSHALLING(ps))
309                         data->notify_data.data.length /= 2;
310
311                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
312                         return False;
313
314                 if (UNMARSHALLING(ps) && data->notify_data.data.length) {
315                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
316                                                                 data->notify_data.data.length);
317
318                         if (!data->notify_data.data.string) 
319                                 return False;
320                 }
321
322                 if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
323                                    data->notify_data.data.length))
324                         return False;
325
326                 if (MARSHALLING(ps))
327                         data->notify_data.data.length *= 2;
328
329                 break;
330
331         case NOTIFY_POINTER:
332
333                 if (UNMARSHALLING(ps) && data->notify_data.data.length) {
334                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
335                                                                 data->notify_data.data.length);
336
337                         if (!data->notify_data.data.string) 
338                                 return False;
339                 }
340
341                 if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
342                         return False;
343
344                 break;
345
346         case NOTIFY_SECDESC:    
347                 if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
348                         return False;
349                 if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
350                         return False;
351                 break;
352
353         default:
354                 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
355                           data->enc_type));
356                 break;
357         }
358
359 #if 0
360         if (isvalue==False) {
361
362                 /* length of string in unicode include \0 */
363                 x=data->notify_data.data.length+1;
364
365                 if (data->field != 16)
366                 if(!prs_uint32("string length", ps, depth, &x ))
367                         return False;
368
369                 if (MARSHALLING(ps)) {
370                         /* These are already in little endian format. Don't byte swap. */
371                         if (x == 1) {
372
373                                 /* No memory allocated for this string
374                                    therefore following the data.string
375                                    pointer is a bad idea.  Use a pointer to
376                                    the uint32 length union member to
377                                    provide a source for a unicode NULL */
378
379                                 if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2)) 
380                                         return False;
381                         } else {
382
383                                 if (data->field == 16)
384                                         x /= 2;
385
386                                 if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
387                                         return False;
388                         }
389                 } else {
390
391                         /* Tallocate memory for string */
392
393                         if (x) {
394                                 data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
395                                 if (!data->notify_data.data.string) 
396                                         return False;
397                         } else {
398                                 data->notify_data.data.string = NULL;
399                         }
400
401                         if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
402                                 return False;
403                 }
404         }
405
406 #endif
407
408 #if 0   /* JERRY */
409         /* Win2k does not seem to put this parse align here */
410         if(!prs_align(ps))
411                 return False;
412 #endif
413
414         return True;
415 }
416
417 /*******************************************************************
418 reads or writes an NOTIFY INFO structure.
419 ********************************************************************/  
420
421 static bool smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
422 {
423         int i;
424
425         prs_debug(ps, depth, desc, "smb_io_notify_info");
426         depth++;
427  
428         if(!prs_align(ps))
429                 return False;
430
431         if(!prs_uint32("count", ps, depth, &info->count))
432                 return False;
433         if(!prs_uint32("version", ps, depth, &info->version))
434                 return False;
435         if(!prs_uint32("flags", ps, depth, &info->flags))
436                 return False;
437         if(!prs_uint32("count", ps, depth, &info->count))
438                 return False;
439
440         for (i=0;i<info->count;i++) {
441                 if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
442                         return False;
443         }
444
445         /* now do the strings at the end of the stream */       
446         for (i=0;i<info->count;i++) {
447                 if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
448                         return False;
449         }
450
451         return True;
452 }
453
454 /*******************************************************************
455 ********************************************************************/  
456
457 bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
458 {
459         prs_debug(ps, depth, desc, "");
460         depth++;
461
462         if (!prs_align(ps))
463                 return False;
464
465         if (!prs_uint32("size", ps, depth, &q_u->size))
466                 return False;
467
468         if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
469                 return False;
470         if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
471                 return False;
472
473         if (!prs_uint32("build", ps, depth, &q_u->build))
474                 return False;
475         if (!prs_uint32("major", ps, depth, &q_u->major))
476                 return False;
477         if (!prs_uint32("minor", ps, depth, &q_u->minor))
478                 return False;
479         if (!prs_uint32("processor", ps, depth, &q_u->processor))
480                 return False;
481
482         if (!prs_io_unistr2("", ps, depth, q_u->client_name))
483                 return False;
484         if (!prs_align(ps))
485                 return False;
486
487         if (!prs_io_unistr2("", ps, depth, q_u->user_name))
488                 return False;
489
490         return True;
491 }
492
493 /*******************************************************************
494 ********************************************************************/  
495
496 static bool spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
497 {
498         if (q_u==NULL)
499                 return False;
500
501         prs_debug(ps, depth, desc, "spool_io_user_level");
502         depth++;
503
504         if (!prs_align(ps))
505                 return False;
506
507         if (!prs_uint32("level", ps, depth, &q_u->level))
508                 return False;
509         
510         switch ( q_u->level ) 
511         {       
512                 case 1:
513                         if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, 
514                                 sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) 
515                         {
516                                 return False;
517                         }
518                         break;
519                 default:
520                         return False;   
521         }       
522
523         return True;
524 }
525
526 /*******************************************************************
527  * read or write a DEVICEMODE struct.
528  * on reading allocate memory for the private member
529  ********************************************************************/
530
531 #define DM_NUM_OPTIONAL_FIELDS          8
532
533 bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
534 {
535         int available_space;            /* size of the device mode left to parse */
536                                         /* only important on unmarshalling       */
537         int i = 0;
538         uint16 *unistr_buffer;
539         int j;
540                                         
541         struct optional_fields {
542                 fstring         name;
543                 uint32*         field;
544         } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
545                 { "icmmethod",          NULL },
546                 { "icmintent",          NULL },
547                 { "mediatype",          NULL },
548                 { "dithertype",         NULL },
549                 { "reserved1",          NULL },
550                 { "reserved2",          NULL },
551                 { "panningwidth",       NULL },
552                 { "panningheight",      NULL }
553         };
554
555         /* assign at run time to keep non-gcc compilers happy */
556
557         opt_fields[0].field = &devmode->icmmethod;
558         opt_fields[1].field = &devmode->icmintent;
559         opt_fields[2].field = &devmode->mediatype;
560         opt_fields[3].field = &devmode->dithertype;
561         opt_fields[4].field = &devmode->reserved1;
562         opt_fields[5].field = &devmode->reserved2;
563         opt_fields[6].field = &devmode->panningwidth;
564         opt_fields[7].field = &devmode->panningheight;
565                 
566         
567         prs_debug(ps, depth, desc, "spoolss_io_devmode");
568         depth++;
569
570         if (UNMARSHALLING(ps)) {
571                 devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
572                 if (devmode->devicename.buffer == NULL)
573                         return False;
574                 unistr_buffer = devmode->devicename.buffer;
575         }
576         else {
577                 /* devicename is a static sized string but the buffer we set is not */
578                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
579                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
580                 for ( j=0; devmode->devicename.buffer[j]; j++ )
581                         unistr_buffer[j] = devmode->devicename.buffer[j];
582         }
583                 
584         if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
585                 return False;
586         
587         if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
588                 return False;
589                 
590         if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
591                 return False;
592         if (!prs_uint16("size",             ps, depth, &devmode->size))
593                 return False;
594         if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
595                 return False;
596         if (!prs_uint32("fields",           ps, depth, &devmode->fields))
597                 return False;
598         if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
599                 return False;
600         if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
601                 return False;
602         if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
603                 return False;
604         if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
605                 return False;
606         if (!prs_uint16("scale",            ps, depth, &devmode->scale))
607                 return False;
608         if (!prs_uint16("copies",           ps, depth, &devmode->copies))
609                 return False;
610         if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
611                 return False;
612         if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
613                 return False;
614         if (!prs_uint16("color",            ps, depth, &devmode->color))
615                 return False;
616         if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
617                 return False;
618         if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
619                 return False;
620         if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
621                 return False;
622         if (!prs_uint16("collate",          ps, depth, &devmode->collate))
623                 return False;
624
625         if (UNMARSHALLING(ps)) {
626                 devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
627                 if (devmode->formname.buffer == NULL)
628                         return False;
629                 unistr_buffer = devmode->formname.buffer;
630         }
631         else {
632                 /* devicename is a static sized string but the buffer we set is not */
633                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
634                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
635                 for ( j=0; devmode->formname.buffer[j]; j++ )
636                         unistr_buffer[j] = devmode->formname.buffer[j];
637         }
638         
639         if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
640                 return False;
641         if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
642                 return False;
643         if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
644                 return False;
645         if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
646                 return False;
647         if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
648                 return False;
649         if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
650                 return False;
651         if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
652                 return False;
653         /* 
654          * every device mode I've ever seen on the wire at least has up 
655          * to the displayfrequency field.   --jerry (05-09-2002)
656          */
657          
658         /* add uint32's + uint16's + two UNICODE strings */
659          
660         available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
661         
662         /* Sanity check - we only have uint32's left tp parse */
663         
664         if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
665                 DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
666                         available_space, devmode->size));
667                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
668                 return False;
669         }
670
671         /* 
672          * Conditional parsing.  Assume that the DeviceMode has been 
673          * zero'd by the caller. 
674          */
675         
676         while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
677         {
678                 DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
679                 if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
680                         return False;
681                 available_space -= sizeof(uint32);
682                 i++;
683         }        
684         
685         /* Sanity Check - we should no available space at this point unless 
686            MS changes the device mode structure */
687                 
688         if (available_space) {
689                 DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
690                 DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
691                         available_space, devmode->size));
692                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
693                 return False;
694         }
695
696
697         if (devmode->driverextra!=0) {
698                 if (UNMARSHALLING(ps)) {
699                         devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
700                         if(devmode->dev_private == NULL)
701                                 return False;
702                         DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); 
703                 }
704                         
705                 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
706                 if (!prs_uint8s(False, "dev_private",  ps, depth,
707                                 devmode->dev_private, devmode->driverextra))
708                         return False;
709         }
710
711         return True;
712 }
713
714 /*******************************************************************
715  Read or write a DEVICEMODE container
716 ********************************************************************/  
717
718 static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
719 {
720         if (dm_c==NULL)
721                 return False;
722
723         prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
724         depth++;
725
726         if(!prs_align(ps))
727                 return False;
728         
729         if (!prs_uint32("size", ps, depth, &dm_c->size))
730                 return False;
731
732         if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
733                 return False;
734
735         if (dm_c->size==0 || dm_c->devmode_ptr==0) {
736                 if (UNMARSHALLING(ps))
737                         /* if while reading there is no DEVMODE ... */
738                         dm_c->devmode=NULL;
739                 return True;
740         }
741         
742         /* so we have a DEVICEMODE to follow */         
743         if (UNMARSHALLING(ps)) {
744                 DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
745                 dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1);
746                 if(dm_c->devmode == NULL)
747                         return False;
748         }
749         
750         /* this is bad code, shouldn't be there */
751         if (!prs_uint32("size", ps, depth, &dm_c->size))
752                 return False;
753                 
754         if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
755                 return False;
756
757         return True;
758 }
759
760 /*******************************************************************
761  * init a structure.
762  ********************************************************************/
763
764 bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
765         const char *srv_name, const char* clientname, const char* user_name,
766         uint32 level, PRINTER_INFO_CTR *ctr)
767 {
768         DEBUG(5,("make_spoolss_q_addprinterex\n"));
769         
770         if (!ctr || !ctr->printers_2) 
771                 return False;
772
773         ZERO_STRUCTP(q_u);
774
775         q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
776         if (!q_u->server_name) {
777                 return False;
778         }
779         init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
780
781         q_u->level = level;
782         
783         q_u->info.level = level;
784         q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
785         switch (level) {
786                 case 2:
787                         /* init q_u->info.info2 from *info */
788                         if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
789                                 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
790                                 return False;
791                         }
792                         break;
793                 default :
794                         break;
795         }
796
797         q_u->user_switch=1;
798
799         q_u->user_ctr.level                 = 1;
800         q_u->user_ctr.user.user1            = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
801         if (!q_u->user_ctr.user.user1) {
802                 return False;
803         }
804         q_u->user_ctr.user.user1->build     = 1381;
805         q_u->user_ctr.user.user1->major     = 2; 
806         q_u->user_ctr.user.user1->minor     = 0;
807         q_u->user_ctr.user.user1->processor = 0;
808
809         q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
810         if (!q_u->user_ctr.user.user1->client_name) {
811                 return False;
812         }
813         q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
814         if (!q_u->user_ctr.user.user1->user_name) {
815                 return False;
816         }
817         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
818         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
819
820         q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
821                                    q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
822         
823         return True;
824 }
825         
826 /*******************************************************************
827 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
828 *******************************************************************/
829
830 bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
831                                 PRINTER_INFO_2 *info)
832 {
833
834         SPOOL_PRINTER_INFO_LEVEL_2 *inf;
835
836         /* allocate the necessary memory */
837         if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
838                 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
839                 return False;
840         }
841
842         inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
843         inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
844         inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
845         inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
846         inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
847         inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
848         inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
849         inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
850         inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
851         inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
852         inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
853         inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
854         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
855         inf->attributes         = info->attributes;
856         inf->priority           = info->priority;
857         inf->default_priority   = info->defaultpriority;
858         inf->starttime          = info->starttime;
859         inf->untiltime          = info->untiltime;
860         inf->cjobs              = info->cjobs;
861         inf->averageppm = info->averageppm;
862         init_unistr2_from_unistr(inf, &inf->servername, &info->servername);
863         init_unistr2_from_unistr(inf, &inf->printername, &info->printername);
864         init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename);
865         init_unistr2_from_unistr(inf, &inf->portname, &info->portname);
866         init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername);
867         init_unistr2_from_unistr(inf, &inf->comment, &info->comment);
868         init_unistr2_from_unistr(inf, &inf->location, &info->location);
869         init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile);
870         init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor);
871         init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
872         init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters);
873         init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
874
875         *spool_info2 = inf;
876
877         return True;
878 }
879
880 /*******************************************************************
881 create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
882 *******************************************************************/
883
884 bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, 
885                                 PRINTER_INFO_3 *info)
886 {
887
888         SPOOL_PRINTER_INFO_LEVEL_3 *inf;
889
890         /* allocate the necessary memory */
891         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
892                 DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
893                 return False;
894         }
895         
896         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
897
898         *spool_info3 = inf;
899
900         return True;
901 }
902
903 /*******************************************************************
904 create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
905 *******************************************************************/
906
907 bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, 
908                                 PRINTER_INFO_7 *info)
909 {
910
911         SPOOL_PRINTER_INFO_LEVEL_7 *inf;
912
913         /* allocate the necessary memory */
914         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
915                 DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
916                 return False;
917         }
918
919         inf->guid_ptr = (info->guid.buffer!=NULL)?1:0;
920         inf->action = info->action;
921         init_unistr2_from_unistr(inf, &inf->guid, &info->guid);
922
923         *spool_info7 = inf;
924
925         return True;
926 }
927
928 /*******************************************************************
929  * make a structure.
930  ********************************************************************/
931
932 bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
933                                    const POLICY_HND *handle,
934                                    const char *valuename, uint32 size)
935 {
936         if (q_u == NULL) return False;
937
938         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
939
940         q_u->handle = *handle;
941         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
942         q_u->size = size;
943
944         return True;
945 }
946
947 /*******************************************************************
948  * read a structure.
949  * called from spoolss_q_getprinterdata (srv_spoolss.c)
950  ********************************************************************/
951
952 bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
953 {
954         if (q_u == NULL)
955                 return False;
956
957         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
958         depth++;
959
960         if (!prs_align(ps))
961                 return False;
962         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
963                 return False;
964         if (!prs_align(ps))
965                 return False;
966         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
967                 return False;
968         if (!prs_align(ps))
969                 return False;
970         if (!prs_uint32("size", ps, depth, &q_u->size))
971                 return False;
972
973         return True;
974 }
975
976 /*******************************************************************
977  * write a structure.
978  * called from spoolss_r_getprinterdata (srv_spoolss.c)
979  ********************************************************************/
980
981 bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
982 {
983         if (r_u == NULL)
984                 return False;
985
986         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
987         depth++;
988
989         if (!prs_align(ps))
990                 return False;
991         if (!prs_uint32("type", ps, depth, &r_u->type))
992                 return False;
993         if (!prs_uint32("size", ps, depth, &r_u->size))
994                 return False;
995         
996         if (UNMARSHALLING(ps) && r_u->size) {
997                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
998                 if(!r_u->data)
999                         return False;
1000         }
1001
1002         if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
1003                 return False;
1004                 
1005         if (!prs_align(ps))
1006                 return False;
1007         
1008         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1009                 return False;
1010         if (!prs_werror("status", ps, depth, &r_u->status))
1011                 return False;
1012                 
1013         return True;
1014 }
1015
1016 /*******************************************************************
1017  * read a structure.
1018  * called from spoolss_q_rffpcnex (srv_spoolss.c)
1019  ********************************************************************/
1020
1021 bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1022 {
1023         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1024         depth++;
1025
1026         if(!prs_align(ps))
1027                 return False;
1028
1029         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1030                 return False;
1031         if(!prs_uint32("flags", ps, depth, &q_u->flags))
1032                 return False;
1033         if(!prs_uint32("options", ps, depth, &q_u->options))
1034                 return False;
1035         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1036                 return False;
1037         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1038                 return False;
1039
1040         if(!prs_align(ps))
1041                 return False;
1042                 
1043         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1044                 return False;
1045
1046         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1047                 return False;
1048         
1049         if (q_u->option_ptr!=0) {
1050         
1051                 if (UNMARSHALLING(ps))
1052                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1053                                 return False;
1054         
1055                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1056                         return False;
1057         }
1058         
1059         return True;
1060 }
1061
1062 /*******************************************************************
1063  * write a structure.
1064  * called from spoolss_r_rffpcnex (srv_spoolss.c)
1065  ********************************************************************/
1066
1067 bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1068 {
1069         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1070         depth++;
1071
1072         if(!prs_werror("status", ps, depth, &r_u->status))
1073                 return False;
1074
1075         return True;
1076 }
1077
1078 /*******************************************************************
1079  * read a structure.
1080  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1081  ********************************************************************/
1082
1083 bool spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1084 {
1085         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1086         depth++;
1087
1088         if(!prs_align(ps))
1089                 return False;
1090
1091         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1092                 return False;
1093
1094         if(!prs_uint32("change", ps, depth, &q_u->change))
1095                 return False;
1096         
1097         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1098                 return False;
1099         
1100         if (q_u->option_ptr!=0) {
1101         
1102                 if (UNMARSHALLING(ps))
1103                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1104                                 return False;
1105         
1106                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1107                         return False;
1108         }
1109
1110         return True;
1111 }
1112
1113 /*******************************************************************
1114  * write a structure.
1115  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
1116  ********************************************************************/
1117
1118 bool spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
1119 {
1120         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
1121         depth++;
1122
1123         if(!prs_align(ps))
1124                 return False;
1125                 
1126         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
1127                 return False;
1128
1129         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
1130                 return False;
1131         
1132         if(!prs_align(ps))
1133                 return False;
1134         if(!prs_werror("status", ps, depth, &r_u->status))
1135                 return False;
1136
1137         return True;
1138 }
1139
1140 /*******************************************************************
1141  * return the length of a uint16 (obvious, but the code is clean)
1142  ********************************************************************/
1143
1144 static uint32 size_of_uint16(uint16 *value)
1145 {
1146         return (sizeof(*value));
1147 }
1148
1149 /*******************************************************************
1150  * return the length of a uint32 (obvious, but the code is clean)
1151  ********************************************************************/
1152
1153 static uint32 size_of_uint32(uint32 *value)
1154 {
1155         return (sizeof(*value));
1156 }
1157
1158 /*******************************************************************
1159  * return the length of a NTTIME (obvious, but the code is clean)
1160  ********************************************************************/
1161
1162 static uint32 size_of_nttime(NTTIME *value)
1163 {
1164         return (sizeof(*value));
1165 }
1166
1167 /*******************************************************************
1168  * return the length of a uint32 (obvious, but the code is clean)
1169  ********************************************************************/
1170
1171 static uint32 size_of_device_mode(DEVICEMODE *devmode)
1172 {
1173         if (devmode==NULL)
1174                 return (4);
1175         else 
1176                 return (4+devmode->size+devmode->driverextra);
1177 }
1178
1179 /*******************************************************************
1180  * return the length of a uint32 (obvious, but the code is clean)
1181  ********************************************************************/
1182
1183 static uint32 size_of_systemtime(SYSTEMTIME *systime)
1184 {
1185         if (systime==NULL)
1186                 return (4);
1187         else 
1188                 return (sizeof(SYSTEMTIME) +4);
1189 }
1190
1191 /*******************************************************************
1192  Parse a DEVMODE structure and its relative pointer.
1193 ********************************************************************/
1194
1195 static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
1196 {
1197         prs_struct *ps=&buffer->prs;
1198
1199         prs_debug(ps, depth, desc, "smb_io_reldevmode");
1200         depth++;
1201
1202         if (MARSHALLING(ps)) {
1203                 uint32 struct_offset = prs_offset(ps);
1204                 uint32 relative_offset;
1205                 
1206                 if (*devmode == NULL) {
1207                         relative_offset=0;
1208                         if (!prs_uint32("offset", ps, depth, &relative_offset))
1209                                 return False;
1210                         DEBUG(8, ("boing, the devmode was NULL\n"));
1211                         
1212                         return True;
1213                 }
1214                 
1215                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
1216
1217                 /* mz:  we have to align the device mode for VISTA */
1218                 if (buffer->string_at_end % 4) {
1219                         buffer->string_at_end += 4 - (buffer->string_at_end % 4);
1220                 }
1221
1222                 if(!prs_set_offset(ps, buffer->string_at_end))
1223                         return False;
1224                 
1225                 /* write the DEVMODE */
1226                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1227                         return False;
1228
1229                 if(!prs_set_offset(ps, struct_offset))
1230                         return False;
1231                 
1232                 relative_offset=buffer->string_at_end - buffer->struct_start;
1233                 /* write its offset */
1234                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1235                         return False;
1236         }
1237         else {
1238                 uint32 old_offset;
1239                 
1240                 /* read the offset */
1241                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
1242                         return False;
1243                 if (buffer->string_at_end == 0) {
1244                         *devmode = NULL;
1245                         return True;
1246                 }
1247
1248                 old_offset = prs_offset(ps);
1249                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
1250                         return False;
1251
1252                 /* read the string */
1253                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
1254                         return False;
1255                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1256                         return False;
1257
1258                 if(!prs_set_offset(ps, old_offset))
1259                         return False;
1260         }
1261         return True;
1262 }
1263
1264 /*******************************************************************
1265  Parse a PRINTER_INFO_0 structure.
1266 ********************************************************************/  
1267
1268 bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
1269 {
1270         prs_struct *ps=&buffer->prs;
1271
1272         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
1273         depth++;        
1274         
1275         buffer->struct_start=prs_offset(ps);
1276
1277         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1278                 return False;
1279         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
1280                 return False;
1281         
1282         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
1283                 return False;
1284         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
1285                 return False;
1286         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
1287                 return False;
1288
1289         if(!prs_uint16("year", ps, depth, &info->year))
1290                 return False;
1291         if(!prs_uint16("month", ps, depth, &info->month))
1292                 return False;
1293         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
1294                 return False;
1295         if(!prs_uint16("day", ps, depth, &info->day))
1296                 return False;
1297         if(!prs_uint16("hour", ps, depth, &info->hour))
1298                 return False;
1299         if(!prs_uint16("minute", ps, depth, &info->minute))
1300                 return False;
1301         if(!prs_uint16("second", ps, depth, &info->second))
1302                 return False;
1303         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
1304                 return False;
1305
1306         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
1307                 return False;
1308         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
1309                 return False;
1310
1311         if(!prs_uint16("major_version", ps, depth, &info->major_version))
1312                 return False;
1313         if(!prs_uint16("build_version", ps, depth, &info->build_version))
1314                 return False;
1315         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
1316                 return False;
1317         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
1318                 return False;
1319         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
1320                 return False;
1321         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
1322                 return False;
1323         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
1324                 return False;
1325         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
1326                 return False;
1327         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
1328                 return False;
1329         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
1330                 return False;
1331         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
1332                 return False;
1333         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
1334                 return False;
1335         if(!prs_uint32("change_id", ps, depth, &info->change_id))
1336                 return False;
1337         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
1338                 return False;
1339         if(!prs_uint32("status"   , ps, depth, &info->status))
1340                 return False;
1341         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
1342                 return False;
1343         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
1344                 return False;
1345         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
1346                 return False;
1347         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
1348                 return False;
1349         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
1350                 return False;
1351         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
1352                 return False;
1353         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
1354                 return False;
1355         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
1356                 return False;
1357         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
1358                 return False;
1359         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
1360                 return False;
1361
1362         return True;
1363 }
1364
1365 /*******************************************************************
1366  Parse a PRINTER_INFO_1 structure.
1367 ********************************************************************/  
1368
1369 bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
1370 {
1371         prs_struct *ps=&buffer->prs;
1372
1373         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
1374         depth++;        
1375         
1376         buffer->struct_start=prs_offset(ps);
1377
1378         if (!prs_uint32("flags", ps, depth, &info->flags))
1379                 return False;
1380         if (!smb_io_relstr("description", buffer, depth, &info->description))
1381                 return False;
1382         if (!smb_io_relstr("name", buffer, depth, &info->name))
1383                 return False;
1384         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
1385                 return False;   
1386
1387         return True;
1388 }
1389
1390 /*******************************************************************
1391  Parse a PRINTER_INFO_2 structure.
1392 ********************************************************************/  
1393
1394 bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
1395 {
1396         prs_struct *ps=&buffer->prs;
1397         uint32 dm_offset, sd_offset, current_offset;
1398         uint32 dummy_value = 0, has_secdesc = 0;
1399
1400         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
1401         depth++;        
1402         
1403         buffer->struct_start=prs_offset(ps);
1404         
1405         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
1406                 return False;
1407         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1408                 return False;
1409         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
1410                 return False;
1411         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
1412                 return False;
1413         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
1414                 return False;
1415         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
1416                 return False;
1417         if (!smb_io_relstr("location", buffer, depth, &info->location))
1418                 return False;
1419
1420         /* save current offset and wind forwared by a uint32 */
1421         dm_offset = prs_offset(ps);
1422         if (!prs_uint32("devmode", ps, depth, &dummy_value))
1423                 return False;
1424         
1425         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
1426                 return False;
1427         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1428                 return False;
1429         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
1430                 return False;
1431         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
1432                 return False;
1433
1434         /* save current offset for the sec_desc */
1435         sd_offset = prs_offset(ps);
1436         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
1437                 return False;
1438
1439         
1440         /* save current location so we can pick back up here */
1441         current_offset = prs_offset(ps);
1442         
1443         /* parse the devmode */
1444         if (!prs_set_offset(ps, dm_offset))
1445                 return False;
1446         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1447                 return False;
1448         
1449         /* parse the sec_desc */
1450         if (info->secdesc) {
1451                 if (!prs_set_offset(ps, sd_offset))
1452                         return False;
1453                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
1454                         return False;
1455         }
1456
1457         /* pick up where we left off */
1458         if (!prs_set_offset(ps, current_offset))
1459                 return False;
1460
1461         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1462                 return False;
1463         if (!prs_uint32("priority", ps, depth, &info->priority))
1464                 return False;
1465         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
1466                 return False;
1467         if (!prs_uint32("starttime", ps, depth, &info->starttime))
1468                 return False;
1469         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
1470                 return False;
1471         if (!prs_uint32("status", ps, depth, &info->status))
1472                 return False;
1473         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
1474                 return False;
1475         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
1476                 return False;
1477
1478         return True;
1479 }
1480
1481 /*******************************************************************
1482  Parse a PRINTER_INFO_3 structure.
1483 ********************************************************************/  
1484
1485 bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
1486 {
1487         uint32 offset = 0;
1488         prs_struct *ps=&buffer->prs;
1489
1490         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
1491         depth++;        
1492         
1493         buffer->struct_start=prs_offset(ps);
1494         
1495         if (MARSHALLING(ps)) {
1496                 /* Ensure the SD is 8 byte aligned in the buffer. */
1497                 uint32 start = prs_offset(ps); /* Remember the start position. */
1498                 uint32 off_val = 0;
1499
1500                 /* Write a dummy value. */
1501                 if (!prs_uint32("offset", ps, depth, &off_val))
1502                         return False;
1503
1504                 /* 8 byte align. */
1505                 if (!prs_align_uint64(ps))
1506                         return False;
1507
1508                 /* Remember where we must seek back to write the SD. */
1509                 offset = prs_offset(ps);
1510
1511                 /* Calculate the real offset for the SD. */
1512
1513                 off_val = offset - start;
1514
1515                 /* Seek back to where we store the SD offset & store. */
1516                 prs_set_offset(ps, start);
1517                 if (!prs_uint32("offset", ps, depth, &off_val))
1518                         return False;
1519
1520                 /* Return to after the 8 byte align. */
1521                 prs_set_offset(ps, offset);
1522
1523         } else {
1524                 if (!prs_uint32("offset", ps, depth, &offset))
1525                         return False;
1526                 /* Seek within the buffer. */
1527                 if (!prs_set_offset(ps, offset))
1528                         return False;
1529         }
1530         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
1531                 return False;
1532
1533         return True;
1534 }
1535
1536 /*******************************************************************
1537  Parse a PRINTER_INFO_4 structure.
1538 ********************************************************************/  
1539
1540 bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
1541 {
1542         prs_struct *ps=&buffer->prs;
1543
1544         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
1545         depth++;        
1546         
1547         buffer->struct_start=prs_offset(ps);
1548         
1549         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1550                 return False;
1551         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
1552                 return False;
1553         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1554                 return False;
1555         return True;
1556 }
1557
1558 /*******************************************************************
1559  Parse a PRINTER_INFO_5 structure.
1560 ********************************************************************/  
1561
1562 bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
1563 {
1564         prs_struct *ps=&buffer->prs;
1565
1566         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
1567         depth++;        
1568         
1569         buffer->struct_start=prs_offset(ps);
1570         
1571         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1572                 return False;
1573         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
1574                 return False;
1575         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1576                 return False;
1577         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
1578                 return False;
1579         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
1580                 return False;
1581         return True;
1582 }
1583
1584 /*******************************************************************
1585  Parse a PRINTER_INFO_6 structure.
1586 ********************************************************************/  
1587
1588 bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
1589                            PRINTER_INFO_6 *info, int depth)
1590 {
1591         prs_struct *ps=&buffer->prs;
1592
1593         prs_debug(ps, depth, desc, "smb_io_printer_info_6");
1594         depth++;        
1595         
1596         if (!prs_uint32("status", ps, depth, &info->status))
1597                 return False;
1598
1599         return True;
1600 }
1601
1602 /*******************************************************************
1603  Parse a PRINTER_INFO_7 structure.
1604 ********************************************************************/  
1605
1606 bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
1607 {
1608         prs_struct *ps=&buffer->prs;
1609
1610         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
1611         depth++;        
1612         
1613         buffer->struct_start=prs_offset(ps);
1614         
1615         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
1616                 return False;
1617         if (!prs_uint32("action", ps, depth, &info->action))
1618                 return False;
1619         return True;
1620 }
1621
1622 /*******************************************************************
1623  Parse a PORT_INFO_1 structure.
1624 ********************************************************************/  
1625
1626 bool smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
1627 {
1628         prs_struct *ps=&buffer->prs;
1629
1630         prs_debug(ps, depth, desc, "smb_io_port_info_1");
1631         depth++;        
1632         
1633         buffer->struct_start=prs_offset(ps);
1634         
1635         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1636                 return False;
1637
1638         return True;
1639 }
1640
1641 /*******************************************************************
1642  Parse a PORT_INFO_2 structure.
1643 ********************************************************************/  
1644
1645 bool smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
1646 {
1647         prs_struct *ps=&buffer->prs;
1648
1649         prs_debug(ps, depth, desc, "smb_io_port_info_2");
1650         depth++;        
1651         
1652         buffer->struct_start=prs_offset(ps);
1653         
1654         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1655                 return False;
1656         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
1657                 return False;
1658         if (!smb_io_relstr("description", buffer, depth, &info->description))
1659                 return False;
1660         if (!prs_uint32("port_type", ps, depth, &info->port_type))
1661                 return False;
1662         if (!prs_uint32("reserved", ps, depth, &info->reserved))
1663                 return False;
1664
1665         return True;
1666 }
1667
1668 /*******************************************************************
1669  Parse a DRIVER_INFO_1 structure.
1670 ********************************************************************/
1671
1672 bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
1673 {
1674         prs_struct *ps=&buffer->prs;
1675
1676         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
1677         depth++;        
1678         
1679         buffer->struct_start=prs_offset(ps);
1680
1681         if (!smb_io_relstr("name", buffer, depth, &info->name))
1682                 return False;
1683
1684         return True;
1685 }
1686
1687 /*******************************************************************
1688  Parse a DRIVER_INFO_2 structure.
1689 ********************************************************************/
1690
1691 bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
1692 {
1693         prs_struct *ps=&buffer->prs;
1694
1695         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
1696         depth++;        
1697         
1698         buffer->struct_start=prs_offset(ps);
1699
1700         if (!prs_uint32("version", ps, depth, &info->version))
1701                 return False;
1702         if (!smb_io_relstr("name", buffer, depth, &info->name))
1703                 return False;
1704         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1705                 return False;
1706         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1707                 return False;
1708         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
1709                 return False;
1710         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
1711                 return False;
1712
1713         return True;
1714 }
1715
1716 /*******************************************************************
1717  Parse a DRIVER_INFO_3 structure.
1718 ********************************************************************/
1719
1720 bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
1721 {
1722         prs_struct *ps=&buffer->prs;
1723
1724         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
1725         depth++;        
1726         
1727         buffer->struct_start=prs_offset(ps);
1728
1729         if (!prs_uint32("version", ps, depth, &info->version))
1730                 return False;
1731         if (!smb_io_relstr("name", buffer, depth, &info->name))
1732                 return False;
1733         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1734                 return False;
1735         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1736                 return False;
1737         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
1738                 return False;
1739         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
1740                 return False;
1741         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
1742                 return False;
1743
1744         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
1745                 return False;
1746
1747         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
1748                 return False;
1749         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
1750                 return False;
1751
1752         return True;
1753 }
1754
1755 /*******************************************************************
1756  Parse a DRIVER_INFO_6 structure.
1757 ********************************************************************/
1758
1759 bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
1760 {
1761         prs_struct *ps=&buffer->prs;
1762
1763         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
1764         depth++;        
1765         
1766         buffer->struct_start=prs_offset(ps);
1767
1768         if (!prs_uint32("version", ps, depth, &info->version))
1769                 return False;
1770         if (!smb_io_relstr("name", buffer, depth, &info->name))
1771                 return False;
1772         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1773                 return False;
1774         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1775                 return False;
1776         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
1777                 return False;
1778         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
1779                 return False;
1780         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
1781                 return False;
1782
1783         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
1784                 return False;
1785
1786         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
1787                 return False;
1788         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
1789                 return False;
1790
1791         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
1792                 return False;
1793
1794         if (!prs_uint64("date", ps, depth, &info->driver_date))
1795                 return False;
1796
1797         if (!prs_uint32("padding", ps, depth, &info->padding))
1798                 return False;
1799
1800         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
1801                 return False;
1802
1803         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
1804                 return False;
1805
1806         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
1807                 return False;
1808         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
1809                 return False;
1810         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
1811                 return False;
1812         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
1813                 return False;
1814         
1815         return True;
1816 }
1817
1818 /*******************************************************************
1819  Parse a JOB_INFO_1 structure.
1820 ********************************************************************/  
1821
1822 bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
1823 {
1824         prs_struct *ps=&buffer->prs;
1825
1826         prs_debug(ps, depth, desc, "smb_io_job_info_1");
1827         depth++;        
1828         
1829         buffer->struct_start=prs_offset(ps);
1830
1831         if (!prs_uint32("jobid", ps, depth, &info->jobid))
1832                 return False;
1833         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1834                 return False;
1835         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
1836                 return False;
1837         if (!smb_io_relstr("username", buffer, depth, &info->username))
1838                 return False;
1839         if (!smb_io_relstr("document", buffer, depth, &info->document))
1840                 return False;
1841         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
1842                 return False;
1843         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
1844                 return False;
1845         if (!prs_uint32("status", ps, depth, &info->status))
1846                 return False;
1847         if (!prs_uint32("priority", ps, depth, &info->priority))
1848                 return False;
1849         if (!prs_uint32("position", ps, depth, &info->position))
1850                 return False;
1851         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
1852                 return False;
1853         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
1854                 return False;
1855         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
1856                 return False;
1857
1858         return True;
1859 }
1860
1861 /*******************************************************************
1862  Parse a JOB_INFO_2 structure.
1863 ********************************************************************/  
1864
1865 bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
1866 {       
1867         uint32 pipo=0;
1868         prs_struct *ps=&buffer->prs;
1869         
1870         prs_debug(ps, depth, desc, "smb_io_job_info_2");
1871         depth++;        
1872
1873         buffer->struct_start=prs_offset(ps);
1874         
1875         if (!prs_uint32("jobid",ps, depth, &info->jobid))
1876                 return False;
1877         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1878                 return False;
1879         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
1880                 return False;
1881         if (!smb_io_relstr("username", buffer, depth, &info->username))
1882                 return False;
1883         if (!smb_io_relstr("document", buffer, depth, &info->document))
1884                 return False;
1885         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
1886                 return False;
1887         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
1888                 return False;
1889
1890         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1891                 return False;
1892         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
1893                 return False;
1894         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
1895                 return False;
1896         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1897                 return False;
1898         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
1899                 return False;
1900
1901 /*      SEC_DESC sec_desc;*/
1902         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
1903                 return False;
1904
1905         if (!prs_uint32("status",ps, depth, &info->status))
1906                 return False;
1907         if (!prs_uint32("priority",ps, depth, &info->priority))
1908                 return False;
1909         if (!prs_uint32("position",ps, depth, &info->position)) 
1910                 return False;
1911         if (!prs_uint32("starttime",ps, depth, &info->starttime))
1912                 return False;
1913         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
1914                 return False;
1915         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
1916                 return False;
1917         if (!prs_uint32("size",ps, depth, &info->size))
1918                 return False;
1919         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
1920                 return False;
1921         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
1922                 return False;
1923         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
1924                 return False;
1925
1926         return True;
1927 }
1928
1929 /*******************************************************************
1930 ********************************************************************/  
1931
1932 bool smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
1933 {
1934         prs_struct *ps=&buffer->prs;
1935         
1936         prs_debug(ps, depth, desc, "smb_io_form_1");
1937         depth++;
1938                 
1939         buffer->struct_start=prs_offset(ps);
1940         
1941         if (!prs_uint32("flag", ps, depth, &info->flag))
1942                 return False;
1943                 
1944         if (!smb_io_relstr("name", buffer, depth, &info->name))
1945                 return False;
1946
1947         if (!prs_uint32("width", ps, depth, &info->width))
1948                 return False;
1949         if (!prs_uint32("length", ps, depth, &info->length))
1950                 return False;
1951         if (!prs_uint32("left", ps, depth, &info->left))
1952                 return False;
1953         if (!prs_uint32("top", ps, depth, &info->top))
1954                 return False;
1955         if (!prs_uint32("right", ps, depth, &info->right))
1956                 return False;
1957         if (!prs_uint32("bottom", ps, depth, &info->bottom))
1958                 return False;
1959
1960         return True;
1961 }
1962
1963 /*******************************************************************
1964  Parse a PORT_INFO_1 structure.
1965 ********************************************************************/  
1966
1967 bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
1968 {
1969         prs_struct *ps=&buffer->prs;
1970
1971         prs_debug(ps, depth, desc, "smb_io_port_1");
1972         depth++;
1973
1974         buffer->struct_start=prs_offset(ps);
1975
1976         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1977                 return False;
1978
1979         return True;
1980 }
1981
1982 /*******************************************************************
1983  Parse a PORT_INFO_2 structure.
1984 ********************************************************************/  
1985
1986 bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
1987 {
1988         prs_struct *ps=&buffer->prs;
1989
1990         prs_debug(ps, depth, desc, "smb_io_port_2");
1991         depth++;
1992
1993         buffer->struct_start=prs_offset(ps);
1994
1995         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1996                 return False;
1997         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
1998                 return False;
1999         if(!smb_io_relstr("description", buffer, depth, &info->description))
2000                 return False;
2001         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2002                 return False;
2003         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2004                 return False;
2005
2006         return True;
2007 }
2008
2009 /*******************************************************************
2010 ********************************************************************/  
2011
2012 bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2013 {
2014         prs_struct *ps=&buffer->prs;
2015
2016         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2017         depth++;        
2018
2019         buffer->struct_start=prs_offset(ps);
2020         
2021         if (smb_io_relstr("name", buffer, depth, &info->name))
2022                 return False;
2023
2024         return True;
2025 }
2026
2027 /*******************************************************************
2028 ********************************************************************/  
2029
2030 bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2031 {
2032         prs_struct *ps=&buffer->prs;
2033
2034         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2035         depth++;        
2036
2037         buffer->struct_start=prs_offset(ps);
2038         
2039         if (smb_io_relstr("name", buffer, depth, &info->name))
2040                 return False;
2041
2042         return True;
2043 }
2044
2045 /*******************************************************************
2046 ********************************************************************/  
2047
2048 bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2049 {
2050         prs_struct *ps=&buffer->prs;
2051
2052         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2053         depth++;        
2054
2055         buffer->struct_start=prs_offset(ps);
2056
2057         if (!smb_io_relstr("name", buffer, depth, &info->name))
2058                 return False;
2059
2060         return True;
2061 }
2062
2063 /*******************************************************************
2064 ********************************************************************/  
2065
2066 bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2067 {
2068         prs_struct *ps=&buffer->prs;
2069
2070         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2071         depth++;        
2072
2073         buffer->struct_start=prs_offset(ps);
2074
2075         if (!smb_io_relstr("name", buffer, depth, &info->name))
2076                 return False;
2077         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
2078                 return False;
2079         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2080                 return False;
2081
2082         return True;
2083 }
2084
2085 /*******************************************************************
2086 return the size required by a struct in the stream
2087 ********************************************************************/  
2088
2089 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2090 {
2091         int size=0;
2092         
2093         size+=size_of_relative_string( &info->printername );
2094         size+=size_of_relative_string( &info->servername );
2095
2096         size+=size_of_uint32( &info->cjobs);
2097         size+=size_of_uint32( &info->total_jobs);
2098         size+=size_of_uint32( &info->total_bytes);
2099
2100         size+=size_of_uint16( &info->year);
2101         size+=size_of_uint16( &info->month);
2102         size+=size_of_uint16( &info->dayofweek);
2103         size+=size_of_uint16( &info->day);
2104         size+=size_of_uint16( &info->hour);
2105         size+=size_of_uint16( &info->minute);
2106         size+=size_of_uint16( &info->second);
2107         size+=size_of_uint16( &info->milliseconds);
2108
2109         size+=size_of_uint32( &info->global_counter);
2110         size+=size_of_uint32( &info->total_pages);
2111
2112         size+=size_of_uint16( &info->major_version);
2113         size+=size_of_uint16( &info->build_version);
2114
2115         size+=size_of_uint32( &info->unknown7);
2116         size+=size_of_uint32( &info->unknown8);
2117         size+=size_of_uint32( &info->unknown9);
2118         size+=size_of_uint32( &info->session_counter);
2119         size+=size_of_uint32( &info->unknown11);
2120         size+=size_of_uint32( &info->printer_errors);
2121         size+=size_of_uint32( &info->unknown13);
2122         size+=size_of_uint32( &info->unknown14);
2123         size+=size_of_uint32( &info->unknown15);
2124         size+=size_of_uint32( &info->unknown16);
2125         size+=size_of_uint32( &info->change_id);
2126         size+=size_of_uint32( &info->unknown18);
2127         size+=size_of_uint32( &info->status);
2128         size+=size_of_uint32( &info->unknown20);
2129         size+=size_of_uint32( &info->c_setprinter);
2130         
2131         size+=size_of_uint16( &info->unknown22);
2132         size+=size_of_uint16( &info->unknown23);
2133         size+=size_of_uint16( &info->unknown24);
2134         size+=size_of_uint16( &info->unknown25);
2135         size+=size_of_uint16( &info->unknown26);
2136         size+=size_of_uint16( &info->unknown27);
2137         size+=size_of_uint16( &info->unknown28);
2138         size+=size_of_uint16( &info->unknown29);
2139         
2140         return size;
2141 }
2142
2143 /*******************************************************************
2144 return the size required by a struct in the stream
2145 ********************************************************************/  
2146
2147 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
2148 {
2149         int size=0;
2150                 
2151         size+=size_of_uint32( &info->flags );   
2152         size+=size_of_relative_string( &info->description );
2153         size+=size_of_relative_string( &info->name );
2154         size+=size_of_relative_string( &info->comment );
2155
2156         return size;
2157 }
2158
2159 /*******************************************************************
2160 return the size required by a struct in the stream
2161 ********************************************************************/
2162
2163 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
2164 {
2165         uint32 size=0;
2166                 
2167         size += 4;
2168         
2169         size += ndr_size_security_descriptor( info->secdesc, NULL, 0 );
2170
2171         size+=size_of_device_mode( info->devmode );
2172         
2173         size+=size_of_relative_string( &info->servername );
2174         size+=size_of_relative_string( &info->printername );
2175         size+=size_of_relative_string( &info->sharename );
2176         size+=size_of_relative_string( &info->portname );
2177         size+=size_of_relative_string( &info->drivername );
2178         size+=size_of_relative_string( &info->comment );
2179         size+=size_of_relative_string( &info->location );
2180         
2181         size+=size_of_relative_string( &info->sepfile );
2182         size+=size_of_relative_string( &info->printprocessor );
2183         size+=size_of_relative_string( &info->datatype );
2184         size+=size_of_relative_string( &info->parameters );
2185
2186         size+=size_of_uint32( &info->attributes );
2187         size+=size_of_uint32( &info->priority );
2188         size+=size_of_uint32( &info->defaultpriority );
2189         size+=size_of_uint32( &info->starttime );
2190         size+=size_of_uint32( &info->untiltime );
2191         size+=size_of_uint32( &info->status );
2192         size+=size_of_uint32( &info->cjobs );
2193         size+=size_of_uint32( &info->averageppm );      
2194                 
2195         /* 
2196          * add any adjustments for alignment.  This is
2197          * not optimal since we could be calling this
2198          * function from a loop (e.g. enumprinters), but 
2199          * it is easier to maintain the calculation here and
2200          * not place the burden on the caller to remember.   --jerry
2201          */
2202         if ((size % 4) != 0)
2203                 size += 4 - (size % 4);
2204         
2205         return size;
2206 }
2207
2208 /*******************************************************************
2209 return the size required by a struct in the stream
2210 ********************************************************************/
2211
2212 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
2213 {
2214         uint32 size=0;
2215                 
2216         size+=size_of_relative_string( &info->printername );
2217         size+=size_of_relative_string( &info->servername );
2218
2219         size+=size_of_uint32( &info->attributes );
2220         return size;
2221 }
2222
2223 /*******************************************************************
2224 return the size required by a struct in the stream
2225 ********************************************************************/
2226
2227 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
2228 {
2229         uint32 size=0;
2230                 
2231         size+=size_of_relative_string( &info->printername );
2232         size+=size_of_relative_string( &info->portname );
2233
2234         size+=size_of_uint32( &info->attributes );
2235         size+=size_of_uint32( &info->device_not_selected_timeout );
2236         size+=size_of_uint32( &info->transmission_retry_timeout );
2237         return size;
2238 }
2239
2240 /*******************************************************************
2241 return the size required by a struct in the stream
2242 ********************************************************************/
2243
2244 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
2245 {
2246         return sizeof(uint32);
2247 }
2248
2249 /*******************************************************************
2250 return the size required by a struct in the stream
2251 ********************************************************************/
2252
2253 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
2254 {
2255         /* The 8 is for the self relative pointer - 8 byte aligned.. */
2256         return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 );
2257 }
2258
2259 /*******************************************************************
2260 return the size required by a struct in the stream
2261 ********************************************************************/
2262
2263 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
2264 {
2265         uint32 size=0;
2266                 
2267         size+=size_of_relative_string( &info->guid );
2268         size+=size_of_uint32( &info->action );
2269         return size;
2270 }
2271
2272 /*******************************************************************
2273 return the size required by a struct in the stream
2274 ********************************************************************/
2275
2276 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
2277 {
2278         int size=0;
2279         size+=size_of_relative_string( &info->name );
2280
2281         return size;
2282 }
2283
2284 /*******************************************************************
2285 return the size required by a struct in the stream
2286 ********************************************************************/
2287
2288 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
2289 {
2290         int size=0;
2291         size+=size_of_uint32( &info->version ); 
2292         size+=size_of_relative_string( &info->name );
2293         size+=size_of_relative_string( &info->architecture );
2294         size+=size_of_relative_string( &info->driverpath );
2295         size+=size_of_relative_string( &info->datafile );
2296         size+=size_of_relative_string( &info->configfile );
2297
2298         return size;
2299 }
2300
2301 /*******************************************************************
2302 return the size required by a string array.
2303 ********************************************************************/
2304
2305 uint32 spoolss_size_string_array(uint16 *string)
2306 {
2307         uint32 i = 0;
2308
2309         if (string) {
2310                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
2311         }
2312         i=i+2; /* to count all chars including the leading zero */
2313         i=2*i; /* because we need the value in bytes */
2314         i=i+4; /* the offset pointer size */
2315
2316         return i;
2317 }
2318
2319 /*******************************************************************
2320 return the size required by a struct in the stream
2321 ********************************************************************/
2322
2323 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
2324 {
2325         int size=0;
2326
2327         size+=size_of_uint32( &info->version ); 
2328         size+=size_of_relative_string( &info->name );
2329         size+=size_of_relative_string( &info->architecture );
2330         size+=size_of_relative_string( &info->driverpath );
2331         size+=size_of_relative_string( &info->datafile );
2332         size+=size_of_relative_string( &info->configfile );
2333         size+=size_of_relative_string( &info->helpfile );
2334         size+=size_of_relative_string( &info->monitorname );
2335         size+=size_of_relative_string( &info->defaultdatatype );
2336         
2337         size+=spoolss_size_string_array(info->dependentfiles);
2338
2339         return size;
2340 }
2341
2342 /*******************************************************************
2343 return the size required by a struct in the stream
2344 ********************************************************************/
2345
2346 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
2347 {
2348         uint32 size=0;
2349
2350         size+=size_of_uint32( &info->version ); 
2351         size+=size_of_relative_string( &info->name );
2352         size+=size_of_relative_string( &info->architecture );
2353         size+=size_of_relative_string( &info->driverpath );
2354         size+=size_of_relative_string( &info->datafile );
2355         size+=size_of_relative_string( &info->configfile );
2356         size+=size_of_relative_string( &info->helpfile );
2357
2358         size+=spoolss_size_string_array(info->dependentfiles);
2359
2360         size+=size_of_relative_string( &info->monitorname );
2361         size+=size_of_relative_string( &info->defaultdatatype );
2362         
2363         size+=spoolss_size_string_array(info->previousdrivernames);
2364
2365         size+=size_of_nttime(&info->driver_date);
2366         size+=size_of_uint32( &info->padding ); 
2367         size+=size_of_uint32( &info->driver_version_low );      
2368         size+=size_of_uint32( &info->driver_version_high );     
2369         size+=size_of_relative_string( &info->mfgname );
2370         size+=size_of_relative_string( &info->oem_url );
2371         size+=size_of_relative_string( &info->hardware_id );
2372         size+=size_of_relative_string( &info->provider );
2373
2374         return size;
2375 }
2376
2377 /*******************************************************************
2378 return the size required by a struct in the stream
2379 ********************************************************************/  
2380
2381 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
2382 {
2383         int size=0;
2384         size+=size_of_uint32( &info->jobid );
2385         size+=size_of_relative_string( &info->printername );
2386         size+=size_of_relative_string( &info->machinename );
2387         size+=size_of_relative_string( &info->username );
2388         size+=size_of_relative_string( &info->document );
2389         size+=size_of_relative_string( &info->datatype );
2390         size+=size_of_relative_string( &info->text_status );
2391         size+=size_of_uint32( &info->status );
2392         size+=size_of_uint32( &info->priority );
2393         size+=size_of_uint32( &info->position );
2394         size+=size_of_uint32( &info->totalpages );
2395         size+=size_of_uint32( &info->pagesprinted );
2396         size+=size_of_systemtime( &info->submitted );
2397
2398         return size;
2399 }
2400
2401 /*******************************************************************
2402 return the size required by a struct in the stream
2403 ********************************************************************/  
2404
2405 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
2406 {
2407         int size=0;
2408
2409         size+=4; /* size of sec desc ptr */
2410
2411         size+=size_of_uint32( &info->jobid );
2412         size+=size_of_relative_string( &info->printername );
2413         size+=size_of_relative_string( &info->machinename );
2414         size+=size_of_relative_string( &info->username );
2415         size+=size_of_relative_string( &info->document );
2416         size+=size_of_relative_string( &info->notifyname );
2417         size+=size_of_relative_string( &info->datatype );
2418         size+=size_of_relative_string( &info->printprocessor );
2419         size+=size_of_relative_string( &info->parameters );
2420         size+=size_of_relative_string( &info->drivername );
2421         size+=size_of_device_mode( info->devmode );
2422         size+=size_of_relative_string( &info->text_status );
2423 /*      SEC_DESC sec_desc;*/
2424         size+=size_of_uint32( &info->status );
2425         size+=size_of_uint32( &info->priority );
2426         size+=size_of_uint32( &info->position );
2427         size+=size_of_uint32( &info->starttime );
2428         size+=size_of_uint32( &info->untiltime );
2429         size+=size_of_uint32( &info->totalpages );
2430         size+=size_of_uint32( &info->size );
2431         size+=size_of_systemtime( &info->submitted );
2432         size+=size_of_uint32( &info->timeelapsed );
2433         size+=size_of_uint32( &info->pagesprinted );
2434
2435         return size;
2436 }
2437
2438 /*******************************************************************
2439 return the size required by a struct in the stream
2440 ********************************************************************/
2441
2442 uint32 spoolss_size_form_1(FORM_1 *info)
2443 {
2444         int size=0;
2445
2446         size+=size_of_uint32( &info->flag );
2447         size+=size_of_relative_string( &info->name );
2448         size+=size_of_uint32( &info->width );
2449         size+=size_of_uint32( &info->length );
2450         size+=size_of_uint32( &info->left );
2451         size+=size_of_uint32( &info->top );
2452         size+=size_of_uint32( &info->right );
2453         size+=size_of_uint32( &info->bottom );
2454
2455         return size;
2456 }
2457
2458 /*******************************************************************
2459 return the size required by a struct in the stream
2460 ********************************************************************/  
2461
2462 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
2463 {
2464         int size=0;
2465
2466         size+=size_of_relative_string( &info->port_name );
2467
2468         return size;
2469 }
2470
2471 /*******************************************************************
2472 return the size required by a struct in the stream
2473 ********************************************************************/  
2474
2475 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
2476 {
2477         int size=0;
2478
2479         size+=size_of_relative_string( &info->port_name );
2480         size+=size_of_relative_string( &info->monitor_name );
2481         size+=size_of_relative_string( &info->description );
2482
2483         size+=size_of_uint32( &info->port_type );
2484         size+=size_of_uint32( &info->reserved );
2485
2486         return size;
2487 }
2488
2489 /*******************************************************************
2490 return the size required by a struct in the stream
2491 ********************************************************************/  
2492
2493 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
2494 {
2495         int size=0;
2496         size+=size_of_relative_string( &info->name );
2497
2498         return size;
2499 }
2500
2501 /*******************************************************************
2502 return the size required by a struct in the stream
2503 ********************************************************************/  
2504
2505 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
2506 {
2507         int size=0;
2508         size+=size_of_relative_string( &info->name );
2509
2510         return size;
2511 }
2512
2513 /*******************************************************************
2514 return the size required by a struct in the stream
2515 ********************************************************************/  
2516 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
2517 {
2518         uint32  size = 0; 
2519         
2520         if (!p)
2521                 return 0;
2522         
2523         /* uint32(offset) + uint32(length) + length) */
2524         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
2525         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
2526         
2527         size += size_of_uint32(&p->type);
2528                        
2529         return size;
2530 }
2531
2532 /*******************************************************************
2533 return the size required by a struct in the stream
2534 ********************************************************************/  
2535
2536 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
2537 {
2538         int size=0;
2539         size+=size_of_relative_string( &info->name );
2540
2541         return size;
2542 }
2543
2544 /*******************************************************************
2545 return the size required by a struct in the stream
2546 ********************************************************************/  
2547
2548 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
2549 {
2550         int size=0;
2551         size+=size_of_relative_string( &info->name);
2552         size+=size_of_relative_string( &info->environment);
2553         size+=size_of_relative_string( &info->dll_name);
2554
2555         return size;
2556 }
2557
2558 /*******************************************************************
2559  * init a structure.
2560  ********************************************************************/
2561
2562 bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
2563                                const POLICY_HND *hnd,
2564                                const fstring architecture,
2565                                uint32 level, uint32 clientmajor, uint32 clientminor,
2566                                RPC_BUFFER *buffer, uint32 offered)
2567 {      
2568         if (q_u == NULL)
2569                 return False;
2570
2571         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2572
2573         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
2574
2575         q_u->level=level;
2576         q_u->clientmajorversion=clientmajor;
2577         q_u->clientminorversion=clientminor;
2578
2579         q_u->buffer=buffer;
2580         q_u->offered=offered;
2581
2582         return True;
2583 }
2584
2585 /*******************************************************************
2586  * read a structure.
2587  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2588  ********************************************************************/
2589
2590 bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
2591 {
2592         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
2593         depth++;
2594
2595         if(!prs_align(ps))
2596                 return False;
2597         
2598         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2599                 return False;
2600         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
2601                 return False;
2602         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
2603                 return False;
2604         
2605         if(!prs_align(ps))
2606                 return False;
2607         if(!prs_uint32("level", ps, depth, &q_u->level))
2608                 return False;
2609                 
2610         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2611                 return False;
2612
2613         if(!prs_align(ps))
2614                 return False;
2615
2616         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2617                 return False;
2618                 
2619         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
2620                 return False;
2621         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
2622                 return False;
2623
2624         return True;
2625 }
2626
2627 /*******************************************************************
2628  * read a structure.
2629  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2630  ********************************************************************/
2631
2632 bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
2633 {
2634         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
2635         depth++;
2636
2637         if (!prs_align(ps))
2638                 return False;
2639                 
2640         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2641                 return False;
2642
2643         if (!prs_align(ps))
2644                 return False;
2645         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2646                 return False;
2647         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
2648                 return False;
2649         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
2650                 return False;           
2651         if (!prs_werror("status", ps, depth, &r_u->status))
2652                 return False;
2653
2654         return True;            
2655 }
2656
2657 /*******************************************************************
2658  * init a structure.
2659  ********************************************************************/
2660
2661 bool make_spoolss_q_enumprinters(
2662         SPOOL_Q_ENUMPRINTERS *q_u, 
2663         uint32 flags, 
2664         char *servername, 
2665         uint32 level, 
2666         RPC_BUFFER *buffer, 
2667         uint32 offered
2668 )
2669 {
2670         q_u->flags=flags;
2671         
2672         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
2673         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
2674
2675         q_u->level=level;
2676         q_u->buffer=buffer;
2677         q_u->offered=offered;
2678
2679         return True;
2680 }
2681
2682 /*******************************************************************
2683  * init a structure.
2684  ********************************************************************/
2685
2686 bool make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
2687                                 fstring servername, uint32 level, 
2688                                 RPC_BUFFER *buffer, uint32 offered)
2689 {
2690         q_u->name_ptr = (servername != NULL) ? 1 : 0;
2691         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
2692
2693         q_u->level=level;
2694         q_u->buffer=buffer;
2695         q_u->offered=offered;
2696
2697         return True;
2698 }
2699
2700 /*******************************************************************
2701  * read a structure.
2702  * called from spoolss_enumprinters (srv_spoolss.c)
2703  ********************************************************************/
2704
2705 bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
2706 {
2707         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
2708         depth++;
2709
2710         if (!prs_align(ps))
2711                 return False;
2712
2713         if (!prs_uint32("flags", ps, depth, &q_u->flags))
2714                 return False;
2715         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
2716                 return False;
2717
2718         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
2719                 return False;
2720                 
2721         if (!prs_align(ps))
2722                 return False;
2723         if (!prs_uint32("level", ps, depth, &q_u->level))
2724                 return False;
2725
2726         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2727                 return False;
2728
2729         if (!prs_align(ps))
2730                 return False;
2731         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2732                 return False;
2733
2734         return True;
2735 }
2736
2737 /*******************************************************************
2738  Parse a SPOOL_R_ENUMPRINTERS structure.
2739  ********************************************************************/
2740
2741 bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
2742 {
2743         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
2744         depth++;
2745
2746         if (!prs_align(ps))
2747                 return False;
2748                 
2749         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2750                 return False;
2751
2752         if (!prs_align(ps))
2753                 return False;
2754                 
2755         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2756                 return False;
2757                 
2758         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2759                 return False;
2760                 
2761         if (!prs_werror("status", ps, depth, &r_u->status))
2762                 return False;
2763
2764         return True;            
2765 }
2766
2767 /*******************************************************************
2768  * write a structure.
2769  * called from spoolss_r_enum_printers (srv_spoolss.c)
2770  *
2771  ********************************************************************/
2772
2773 bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
2774 {       
2775         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
2776         depth++;
2777
2778         if (!prs_align(ps))
2779                 return False;
2780                 
2781         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2782                 return False;
2783
2784         if (!prs_align(ps))
2785                 return False;
2786
2787         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2788                 return False;
2789                 
2790         if (!prs_werror("status", ps, depth, &r_u->status))
2791                 return False;
2792
2793         return True;            
2794 }
2795
2796 /*******************************************************************
2797  * read a structure.
2798  * called from spoolss_getprinter (srv_spoolss.c)
2799  ********************************************************************/
2800
2801 bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
2802 {
2803         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
2804         depth++;
2805
2806         if (!prs_align(ps))
2807                 return False;
2808
2809         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2810                 return False;
2811         if (!prs_uint32("level", ps, depth, &q_u->level))
2812                 return False;
2813
2814         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2815                 return False;
2816
2817         if (!prs_align(ps))
2818                 return False;
2819         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2820                 return False;
2821
2822         return True;
2823 }
2824
2825 /*******************************************************************
2826  * init a structure.
2827  ********************************************************************/
2828
2829 bool make_spoolss_q_getprinter(
2830         TALLOC_CTX *mem_ctx,
2831         SPOOL_Q_GETPRINTER *q_u, 
2832         const POLICY_HND *hnd, 
2833         uint32 level, 
2834         RPC_BUFFER *buffer, 
2835         uint32 offered
2836 )
2837 {
2838         if (q_u == NULL)
2839         {
2840                 return False;
2841         }
2842         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2843
2844         q_u->level=level;
2845         q_u->buffer=buffer;
2846         q_u->offered=offered;
2847
2848         return True;
2849 }
2850
2851 /*******************************************************************
2852  * init a structure.
2853  ********************************************************************/
2854 bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
2855                                 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
2856                                 uint32 command)
2857 {
2858         SEC_DESC *secdesc;
2859         DEVICEMODE *devmode;
2860
2861         if (!q_u || !info)
2862                 return False;
2863         
2864         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2865
2866         q_u->level = level;
2867         q_u->info.level = level;
2868         q_u->info.info_ptr = 1; /* Info is != NULL, see above */
2869         switch (level) {
2870
2871           /* There's no such thing as a setprinter level 1 */
2872
2873         case 2:
2874                 secdesc = info->printers_2->secdesc;
2875                 devmode = info->printers_2->devmode;
2876                 
2877                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
2878 #if 1   /* JERRY TEST */
2879                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
2880                 if (!q_u->secdesc_ctr)
2881                         return False;
2882                 q_u->secdesc_ctr->sd = secdesc;
2883                 q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
2884
2885                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
2886                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
2887                 q_u->devmode_ctr.devmode = devmode;
2888 #else
2889                 q_u->secdesc_ctr = NULL;
2890         
2891                 q_u->devmode_ctr.devmode_ptr = 0;
2892                 q_u->devmode_ctr.size = 0;
2893                 q_u->devmode_ctr.devmode = NULL;
2894 #endif
2895                 break;
2896         case 3:
2897                 secdesc = info->printers_3->secdesc;
2898                 
2899                 make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
2900                 
2901                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
2902                 if (!q_u->secdesc_ctr)
2903                         return False;
2904                 q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
2905                 q_u->secdesc_ctr->sd = secdesc;
2906
2907                 break;
2908         case 7:
2909                 make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
2910                 break;
2911
2912         default: 
2913                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
2914                         break;
2915         }
2916
2917         
2918         q_u->command = command;
2919
2920         return True;
2921 }
2922
2923
2924 /*******************************************************************
2925 ********************************************************************/  
2926
2927 bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
2928 {               
2929         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
2930         depth++;
2931
2932         if(!prs_align(ps))
2933                 return False;
2934         
2935         if(!prs_werror("status", ps, depth, &r_u->status))
2936                 return False;
2937
2938         return True;
2939 }
2940
2941 /*******************************************************************
2942  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
2943 ********************************************************************/  
2944
2945 bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
2946 {
2947         uint32 ptr_sec_desc = 0;
2948
2949         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
2950         depth++;
2951
2952         if(!prs_align(ps))
2953                 return False;
2954
2955         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
2956                 return False;
2957         if(!prs_uint32("level", ps, depth, &q_u->level))
2958                 return False;
2959         
2960         /* check for supported levels and structures we know about */
2961                 
2962         switch ( q_u->level ) {
2963                 case 0:
2964                 case 2:
2965                 case 3:
2966                 case 7:
2967                         /* supported levels */
2968                         break;
2969                 default:
2970                         DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
2971                                 q_u->level));
2972                         return True;
2973         }
2974                         
2975
2976         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
2977                 return False;
2978
2979         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
2980                 return False;
2981         
2982         if(!prs_align(ps))
2983                 return False;
2984
2985         switch (q_u->level)
2986         {
2987                 case 2:
2988                 {
2989                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
2990                         break;
2991                 }
2992                 case 3:
2993                 {
2994                         /* FIXME ! Our parsing here is wrong I think,
2995                          * but for a level3 it makes no sense for
2996                          * ptr_sec_desc to be NULL. JRA. Based on
2997                          * a Vista sniff from Martin Zielinski <mz@seh.de>.
2998                          */
2999                         if (UNMARSHALLING(ps)) {
3000                                 ptr_sec_desc = 1;
3001                         } else {
3002                                 ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3003                         }
3004                         break;
3005                 }
3006         }
3007         if (ptr_sec_desc)
3008         {
3009                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3010                         return False;
3011         } else {
3012                 uint32 dummy = 0;
3013
3014                 /* Parse a NULL security descriptor.  This should really
3015                    happen inside the sec_io_desc_buf() function. */
3016
3017                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3018                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3019                         return False;
3020                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3021                         return False;
3022         }
3023         
3024         if(!prs_uint32("command", ps, depth, &q_u->command))
3025                 return False;
3026
3027         return True;
3028 }
3029
3030 /*******************************************************************
3031 ********************************************************************/  
3032
3033 bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
3034 {               
3035         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
3036         depth++;
3037
3038         if (!prs_align(ps))
3039                 return False;
3040                 
3041         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3042                 return False;
3043
3044         if (!prs_align(ps))
3045                 return False;
3046                 
3047         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3048                 return False;
3049                 
3050         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3051                 return False;
3052                 
3053         if (!prs_werror("status", ps, depth, &r_u->status))
3054                 return False;
3055
3056         return True;            
3057 }
3058
3059 /*******************************************************************
3060 ********************************************************************/  
3061
3062 bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
3063                                 uint32 firstjob,
3064                                 uint32 numofjobs,
3065                                 uint32 level,
3066                                 RPC_BUFFER *buffer,
3067                                 uint32 offered)
3068 {
3069         if (q_u == NULL)
3070         {
3071                 return False;
3072         }
3073         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3074         q_u->firstjob = firstjob;
3075         q_u->numofjobs = numofjobs;
3076         q_u->level = level;
3077         q_u->buffer= buffer;
3078         q_u->offered = offered;
3079         return True;
3080 }
3081
3082 /*******************************************************************
3083 ********************************************************************/  
3084
3085 bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
3086 {
3087         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
3088         depth++;
3089
3090         if (!prs_align(ps))
3091                 return False;
3092
3093         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
3094                 return False;
3095                 
3096         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
3097                 return False;
3098         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
3099                 return False;
3100         if (!prs_uint32("level", ps, depth, &q_u->level))
3101                 return False;
3102
3103         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3104                 return False;   
3105
3106         if(!prs_align(ps))
3107                 return False;
3108
3109         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3110                 return False;
3111
3112         return True;
3113 }
3114
3115 /*******************************************************************
3116  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
3117 ********************************************************************/  
3118
3119 bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
3120 {
3121         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
3122         depth++;
3123
3124         if (!prs_align(ps))
3125                 return False;
3126                 
3127         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3128                 return False;
3129
3130         if (!prs_align(ps))
3131                 return False;
3132                 
3133         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3134                 return False;
3135                 
3136         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3137                 return False;
3138                 
3139         if (!prs_werror("status", ps, depth, &r_u->status))
3140                 return False;
3141
3142         return True;            
3143 }
3144
3145 /*******************************************************************
3146  * init a structure.
3147  ********************************************************************/
3148
3149 bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
3150                                 const char *name,
3151                                 const char *environment,
3152                                 uint32 level,
3153                                 RPC_BUFFER *buffer, uint32 offered)
3154 {
3155         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
3156         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
3157
3158         q_u->level=level;
3159         q_u->buffer=buffer;
3160         q_u->offered=offered;
3161
3162         return True;
3163 }
3164
3165 /*******************************************************************
3166  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
3167 ********************************************************************/  
3168
3169 bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
3170 {
3171
3172         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
3173         depth++;
3174
3175         if (!prs_align(ps))
3176                 return False;
3177                 
3178         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3179                 return False;
3180         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
3181                 return False;
3182                 
3183         if (!prs_align(ps))
3184                 return False;
3185         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
3186                 return False;
3187         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3188                 return False;
3189                 
3190         if (!prs_align(ps))
3191                 return False;
3192         if (!prs_uint32("level", ps, depth, &q_u->level))
3193                 return False;
3194                 
3195         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3196                 return False;
3197
3198         if (!prs_align(ps))
3199                 return False;
3200                 
3201         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3202                 return False;
3203
3204         return True;
3205 }
3206
3207 /*******************************************************************
3208 ********************************************************************/  
3209
3210 bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
3211 {
3212
3213         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
3214         depth++;
3215
3216         if (!prs_align(ps))
3217                 return False;                   
3218         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3219                 return False;           
3220         if (!prs_uint32("level", ps, depth, &q_u->level))
3221                 return False;   
3222         
3223         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3224                 return False;
3225
3226         if (!prs_align(ps))
3227                 return False;
3228         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3229                 return False;
3230
3231         return True;
3232 }
3233
3234 /*******************************************************************
3235 ********************************************************************/  
3236
3237 bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
3238 {
3239         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
3240         depth++;
3241
3242         if (!prs_align(ps))
3243                 return False;
3244                 
3245         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3246                 return False;
3247
3248         if (!prs_align(ps))
3249                 return False;
3250                 
3251         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
3252                 return False;
3253                 
3254         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
3255                 return False;
3256                 
3257         if (!prs_werror("status", ps, depth, &r_u->status))
3258                 return False;
3259
3260         return True;
3261 }
3262
3263 /*******************************************************************
3264  Parse a SPOOL_R_ENUMPORTS structure.
3265 ********************************************************************/  
3266
3267 bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
3268 {
3269         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
3270         depth++;
3271
3272         if (!prs_align(ps))
3273                 return False;
3274                 
3275         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3276                 return False;
3277
3278         if (!prs_align(ps))
3279                 return False;
3280                 
3281         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3282                 return False;
3283                 
3284         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3285                 return False;
3286                 
3287         if (!prs_werror("status", ps, depth, &r_u->status))
3288                 return False;
3289
3290         return True;            
3291 }
3292
3293 /*******************************************************************
3294 ********************************************************************/  
3295
3296 bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
3297 {
3298         prs_debug(ps, depth, desc, "");
3299         depth++;
3300
3301         if (!prs_align(ps))
3302                 return False;
3303
3304         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
3305                 return False;
3306         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
3307                 return False;
3308
3309         if (!prs_align(ps))
3310                 return False;
3311         if (!prs_uint32("level", ps, depth, &q_u->level))
3312                 return False;
3313                 
3314         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3315                 return False;
3316
3317         if (!prs_align(ps))
3318                 return False;
3319         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3320                 return False;
3321
3322         return True;
3323 }
3324
3325 /*******************************************************************
3326  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
3327 ********************************************************************/  
3328
3329 bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
3330 {       
3331         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
3332         depth++;
3333                 
3334         if(!prs_align(ps))
3335                 return False;
3336
3337         if(!prs_uint32("flags", ps, depth, &il->flags))
3338                 return False;
3339         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
3340                 return False;
3341         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
3342                 return False;
3343         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3344                 return False;
3345                 
3346         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
3347                 return False;
3348         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3349                 return False;
3350         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3351                 return False;
3352
3353         return True;
3354 }
3355
3356 /*******************************************************************
3357  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
3358 ********************************************************************/  
3359
3360 bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
3361 {       
3362         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
3363         depth++;
3364                 
3365         if(!prs_align(ps))
3366                 return False;
3367
3368         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
3369                 return False;
3370
3371         return True;
3372 }
3373
3374 /*******************************************************************
3375  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
3376 ********************************************************************/  
3377
3378 bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
3379 {       
3380         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
3381         depth++;
3382                 
3383         if(!prs_align(ps))
3384                 return False;
3385
3386         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
3387                 return False;
3388         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
3389                 return False;
3390         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
3391                 return False;
3392         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
3393                 return False;
3394
3395         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
3396                 return False;
3397         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3398                 return False;
3399         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
3400                 return False;
3401         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
3402                 return False;
3403         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
3404                 return False;
3405         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
3406                 return False;
3407         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
3408                 return False;
3409         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
3410                 return False;
3411         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
3412                 return False;
3413
3414         if(!prs_uint32("attributes", ps, depth, &il->attributes))
3415                 return False;
3416         if(!prs_uint32("priority", ps, depth, &il->priority))
3417                 return False;
3418         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
3419                 return False;
3420         if(!prs_uint32("starttime", ps, depth, &il->starttime))
3421                 return False;
3422         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
3423                 return False;
3424         if(!prs_uint32("status", ps, depth, &il->status))
3425                 return False;
3426         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
3427                 return False;
3428         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
3429                 return False;
3430
3431         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
3432                 return False;
3433         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
3434                 return False;
3435         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
3436                 return False;
3437         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
3438                 return False;
3439         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
3440                 return False;
3441         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3442                 return False;
3443         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
3444                 return False;
3445         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
3446                 return False;
3447         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
3448                 return False;
3449         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
3450                 return False;
3451         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
3452                 return False;
3453
3454         return True;
3455 }
3456
3457 bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
3458 {       
3459         prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
3460         depth++;
3461                 
3462         if(!prs_align(ps))
3463                 return False;
3464
3465         if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
3466                 return False;
3467         if(!prs_uint32("action", ps, depth, &il->action))
3468                 return False;
3469
3470         if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
3471                 return False;
3472         return True;
3473 }
3474
3475 /*******************************************************************
3476 ********************************************************************/  
3477
3478 bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
3479 {
3480         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
3481         depth++;
3482
3483         if(!prs_align(ps))
3484                 return False;
3485         if(!prs_uint32("level", ps, depth, &il->level))
3486                 return False;
3487         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
3488                 return False;
3489         
3490         /* if no struct inside just return */
3491         if (il->info_ptr==0) {
3492                 if (UNMARSHALLING(ps)) {
3493                         il->info_1=NULL;
3494                         il->info_2=NULL;
3495                 }
3496                 return True;
3497         }
3498                         
3499         switch (il->level) {
3500                 /*
3501                  * level 0 is used by setprinter when managing the queue
3502                  * (hold, stop, start a queue)
3503                  */
3504                 case 0:
3505                         break;
3506                 /* DOCUMENT ME!!! What is level 1 used for? */
3507                 case 1:
3508                 {
3509                         if (UNMARSHALLING(ps)) {
3510                                 if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
3511                                         return False;
3512                         }
3513                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
3514                                 return False;
3515                         break;          
3516                 }
3517                 /* 
3518                  * level 2 is used by addprinter
3519                  * and by setprinter when updating printer's info
3520                  */     
3521                 case 2:
3522                         if (UNMARSHALLING(ps)) {
3523                                 if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
3524                                         return False;
3525                         }
3526                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
3527                                 return False;
3528                         break;          
3529                 /* DOCUMENT ME!!! What is level 3 used for? */
3530                 case 3:
3531                 {
3532                         if (UNMARSHALLING(ps)) {
3533                                 if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
3534                                         return False;
3535                         }
3536                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
3537                                 return False;
3538                         break;          
3539                 }
3540                 case 7:
3541                         if (UNMARSHALLING(ps))
3542                                 if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
3543                                         return False;
3544                         if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
3545                                 return False;
3546                         break;
3547         }
3548
3549         return True;
3550 }
3551
3552 /*******************************************************************
3553 ********************************************************************/  
3554
3555 bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
3556 {
3557         uint32 ptr_sec_desc = 0;
3558
3559         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
3560         depth++;
3561
3562         if(!prs_align(ps))
3563                 return False;
3564
3565         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
3566                 return False;
3567         if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
3568                 return False;
3569
3570         if(!prs_align(ps))
3571                 return False;
3572
3573         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3574                 return False;
3575         
3576         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3577                 return False;
3578         
3579         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3580                 return False;
3581
3582         if(!prs_align(ps))
3583                 return False;
3584
3585         switch (q_u->level) {
3586                 case 2:
3587                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3588                         break;
3589                 case 3:
3590                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3591                         break;
3592         }
3593         if (ptr_sec_desc) {
3594                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3595                         return False;
3596         } else {
3597                 uint32 dummy = 0;
3598
3599                 /* Parse a NULL security descriptor.  This should really
3600                         happen inside the sec_io_desc_buf() function. */
3601
3602                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3603                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3604                         return False;
3605                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3606                         return False;
3607         }
3608
3609         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
3610                 return False;
3611         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
3612                 return False;
3613
3614         return True;
3615 }
3616
3617 /*******************************************************************
3618 ********************************************************************/  
3619
3620 bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
3621                                prs_struct *ps, int depth)
3622 {
3623         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
3624         depth++;
3625         
3626         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
3627                 return False;
3628
3629         if(!prs_werror("status", ps, depth, &r_u->status))
3630                 return False;
3631
3632         return True;
3633 }
3634
3635 /*******************************************************************
3636 ********************************************************************/  
3637
3638 bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
3639                                           prs_struct *ps, int depth)
3640 {       
3641         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
3642         
3643         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
3644         depth++;
3645                 
3646         /* reading */
3647         if (UNMARSHALLING(ps)) {
3648                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
3649                 if(il == NULL)
3650                         return False;
3651                 *q_u=il;
3652         }
3653         else {
3654                 il=*q_u;
3655         }
3656         
3657         if(!prs_align(ps))
3658                 return False;
3659
3660         if(!prs_uint32("cversion", ps, depth, &il->cversion))
3661                 return False;
3662         if(!prs_uint32("name", ps, depth, &il->name_ptr))
3663                 return False;
3664         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
3665                 return False;
3666         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
3667                 return False;
3668         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
3669                 return False;
3670         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
3671                 return False;
3672         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
3673                 return False;
3674         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
3675                 return False;
3676         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3677                 return False;
3678         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
3679                 return False;
3680         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
3681                 return False;
3682
3683         if(!prs_align(ps))
3684                 return False;
3685         
3686         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3687                 return False;
3688         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
3689                 return False;
3690         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
3691                 return False;
3692         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
3693                 return False;
3694         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
3695                 return False;
3696         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
3697                 return False;
3698         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
3699                 return False;
3700         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
3701                 return False;
3702
3703         if(!prs_align(ps))
3704                 return False;
3705                 
3706         if (il->dependentfiles_ptr)
3707                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
3708
3709         return True;
3710 }
3711
3712 /*******************************************************************
3713 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
3714 ********************************************************************/  
3715
3716 bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
3717                                           prs_struct *ps, int depth)
3718 {       
3719         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
3720         
3721         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
3722         depth++;
3723                 
3724         /* reading */
3725         if (UNMARSHALLING(ps)) {
3726                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
3727                 if(il == NULL)
3728                         return False;
3729                 *q_u=il;
3730         }
3731         else {
3732                 il=*q_u;
3733         }
3734         
3735         if(!prs_align(ps))
3736                 return False;
3737
3738         /* 
3739          * I know this seems weird, but I have no other explanation.
3740          * This is observed behavior on both NT4 and 2K servers.
3741          * --jerry
3742          */
3743          
3744         if (!prs_align_uint64(ps))
3745                 return False;
3746
3747         /* parse the main elements the packet */
3748
3749         if(!prs_uint32("cversion       ", ps, depth, &il->version))
3750                 return False;
3751         if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
3752                 return False;
3753         if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
3754                 return False;
3755         if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
3756                 return False;
3757         if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
3758                 return False;
3759         if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
3760                 return False;
3761         if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
3762                 return False;
3763         if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
3764                 return False;
3765         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3766                 return False;
3767         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
3768                 return False;
3769         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
3770                 return False;
3771         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
3772                 return False;
3773         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
3774                 return False;
3775         if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
3776                 return False;
3777         if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
3778                 return False;
3779         if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
3780                 return False;
3781         if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
3782                 return False;
3783         if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
3784                 return False;
3785         if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
3786                 return False;
3787         if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
3788                 return False;
3789
3790         /* parse the structures in the packet */
3791
3792         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3793                 return False;
3794         if(!prs_align(ps))
3795                 return False;
3796
3797         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
3798                 return False;
3799         if(!prs_align(ps))
3800                 return False;
3801
3802         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
3803                 return False;
3804         if(!prs_align(ps))
3805                 return False;
3806
3807         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
3808                 return False;
3809         if(!prs_align(ps))
3810                 return False;
3811
3812         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
3813                 return False;
3814         if(!prs_align(ps))
3815                 return False;
3816
3817         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
3818                 return False;
3819         if(!prs_align(ps))
3820                 return False;
3821
3822         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
3823                 return False;
3824         if(!prs_align(ps))
3825                 return False;
3826
3827         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
3828                 return False;
3829         if(!prs_align(ps))
3830                 return False;
3831         if (il->dependentfiles_ptr) {
3832                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
3833                         return False;
3834                 if(!prs_align(ps))
3835                         return False;
3836         }
3837         if (il->previousnames_ptr) {
3838                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
3839                         return False;
3840                 if(!prs_align(ps))
3841                         return False;
3842         }
3843         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
3844                 return False;
3845         if(!prs_align(ps))
3846                 return False;
3847         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
3848                 return False;
3849         if(!prs_align(ps))
3850                 return False;
3851         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
3852                 return False;
3853         if(!prs_align(ps))
3854                 return False;
3855         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
3856                 return False;
3857
3858         return True;
3859 }
3860
3861 /*******************************************************************
3862  read a UNICODE array with null terminated strings 
3863  and null terminated array 
3864  and size of array at beginning
3865 ********************************************************************/  
3866
3867 bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
3868 {
3869         if (buffer==NULL) return False;
3870
3871         buffer->offset=0;
3872         buffer->uni_str_len=buffer->uni_max_len;
3873         
3874         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
3875                 return False;
3876
3877         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
3878                 return False;
3879
3880         return True;
3881 }
3882
3883 /*******************************************************************
3884 ********************************************************************/  
3885
3886 bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
3887 {
3888         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
3889         depth++;
3890
3891         if(!prs_align(ps))
3892                 return False;
3893         if(!prs_uint32("level", ps, depth, &il->level))
3894                 return False;
3895         if(!prs_uint32("ptr", ps, depth, &il->ptr))
3896                 return False;
3897
3898         if (il->ptr==0)
3899                 return True;
3900                 
3901         switch (il->level) {
3902                 case 3:
3903                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
3904                                 return False;
3905                         break;          
3906                 case 6:
3907                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
3908                                 return False;
3909                         break;          
3910         default:
3911                 return False;
3912         }
3913
3914         return True;
3915 }
3916
3917 /*******************************************************************
3918  init a SPOOL_Q_ADDPRINTERDRIVER struct
3919  ******************************************************************/
3920
3921 bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
3922                                 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
3923                                 uint32 level, PRINTER_DRIVER_CTR *info)
3924 {
3925         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
3926         
3927         if (!srv_name || !info) {
3928                 return False;
3929         }
3930
3931         q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */
3932         init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
3933         
3934         q_u->level = level;
3935         
3936         q_u->info.level = level;
3937         q_u->info.ptr = 1;      /* Info is != NULL, see above */
3938         switch (level)
3939         {
3940         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
3941         case 3 :
3942                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
3943                 break;
3944                 
3945         default:
3946                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
3947                 break;
3948         }
3949         
3950         return True;
3951 }
3952
3953 bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
3954         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
3955                                 DRIVER_INFO_3 *info3)
3956 {
3957         uint32          len = 0;
3958         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
3959
3960         if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
3961                 return False;
3962
3963         inf->cversion   = info3->version;
3964         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
3965         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
3966         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
3967         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
3968         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
3969         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
3970         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
3971         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
3972
3973         init_unistr2_from_unistr(inf, &inf->name, &info3->name);
3974         init_unistr2_from_unistr(inf, &inf->environment, &info3->architecture);
3975         init_unistr2_from_unistr(inf, &inf->driverpath, &info3->driverpath);
3976         init_unistr2_from_unistr(inf, &inf->datafile, &info3->datafile);
3977         init_unistr2_from_unistr(inf, &inf->configfile, &info3->configfile);
3978         init_unistr2_from_unistr(inf, &inf->helpfile, &info3->helpfile);
3979         init_unistr2_from_unistr(inf, &inf->monitorname, &info3->monitorname);
3980         init_unistr2_from_unistr(inf, &inf->defaultdatatype, &info3->defaultdatatype);
3981
3982         if (info3->dependentfiles) {
3983                 bool done = False;
3984                 bool null_char = False;
3985                 uint16 *ptr = info3->dependentfiles;
3986
3987                 while (!done) {
3988                         switch (*ptr) {
3989                                 case 0:
3990                                         /* the null_char bool is used to help locate
3991                                            two '\0's back to back */
3992                                         if (null_char) {
3993                                                 done = True;
3994                                         } else {
3995                                                 null_char = True;
3996                                         }
3997                                         break;
3998                                         
3999                                 default:
4000                                         null_char = False;
4001                                         break;                          
4002                         }
4003                         len++;
4004                         ptr++;
4005                 }
4006         }
4007
4008         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
4009         inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0;
4010         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) {
4011                 SAFE_FREE(inf);
4012                 return False;
4013         }
4014         
4015         *spool_drv_info = inf;
4016         
4017         return True;
4018 }
4019
4020 /*******************************************************************
4021  make a BUFFER5 struct from a uint16*
4022  ******************************************************************/
4023
4024 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
4025 {
4026
4027         buf5->buf_len = len;
4028         if (src) {
4029                 if (len) {
4030                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
4031                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
4032                                 return False;
4033                         }
4034                 } else {
4035                         buf5->buffer = NULL;
4036                 }
4037         } else {
4038                 buf5->buffer=NULL;
4039         }
4040         
4041         return True;
4042 }
4043
4044 /*******************************************************************
4045  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
4046  ********************************************************************/  
4047
4048 bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
4049 {
4050         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
4051         depth++;
4052
4053         if(!prs_align(ps))
4054                 return False;
4055
4056         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
4057                 return False;
4058         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4059                 return False;
4060                 
4061         if(!prs_align(ps))
4062                 return False;
4063         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4064                 return False;
4065
4066         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
4067                 return False;
4068
4069         return True;
4070 }
4071
4072 /*******************************************************************
4073 ********************************************************************/  
4074
4075 bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
4076 {
4077         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
4078         depth++;
4079
4080         if(!prs_werror("status", ps, depth, &q_u->status))
4081                 return False;
4082
4083         return True;
4084 }
4085
4086 /*******************************************************************
4087  ********************************************************************/  
4088
4089 bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
4090                               NT_PRINTER_INFO_LEVEL_2  *d)
4091 {
4092         DEBUG(7,("Converting from UNICODE to ASCII\n"));
4093         
4094         d->attributes=uni->attributes;
4095         d->priority=uni->priority;
4096         d->default_priority=uni->default_priority;
4097         d->starttime=uni->starttime;
4098         d->untiltime=uni->untiltime;
4099         d->status=uni->status;
4100         d->cjobs=uni->cjobs;
4101         
4102         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername));
4103         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername));
4104         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename));
4105         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname));
4106         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername));
4107         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment));
4108         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location));
4109         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile));
4110         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor));
4111         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype));
4112         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters));
4113
4114         return True;
4115 }
4116
4117 /*******************************************************************
4118 ********************************************************************/  
4119
4120 bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
4121 {               
4122         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
4123         depth++;
4124
4125         if (!prs_align(ps))
4126                 return False;
4127                 
4128         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4129                 return False;
4130
4131         if (!prs_align(ps))
4132                 return False;
4133                 
4134         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4135                 return False;
4136                 
4137         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4138                 return False;
4139                 
4140         if (!prs_werror("status", ps, depth, &r_u->status))
4141                 return False;
4142
4143         return True;            
4144 }
4145
4146 /*******************************************************************
4147 ********************************************************************/  
4148
4149 bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
4150 {
4151         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
4152         depth++;
4153
4154         if (!prs_align(ps))
4155                 return False;
4156                 
4157         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4158                 return False;
4159         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4160                 return False;
4161                 
4162         if (!prs_align(ps))
4163                 return False;
4164                 
4165         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
4166                 return False;
4167         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4168                 return False;
4169         
4170         if (!prs_align(ps))
4171                 return False;
4172                 
4173         if (!prs_uint32("level", ps, depth, &q_u->level))
4174                 return False;
4175                 
4176         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4177                 return False;
4178
4179         if (!prs_align(ps))
4180                 return False;
4181
4182         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4183                 return False;
4184
4185         return True;
4186 }
4187
4188 /*******************************************************************
4189 ********************************************************************/  
4190
4191 bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
4192 {               
4193         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
4194         depth++;
4195
4196         if (!prs_align(ps))
4197                 return False;
4198                 
4199         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4200                 return False;
4201
4202         if (!prs_align(ps))
4203                 return False;
4204                 
4205         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4206                 return False;
4207                 
4208         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4209                 return False;
4210                 
4211         if (!prs_werror("status", ps, depth, &r_u->status))
4212                 return False;
4213
4214         return True;            
4215 }
4216
4217 /*******************************************************************
4218 ********************************************************************/  
4219
4220 bool spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
4221 {
4222         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
4223         depth++;
4224
4225         if (!prs_align(ps))
4226                 return False;
4227                 
4228         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4229                 return False;
4230         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4231                 return False;
4232                 
4233         if (!prs_align(ps))
4234                 return False;
4235                 
4236         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
4237                 return False;
4238         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
4239                 return False;
4240         
4241         if (!prs_align(ps))
4242                 return False;
4243                 
4244         if (!prs_uint32("level", ps, depth, &q_u->level))
4245                 return False;
4246                 
4247         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
4248                 return False;
4249
4250         if (!prs_align(ps))
4251                 return False;
4252
4253         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4254                 return False;
4255
4256         return True;
4257 }
4258
4259 /*******************************************************************
4260  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
4261 ********************************************************************/  
4262
4263 bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
4264 {
4265         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
4266         depth++;
4267
4268         if (!prs_align(ps))
4269                 return False;
4270                 
4271         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4272                 return False;
4273         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4274                 return False;
4275                 
4276         if (!prs_align(ps))
4277                 return False;
4278                                 
4279         if (!prs_uint32("level", ps, depth, &q_u->level))
4280                 return False;
4281                 
4282         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4283                 return False;
4284
4285         if (!prs_align(ps))
4286                 return False;
4287
4288         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4289                 return False;
4290
4291         return True;
4292 }
4293
4294 /*******************************************************************
4295 ********************************************************************/  
4296
4297 bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
4298 {               
4299         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
4300         depth++;
4301
4302         if (!prs_align(ps))
4303                 return False;
4304                 
4305         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4306                 return False;
4307
4308         if (!prs_align(ps))
4309                 return False;
4310                 
4311         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4312                 return False;
4313                 
4314         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4315                 return False;
4316                 
4317         if (!prs_werror("status", ps, depth, &r_u->status))
4318                 return False;
4319
4320         return True;            
4321 }
4322
4323 /*******************************************************************
4324 ********************************************************************/  
4325
4326 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
4327 {       
4328         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
4329         depth++;
4330
4331         if(!prs_align(ps))
4332                 return False;
4333         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
4334                 return False;
4335
4336         if (UNMARSHALLING(ps) && r_u->valuesize) {
4337                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
4338                 if (!r_u->value) {
4339                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
4340                         return False;
4341                 }
4342         }
4343
4344         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
4345                 return False;
4346
4347         if(!prs_align(ps))
4348                 return False;
4349
4350         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
4351                 return False;
4352
4353         if(!prs_uint32("type", ps, depth, &r_u->type))
4354                 return False;
4355
4356         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
4357                 return False;
4358
4359         if (UNMARSHALLING(ps) && r_u->datasize) {
4360                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
4361                 if (!r_u->data) {
4362                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
4363                         return False;
4364                 }
4365         }
4366
4367         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
4368                 return False;
4369         if(!prs_align(ps))
4370                 return False;
4371
4372         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
4373                 return False;
4374         if(!prs_werror("status", ps, depth, &r_u->status))
4375                 return False;
4376
4377         return True;
4378 }
4379
4380 /*******************************************************************
4381 ********************************************************************/  
4382
4383 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
4384 {
4385         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
4386         depth++;
4387
4388         if(!prs_align(ps))
4389                 return False;
4390         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4391                 return False;
4392         if(!prs_uint32("index", ps, depth, &q_u->index))
4393                 return False;
4394         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
4395                 return False;
4396         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
4397                 return False;
4398
4399         return True;
4400 }
4401
4402 /*******************************************************************
4403 ********************************************************************/  
4404
4405 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
4406                 const POLICY_HND *hnd,
4407                 uint32 idx, uint32 valuelen, uint32 datalen)
4408 {
4409         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4410         q_u->index=idx;
4411         q_u->valuesize=valuelen;
4412         q_u->datasize=datalen;
4413
4414         return True;
4415 }
4416
4417 /*******************************************************************
4418 ********************************************************************/  
4419
4420 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
4421                                       const POLICY_HND *hnd, const char *key,
4422                                       uint32 size)
4423 {
4424         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4425         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
4426         q_u->size = size;
4427
4428         return True;
4429 }
4430
4431 /*******************************************************************
4432 ********************************************************************/  
4433 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
4434                                    char* value, uint32 data_type, char* data, uint32 data_size)
4435 {
4436         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4437         q_u->type = data_type;
4438         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
4439
4440         q_u->max_len = q_u->real_len = data_size;
4441         q_u->data = (unsigned char *)data;
4442         
4443         return True;
4444 }
4445
4446 /*******************************************************************
4447 ********************************************************************/  
4448
4449 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
4450 {
4451         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
4452         depth++;
4453
4454         if(!prs_align(ps))
4455                 return False;
4456         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4457                 return False;
4458         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
4459                 return False;
4460
4461         if(!prs_align(ps))
4462                 return False;
4463
4464         if(!prs_uint32("type", ps, depth, &q_u->type))
4465                 return False;
4466
4467         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
4468                 return False;
4469
4470         switch (q_u->type)
4471         {
4472                 case REG_SZ:
4473                 case REG_BINARY:
4474                 case REG_DWORD:
4475                 case REG_MULTI_SZ:
4476                         if (q_u->max_len) {
4477                                 if (UNMARSHALLING(ps))
4478                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
4479                                 if(q_u->data == NULL)
4480                                         return False;
4481                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
4482                                         return False;
4483                         }
4484                         if(!prs_align(ps))
4485                                 return False;
4486                         break;
4487         }       
4488         
4489         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
4490                 return False;
4491
4492         return True;
4493 }
4494
4495 /*******************************************************************
4496 ********************************************************************/  
4497
4498 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
4499 {
4500         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
4501         depth++;
4502
4503         if(!prs_align(ps))
4504                 return False;
4505         if(!prs_werror("status",     ps, depth, &r_u->status))
4506                 return False;
4507
4508         return True;
4509 }
4510
4511 /*******************************************************************
4512  Parse a SPOOL_R_GETJOB structure.
4513 ********************************************************************/  
4514
4515 bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
4516 {               
4517         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
4518         depth++;
4519
4520         if (!prs_align(ps))
4521                 return False;
4522                 
4523         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4524                 return False;
4525
4526         if (!prs_align(ps))
4527                 return False;
4528                 
4529         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4530                 return False;
4531                 
4532         if (!prs_werror("status", ps, depth, &r_u->status))
4533                 return False;
4534
4535         return True;            
4536 }
4537
4538 /*******************************************************************
4539  Parse a SPOOL_Q_GETJOB structure.
4540 ********************************************************************/  
4541
4542 bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
4543 {
4544         prs_debug(ps, depth, desc, "");
4545         depth++;
4546
4547         if(!prs_align(ps))
4548                 return False;
4549
4550         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4551                 return False;
4552         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4553                 return False;
4554         if(!prs_uint32("level", ps, depth, &q_u->level))
4555                 return False;
4556         
4557         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4558                 return False;
4559
4560         if(!prs_align(ps))
4561                 return False;
4562         
4563         if(!prs_uint32("offered", ps, depth, &q_u->offered))
4564                 return False;
4565
4566         return True;
4567 }
4568
4569 void free_devmode(DEVICEMODE *devmode)
4570 {
4571         if (devmode!=NULL) {
4572                 SAFE_FREE(devmode->dev_private);
4573                 SAFE_FREE(devmode);
4574         }
4575 }
4576
4577 void free_printer_info_1(PRINTER_INFO_1 *printer)
4578 {
4579         SAFE_FREE(printer);
4580 }
4581
4582 void free_printer_info_2(PRINTER_INFO_2 *printer)
4583 {
4584         if (printer!=NULL) {
4585                 free_devmode(printer->devmode);
4586                 printer->devmode = NULL;
4587                 SAFE_FREE(printer);
4588         }
4589 }
4590
4591 void free_printer_info_3(PRINTER_INFO_3 *printer)
4592 {
4593         SAFE_FREE(printer);
4594 }
4595
4596 void free_printer_info_4(PRINTER_INFO_4 *printer)
4597 {
4598         SAFE_FREE(printer);
4599 }
4600
4601 void free_printer_info_5(PRINTER_INFO_5 *printer)
4602 {
4603         SAFE_FREE(printer);
4604 }
4605
4606 void free_printer_info_6(PRINTER_INFO_6 *printer)
4607 {
4608         SAFE_FREE(printer);
4609 }
4610
4611 void free_printer_info_7(PRINTER_INFO_7 *printer)
4612 {
4613         SAFE_FREE(printer);
4614 }
4615
4616 void free_job_info_2(JOB_INFO_2 *job)
4617 {
4618     if (job!=NULL)
4619         free_devmode(job->devmode);
4620 }
4621
4622 #if 0   /* JERRY - not currently used but could be :-) */
4623
4624 /*******************************************************************
4625  Deep copy a SPOOL_NOTIFY_INFO_DATA structure
4626  ******************************************************************/
4627 static bool copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, 
4628                                 SPOOL_NOTIFY_INFO_DATA *src, int n)
4629 {
4630         int i;
4631
4632         memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
4633         
4634         for (i=0; i<n; i++) {
4635                 int len;
4636                 uint16 *s = NULL;
4637                 
4638                 if (src->size != POINTER) 
4639                         continue;
4640                 len = src->notify_data.data.length;
4641                 s = SMB_MALLOC_ARRAY(uint16, len);
4642                 if (s == NULL) {
4643                         DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
4644                         return False;
4645                 }
4646                 
4647                 memcpy(s, src->notify_data.data.string, len*2);
4648                 dst->notify_data.data.string = s;
4649         }
4650         
4651         return True;
4652 }
4653
4654 /*******************************************************************
4655  Deep copy a SPOOL_NOTIFY_INFO structure
4656  ******************************************************************/
4657 static bool copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
4658 {
4659         if (!dst) {
4660                 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
4661                 return False;
4662         }
4663                 
4664         dst->version = src->version;
4665         dst->flags   = src->flags;
4666         dst->count   = src->count;
4667         
4668         if (dst->count) 
4669         {
4670                 dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count);
4671                 
4672                 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
4673                         dst->count));
4674
4675                 if (dst->data == NULL) {
4676                         DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", 
4677                                 dst->count));
4678                         return False;
4679                 }
4680                 
4681                 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
4682         }
4683         
4684         return True;
4685 }
4686 #endif  /* JERRY */
4687
4688 /*******************************************************************
4689  * init a structure.
4690  ********************************************************************/
4691
4692 bool make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
4693                                 uint32 change_low, uint32 change_high,
4694                                 SPOOL_NOTIFY_INFO *info)
4695 {      
4696         if (q_u == NULL)
4697                 return False;
4698
4699         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4700
4701         q_u->change_low=change_low;
4702         q_u->change_high=change_high;
4703
4704         q_u->unknown0=0x0;
4705         q_u->unknown1=0x0;
4706
4707         q_u->info_ptr=0x0FF0ADDE;
4708
4709         q_u->info.version=2;
4710         
4711         if (info->count) {
4712                 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
4713                         info->count));
4714                 q_u->info.version = info->version;
4715                 q_u->info.flags   = info->flags;
4716                 q_u->info.count   = info->count;
4717                 /* pointer field - be careful! */
4718                 q_u->info.data    = info->data;
4719         }
4720         else  {
4721         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
4722         q_u->info.count=0;
4723         }
4724
4725         return True;
4726 }
4727
4728 /*******************************************************************
4729  Parse a SPOOL_Q_REPLY_RRPCN structure.
4730 ********************************************************************/  
4731
4732 bool spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
4733 {
4734         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
4735         depth++;
4736
4737         if(!prs_align(ps))
4738                 return False;
4739
4740         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4741                 return False;
4742
4743         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
4744                 return False;
4745
4746         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
4747                 return False;
4748
4749         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
4750                 return False;
4751
4752         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
4753                 return False;
4754
4755         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
4756                 return False;
4757
4758         if(q_u->info_ptr!=0)
4759                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
4760                         return False;
4761                 
4762         return True;
4763 }
4764
4765 /*******************************************************************
4766  Parse a SPOOL_R_REPLY_RRPCN structure.
4767 ********************************************************************/  
4768
4769 bool spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
4770 {               
4771         prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
4772         depth++;
4773
4774         if (!prs_align(ps))
4775                 return False;
4776
4777         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
4778                 return False;
4779
4780         if (!prs_werror("status", ps, depth, &r_u->status))
4781                 return False;
4782
4783         return True;            
4784 }
4785
4786 /*******************************************************************
4787  * read a structure.
4788  ********************************************************************/  
4789 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
4790                                    POLICY_HND *hnd, const char *key, 
4791                                    uint32 size)
4792 {
4793         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
4794
4795         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4796         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
4797         q_u->size = size;
4798
4799         return True;
4800 }
4801
4802 /*******************************************************************
4803  * read a structure.
4804  ********************************************************************/  
4805
4806 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
4807 {
4808         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
4809         depth++;
4810
4811         if(!prs_align(ps))
4812                 return False;
4813         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4814                 return False;
4815                 
4816         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
4817                 return False;
4818
4819         if(!prs_align(ps))
4820                 return False;
4821         
4822         if(!prs_uint32("size", ps, depth, &q_u->size))
4823                 return False;
4824
4825         return True;
4826 }
4827
4828 /*******************************************************************
4829  * write a structure.
4830  ********************************************************************/  
4831
4832 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
4833 {
4834         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
4835         depth++;
4836
4837         if(!prs_align(ps))
4838                 return False;
4839
4840         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
4841                 return False;
4842         
4843         if(!prs_align(ps))
4844                 return False;
4845
4846         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
4847                 return False;
4848
4849         if(!prs_werror("status",     ps, depth, &r_u->status))
4850                 return False;
4851
4852         return True;
4853 }
4854
4855 /*******************************************************************
4856  * read a structure.
4857  ********************************************************************/  
4858
4859 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
4860 {
4861         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
4862         depth++;
4863
4864         if(!prs_align(ps))
4865                 return False;
4866         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4867                 return False;
4868                 
4869         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
4870                 return False;
4871
4872         if(!prs_align(ps))
4873                 return False;
4874         
4875         if(!prs_uint32("size", ps, depth, &q_u->size))
4876                 return False;
4877
4878         return True;
4879 }
4880
4881 /*******************************************************************
4882 ********************************************************************/  
4883
4884 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
4885                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
4886 {
4887         int     i;
4888         uint32  valuename_offset,
4889                 data_offset,
4890                 current_offset;
4891         const uint32 basic_unit = 20; /* size of static portion of enum_values */
4892
4893         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
4894         depth++;        
4895
4896         /* 
4897          * offset data begins at 20 bytes per structure * size_of_array.
4898          * Don't forget the uint32 at the beginning 
4899          * */
4900         
4901         current_offset = basic_unit * ctr->size_of_array;
4902         
4903         /* first loop to write basic enum_value information */
4904         
4905         if (UNMARSHALLING(ps) && ctr->size_of_array) {
4906                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
4907                 if (!ctr->values)
4908                         return False;
4909         }
4910
4911         for (i=0; i<ctr->size_of_array; i++) {
4912                 uint32 base_offset, return_offset;
4913
4914                 base_offset = prs_offset(ps);
4915
4916                 valuename_offset = current_offset;
4917                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
4918                         return False;
4919
4920                 /* Read or write the value. */
4921
4922                 return_offset = prs_offset(ps);
4923
4924                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
4925                         return False;
4926                 }
4927
4928                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
4929                         return False;
4930
4931                 /* And go back. */
4932                 if (!prs_set_offset(ps, return_offset))
4933                         return False;
4934
4935                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
4936                         return False;
4937         
4938                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
4939                         return False;
4940         
4941                 data_offset = ctr->values[i].value_len + valuename_offset;
4942                 
4943                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
4944                         return False;
4945
4946                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
4947                         return False;
4948                         
4949                 /* Read or write the data. */
4950
4951                 return_offset = prs_offset(ps);
4952
4953                 if (!prs_set_offset(ps, base_offset + data_offset)) {
4954                         return False;
4955                 }
4956
4957                 if ( ctr->values[i].data_len ) {
4958                         if ( UNMARSHALLING(ps) ) {
4959                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
4960                                 if (!ctr->values[i].data)
4961                                         return False;
4962                         }
4963                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
4964                                 return False;
4965                 }
4966
4967                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
4968                 /* account for 2 byte alignment */
4969                 current_offset += (current_offset % 2);
4970
4971                 /* Remember how far we got. */
4972                 data_offset = prs_offset(ps);
4973
4974                 /* And go back. */
4975                 if (!prs_set_offset(ps, return_offset))
4976                         return False;
4977
4978         }
4979
4980         /* Go to the last data offset we got to. */
4981
4982         if (!prs_set_offset(ps, data_offset))
4983                 return False;
4984
4985         /* And ensure we're 2 byte aligned. */
4986
4987         if ( !prs_align_uint16(ps) )
4988                 return False;
4989
4990         return True;    
4991 }
4992
4993 /*******************************************************************
4994  * write a structure.
4995  ********************************************************************/  
4996
4997 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
4998 {
4999         uint32 data_offset, end_offset;
5000         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
5001         depth++;
5002
5003         if(!prs_align(ps))
5004                 return False;
5005
5006         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
5007                 return False;
5008
5009         data_offset = prs_offset(ps);
5010
5011         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
5012                 return False;
5013
5014         if(!prs_align(ps))
5015                 return False;
5016
5017         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
5018                 return False;
5019
5020         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
5021                 return False;
5022
5023         if(!prs_werror("status",     ps, depth, &r_u->status))
5024                 return False;
5025
5026         r_u->ctr.size_of_array = r_u->returned;
5027
5028         end_offset = prs_offset(ps);
5029
5030         if (!prs_set_offset(ps, data_offset))
5031                 return False;
5032
5033         if (r_u->ctr.size)
5034                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
5035                         return False;
5036
5037         if (!prs_set_offset(ps, end_offset))
5038                 return False;
5039         return True;
5040 }
5041
5042 /*******************************************************************
5043  * init a structure.
5044  ********************************************************************/
5045
5046 bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
5047                               uint32 level, RPC_BUFFER *buffer,
5048                               uint32 offered)
5049 {
5050         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
5051         q_u->level = level;
5052         q_u->buffer=buffer;
5053         q_u->offered=offered;
5054
5055         return True;
5056 }
5057
5058 /*******************************************************************
5059  * init a structure.
5060  ********************************************************************/
5061
5062 bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
5063                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
5064                            uint32 offered)
5065 {
5066         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
5067         q_u->jobid = jobid;
5068         q_u->level = level;
5069         q_u->buffer = buffer;
5070         q_u->offered = offered;
5071
5072         return True;
5073 }
5074
5075 /*******************************************************************
5076  * init a structure.
5077  ********************************************************************/
5078
5079 bool make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
5080                              uint32 flags, uint32 options, const char *localmachine,
5081                              uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
5082 {
5083         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
5084
5085         q_u->flags = flags;
5086         q_u->options = options;
5087
5088         q_u->localmachine_ptr = 1;
5089
5090         init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
5091
5092         q_u->printerlocal = printerlocal;
5093
5094         if (option)
5095                 q_u->option_ptr = 1;
5096
5097         q_u->option = option;
5098
5099         return True;
5100 }