s3-spoolss: remove old spoolss_SetPrinterDataEx.
[tprouty/samba.git] / source3 / rpc_parse / parse_spoolss.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000,
7  *  Copyright (C) Gerald Carter                2000-2002,
8  *  Copyright (C) Tim Potter                   2001-2002.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 3 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
28
29
30 /*******************************************************************
31 This should be moved in a more generic lib.
32 ********************************************************************/  
33
34 bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
35 {
36         if(!prs_uint16("year", ps, depth, &systime->year))
37                 return False;
38         if(!prs_uint16("month", ps, depth, &systime->month))
39                 return False;
40         if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
41                 return False;
42         if(!prs_uint16("day", ps, depth, &systime->day))
43                 return False;
44         if(!prs_uint16("hour", ps, depth, &systime->hour))
45                 return False;
46         if(!prs_uint16("minute", ps, depth, &systime->minute))
47                 return False;
48         if(!prs_uint16("second", ps, depth, &systime->second))
49                 return False;
50         if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
51                 return False;
52
53         return True;
54 }
55
56 /*******************************************************************
57 ********************************************************************/  
58
59 bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
60 {
61         systime->year=unixtime->tm_year+1900;
62         systime->month=unixtime->tm_mon+1;
63         systime->dayofweek=unixtime->tm_wday;
64         systime->day=unixtime->tm_mday;
65         systime->hour=unixtime->tm_hour;
66         systime->minute=unixtime->tm_min;
67         systime->second=unixtime->tm_sec;
68         systime->milliseconds=0;
69
70         return True;
71 }
72
73 /*******************************************************************
74 reads or writes an 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
1965 /*******************************************************************
1966  Parse a DRIVER_DIRECTORY_1 structure.
1967 ********************************************************************/  
1968
1969 bool smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
1970 {
1971         prs_struct *ps=&buffer->prs;
1972
1973         prs_debug(ps, depth, desc, "smb_io_driverdir_1");
1974         depth++;
1975
1976         buffer->struct_start=prs_offset(ps);
1977
1978         if (!smb_io_unistr(desc, &info->name, ps, depth))
1979                 return False;
1980
1981         return True;
1982 }
1983
1984 /*******************************************************************
1985  Parse a PORT_INFO_1 structure.
1986 ********************************************************************/  
1987
1988 bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
1989 {
1990         prs_struct *ps=&buffer->prs;
1991
1992         prs_debug(ps, depth, desc, "smb_io_port_1");
1993         depth++;
1994
1995         buffer->struct_start=prs_offset(ps);
1996
1997         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1998                 return False;
1999
2000         return True;
2001 }
2002
2003 /*******************************************************************
2004  Parse a PORT_INFO_2 structure.
2005 ********************************************************************/  
2006
2007 bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2008 {
2009         prs_struct *ps=&buffer->prs;
2010
2011         prs_debug(ps, depth, desc, "smb_io_port_2");
2012         depth++;
2013
2014         buffer->struct_start=prs_offset(ps);
2015
2016         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2017                 return False;
2018         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2019                 return False;
2020         if(!smb_io_relstr("description", buffer, depth, &info->description))
2021                 return False;
2022         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2023                 return False;
2024         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2025                 return False;
2026
2027         return True;
2028 }
2029
2030 /*******************************************************************
2031 ********************************************************************/  
2032
2033 bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2034 {
2035         prs_struct *ps=&buffer->prs;
2036
2037         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2038         depth++;        
2039
2040         buffer->struct_start=prs_offset(ps);
2041         
2042         if (smb_io_relstr("name", buffer, depth, &info->name))
2043                 return False;
2044
2045         return True;
2046 }
2047
2048 /*******************************************************************
2049 ********************************************************************/  
2050
2051 bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2052 {
2053         prs_struct *ps=&buffer->prs;
2054
2055         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2056         depth++;        
2057
2058         buffer->struct_start=prs_offset(ps);
2059         
2060         if (smb_io_relstr("name", buffer, depth, &info->name))
2061                 return False;
2062
2063         return True;
2064 }
2065
2066 /*******************************************************************
2067 ********************************************************************/  
2068
2069 bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2070 {
2071         prs_struct *ps=&buffer->prs;
2072
2073         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2074         depth++;        
2075
2076         buffer->struct_start=prs_offset(ps);
2077
2078         if (!smb_io_relstr("name", buffer, depth, &info->name))
2079                 return False;
2080
2081         return True;
2082 }
2083
2084 /*******************************************************************
2085 ********************************************************************/  
2086
2087 bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2088 {
2089         prs_struct *ps=&buffer->prs;
2090
2091         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2092         depth++;        
2093
2094         buffer->struct_start=prs_offset(ps);
2095
2096         if (!smb_io_relstr("name", buffer, depth, &info->name))
2097                 return False;
2098         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
2099                 return False;
2100         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2101                 return False;
2102
2103         return True;
2104 }
2105
2106 /*******************************************************************
2107 return the size required by a struct in the stream
2108 ********************************************************************/  
2109
2110 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2111 {
2112         int size=0;
2113         
2114         size+=size_of_relative_string( &info->printername );
2115         size+=size_of_relative_string( &info->servername );
2116
2117         size+=size_of_uint32( &info->cjobs);
2118         size+=size_of_uint32( &info->total_jobs);
2119         size+=size_of_uint32( &info->total_bytes);
2120
2121         size+=size_of_uint16( &info->year);
2122         size+=size_of_uint16( &info->month);
2123         size+=size_of_uint16( &info->dayofweek);
2124         size+=size_of_uint16( &info->day);
2125         size+=size_of_uint16( &info->hour);
2126         size+=size_of_uint16( &info->minute);
2127         size+=size_of_uint16( &info->second);
2128         size+=size_of_uint16( &info->milliseconds);
2129
2130         size+=size_of_uint32( &info->global_counter);
2131         size+=size_of_uint32( &info->total_pages);
2132
2133         size+=size_of_uint16( &info->major_version);
2134         size+=size_of_uint16( &info->build_version);
2135
2136         size+=size_of_uint32( &info->unknown7);
2137         size+=size_of_uint32( &info->unknown8);
2138         size+=size_of_uint32( &info->unknown9);
2139         size+=size_of_uint32( &info->session_counter);
2140         size+=size_of_uint32( &info->unknown11);
2141         size+=size_of_uint32( &info->printer_errors);
2142         size+=size_of_uint32( &info->unknown13);
2143         size+=size_of_uint32( &info->unknown14);
2144         size+=size_of_uint32( &info->unknown15);
2145         size+=size_of_uint32( &info->unknown16);
2146         size+=size_of_uint32( &info->change_id);
2147         size+=size_of_uint32( &info->unknown18);
2148         size+=size_of_uint32( &info->status);
2149         size+=size_of_uint32( &info->unknown20);
2150         size+=size_of_uint32( &info->c_setprinter);
2151         
2152         size+=size_of_uint16( &info->unknown22);
2153         size+=size_of_uint16( &info->unknown23);
2154         size+=size_of_uint16( &info->unknown24);
2155         size+=size_of_uint16( &info->unknown25);
2156         size+=size_of_uint16( &info->unknown26);
2157         size+=size_of_uint16( &info->unknown27);
2158         size+=size_of_uint16( &info->unknown28);
2159         size+=size_of_uint16( &info->unknown29);
2160         
2161         return size;
2162 }
2163
2164 /*******************************************************************
2165 return the size required by a struct in the stream
2166 ********************************************************************/  
2167
2168 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
2169 {
2170         int size=0;
2171                 
2172         size+=size_of_uint32( &info->flags );   
2173         size+=size_of_relative_string( &info->description );
2174         size+=size_of_relative_string( &info->name );
2175         size+=size_of_relative_string( &info->comment );
2176
2177         return size;
2178 }
2179
2180 /*******************************************************************
2181 return the size required by a struct in the stream
2182 ********************************************************************/
2183
2184 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
2185 {
2186         uint32 size=0;
2187                 
2188         size += 4;
2189         
2190         size += ndr_size_security_descriptor( info->secdesc, NULL, 0 );
2191
2192         size+=size_of_device_mode( info->devmode );
2193         
2194         size+=size_of_relative_string( &info->servername );
2195         size+=size_of_relative_string( &info->printername );
2196         size+=size_of_relative_string( &info->sharename );
2197         size+=size_of_relative_string( &info->portname );
2198         size+=size_of_relative_string( &info->drivername );
2199         size+=size_of_relative_string( &info->comment );
2200         size+=size_of_relative_string( &info->location );
2201         
2202         size+=size_of_relative_string( &info->sepfile );
2203         size+=size_of_relative_string( &info->printprocessor );
2204         size+=size_of_relative_string( &info->datatype );
2205         size+=size_of_relative_string( &info->parameters );
2206
2207         size+=size_of_uint32( &info->attributes );
2208         size+=size_of_uint32( &info->priority );
2209         size+=size_of_uint32( &info->defaultpriority );
2210         size+=size_of_uint32( &info->starttime );
2211         size+=size_of_uint32( &info->untiltime );
2212         size+=size_of_uint32( &info->status );
2213         size+=size_of_uint32( &info->cjobs );
2214         size+=size_of_uint32( &info->averageppm );      
2215                 
2216         /* 
2217          * add any adjustments for alignment.  This is
2218          * not optimal since we could be calling this
2219          * function from a loop (e.g. enumprinters), but 
2220          * it is easier to maintain the calculation here and
2221          * not place the burden on the caller to remember.   --jerry
2222          */
2223         if ((size % 4) != 0)
2224                 size += 4 - (size % 4);
2225         
2226         return size;
2227 }
2228
2229 /*******************************************************************
2230 return the size required by a struct in the stream
2231 ********************************************************************/
2232
2233 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
2234 {
2235         uint32 size=0;
2236                 
2237         size+=size_of_relative_string( &info->printername );
2238         size+=size_of_relative_string( &info->servername );
2239
2240         size+=size_of_uint32( &info->attributes );
2241         return size;
2242 }
2243
2244 /*******************************************************************
2245 return the size required by a struct in the stream
2246 ********************************************************************/
2247
2248 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
2249 {
2250         uint32 size=0;
2251                 
2252         size+=size_of_relative_string( &info->printername );
2253         size+=size_of_relative_string( &info->portname );
2254
2255         size+=size_of_uint32( &info->attributes );
2256         size+=size_of_uint32( &info->device_not_selected_timeout );
2257         size+=size_of_uint32( &info->transmission_retry_timeout );
2258         return size;
2259 }
2260
2261 /*******************************************************************
2262 return the size required by a struct in the stream
2263 ********************************************************************/
2264
2265 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
2266 {
2267         return sizeof(uint32);
2268 }
2269
2270 /*******************************************************************
2271 return the size required by a struct in the stream
2272 ********************************************************************/
2273
2274 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
2275 {
2276         /* The 8 is for the self relative pointer - 8 byte aligned.. */
2277         return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 );
2278 }
2279
2280 /*******************************************************************
2281 return the size required by a struct in the stream
2282 ********************************************************************/
2283
2284 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
2285 {
2286         uint32 size=0;
2287                 
2288         size+=size_of_relative_string( &info->guid );
2289         size+=size_of_uint32( &info->action );
2290         return size;
2291 }
2292
2293 /*******************************************************************
2294 return the size required by a struct in the stream
2295 ********************************************************************/
2296
2297 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
2298 {
2299         int size=0;
2300         size+=size_of_relative_string( &info->name );
2301
2302         return size;
2303 }
2304
2305 /*******************************************************************
2306 return the size required by a struct in the stream
2307 ********************************************************************/
2308
2309 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
2310 {
2311         int size=0;
2312         size+=size_of_uint32( &info->version ); 
2313         size+=size_of_relative_string( &info->name );
2314         size+=size_of_relative_string( &info->architecture );
2315         size+=size_of_relative_string( &info->driverpath );
2316         size+=size_of_relative_string( &info->datafile );
2317         size+=size_of_relative_string( &info->configfile );
2318
2319         return size;
2320 }
2321
2322 /*******************************************************************
2323 return the size required by a string array.
2324 ********************************************************************/
2325
2326 uint32 spoolss_size_string_array(uint16 *string)
2327 {
2328         uint32 i = 0;
2329
2330         if (string) {
2331                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
2332         }
2333         i=i+2; /* to count all chars including the leading zero */
2334         i=2*i; /* because we need the value in bytes */
2335         i=i+4; /* the offset pointer size */
2336
2337         return i;
2338 }
2339
2340 /*******************************************************************
2341 return the size required by a struct in the stream
2342 ********************************************************************/
2343
2344 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
2345 {
2346         int size=0;
2347
2348         size+=size_of_uint32( &info->version ); 
2349         size+=size_of_relative_string( &info->name );
2350         size+=size_of_relative_string( &info->architecture );
2351         size+=size_of_relative_string( &info->driverpath );
2352         size+=size_of_relative_string( &info->datafile );
2353         size+=size_of_relative_string( &info->configfile );
2354         size+=size_of_relative_string( &info->helpfile );
2355         size+=size_of_relative_string( &info->monitorname );
2356         size+=size_of_relative_string( &info->defaultdatatype );
2357         
2358         size+=spoolss_size_string_array(info->dependentfiles);
2359
2360         return size;
2361 }
2362
2363 /*******************************************************************
2364 return the size required by a struct in the stream
2365 ********************************************************************/
2366
2367 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
2368 {
2369         uint32 size=0;
2370
2371         size+=size_of_uint32( &info->version ); 
2372         size+=size_of_relative_string( &info->name );
2373         size+=size_of_relative_string( &info->architecture );
2374         size+=size_of_relative_string( &info->driverpath );
2375         size+=size_of_relative_string( &info->datafile );
2376         size+=size_of_relative_string( &info->configfile );
2377         size+=size_of_relative_string( &info->helpfile );
2378
2379         size+=spoolss_size_string_array(info->dependentfiles);
2380
2381         size+=size_of_relative_string( &info->monitorname );
2382         size+=size_of_relative_string( &info->defaultdatatype );
2383         
2384         size+=spoolss_size_string_array(info->previousdrivernames);
2385
2386         size+=size_of_nttime(&info->driver_date);
2387         size+=size_of_uint32( &info->padding ); 
2388         size+=size_of_uint32( &info->driver_version_low );      
2389         size+=size_of_uint32( &info->driver_version_high );     
2390         size+=size_of_relative_string( &info->mfgname );
2391         size+=size_of_relative_string( &info->oem_url );
2392         size+=size_of_relative_string( &info->hardware_id );
2393         size+=size_of_relative_string( &info->provider );
2394
2395         return size;
2396 }
2397
2398 /*******************************************************************
2399 return the size required by a struct in the stream
2400 ********************************************************************/  
2401
2402 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
2403 {
2404         int size=0;
2405         size+=size_of_uint32( &info->jobid );
2406         size+=size_of_relative_string( &info->printername );
2407         size+=size_of_relative_string( &info->machinename );
2408         size+=size_of_relative_string( &info->username );
2409         size+=size_of_relative_string( &info->document );
2410         size+=size_of_relative_string( &info->datatype );
2411         size+=size_of_relative_string( &info->text_status );
2412         size+=size_of_uint32( &info->status );
2413         size+=size_of_uint32( &info->priority );
2414         size+=size_of_uint32( &info->position );
2415         size+=size_of_uint32( &info->totalpages );
2416         size+=size_of_uint32( &info->pagesprinted );
2417         size+=size_of_systemtime( &info->submitted );
2418
2419         return size;
2420 }
2421
2422 /*******************************************************************
2423 return the size required by a struct in the stream
2424 ********************************************************************/  
2425
2426 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
2427 {
2428         int size=0;
2429
2430         size+=4; /* size of sec desc ptr */
2431
2432         size+=size_of_uint32( &info->jobid );
2433         size+=size_of_relative_string( &info->printername );
2434         size+=size_of_relative_string( &info->machinename );
2435         size+=size_of_relative_string( &info->username );
2436         size+=size_of_relative_string( &info->document );
2437         size+=size_of_relative_string( &info->notifyname );
2438         size+=size_of_relative_string( &info->datatype );
2439         size+=size_of_relative_string( &info->printprocessor );
2440         size+=size_of_relative_string( &info->parameters );
2441         size+=size_of_relative_string( &info->drivername );
2442         size+=size_of_device_mode( info->devmode );
2443         size+=size_of_relative_string( &info->text_status );
2444 /*      SEC_DESC sec_desc;*/
2445         size+=size_of_uint32( &info->status );
2446         size+=size_of_uint32( &info->priority );
2447         size+=size_of_uint32( &info->position );
2448         size+=size_of_uint32( &info->starttime );
2449         size+=size_of_uint32( &info->untiltime );
2450         size+=size_of_uint32( &info->totalpages );
2451         size+=size_of_uint32( &info->size );
2452         size+=size_of_systemtime( &info->submitted );
2453         size+=size_of_uint32( &info->timeelapsed );
2454         size+=size_of_uint32( &info->pagesprinted );
2455
2456         return size;
2457 }
2458
2459 /*******************************************************************
2460 return the size required by a struct in the stream
2461 ********************************************************************/
2462
2463 uint32 spoolss_size_form_1(FORM_1 *info)
2464 {
2465         int size=0;
2466
2467         size+=size_of_uint32( &info->flag );
2468         size+=size_of_relative_string( &info->name );
2469         size+=size_of_uint32( &info->width );
2470         size+=size_of_uint32( &info->length );
2471         size+=size_of_uint32( &info->left );
2472         size+=size_of_uint32( &info->top );
2473         size+=size_of_uint32( &info->right );
2474         size+=size_of_uint32( &info->bottom );
2475
2476         return size;
2477 }
2478
2479 /*******************************************************************
2480 return the size required by a struct in the stream
2481 ********************************************************************/  
2482
2483 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
2484 {
2485         int size=0;
2486
2487         size+=size_of_relative_string( &info->port_name );
2488
2489         return size;
2490 }
2491
2492 /*******************************************************************
2493 return the size required by a struct in the stream
2494 ********************************************************************/  
2495
2496 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
2497 {
2498         int size=0;
2499
2500         size=str_len_uni(&info->name);  /* the string length       */
2501         size=size+1;                    /* add the leading zero    */
2502         size=size*2;                    /* convert in char         */
2503
2504         return size;
2505 }
2506
2507 /*******************************************************************
2508 return the size required by a struct in the stream
2509 ********************************************************************/  
2510
2511 uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
2512 {
2513         int size=0;
2514
2515         size=str_len_uni(&info->name);  /* the string length       */
2516         size=size+1;                    /* add the leading zero    */
2517         size=size*2;                    /* convert in char         */
2518
2519         return size;
2520 }
2521
2522 /*******************************************************************
2523 return the size required by a struct in the stream
2524 ********************************************************************/  
2525
2526 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
2527 {
2528         int size=0;
2529
2530         size+=size_of_relative_string( &info->port_name );
2531         size+=size_of_relative_string( &info->monitor_name );
2532         size+=size_of_relative_string( &info->description );
2533
2534         size+=size_of_uint32( &info->port_type );
2535         size+=size_of_uint32( &info->reserved );
2536
2537         return size;
2538 }
2539
2540 /*******************************************************************
2541 return the size required by a struct in the stream
2542 ********************************************************************/  
2543
2544 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
2545 {
2546         int size=0;
2547         size+=size_of_relative_string( &info->name );
2548
2549         return size;
2550 }
2551
2552 /*******************************************************************
2553 return the size required by a struct in the stream
2554 ********************************************************************/  
2555
2556 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
2557 {
2558         int size=0;
2559         size+=size_of_relative_string( &info->name );
2560
2561         return size;
2562 }
2563
2564 /*******************************************************************
2565 return the size required by a struct in the stream
2566 ********************************************************************/  
2567 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
2568 {
2569         uint32  size = 0; 
2570         
2571         if (!p)
2572                 return 0;
2573         
2574         /* uint32(offset) + uint32(length) + length) */
2575         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
2576         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
2577         
2578         size += size_of_uint32(&p->type);
2579                        
2580         return size;
2581 }
2582
2583 /*******************************************************************
2584 return the size required by a struct in the stream
2585 ********************************************************************/  
2586
2587 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
2588 {
2589         int size=0;
2590         size+=size_of_relative_string( &info->name );
2591
2592         return size;
2593 }
2594
2595 /*******************************************************************
2596 return the size required by a struct in the stream
2597 ********************************************************************/  
2598
2599 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
2600 {
2601         int size=0;
2602         size+=size_of_relative_string( &info->name);
2603         size+=size_of_relative_string( &info->environment);
2604         size+=size_of_relative_string( &info->dll_name);
2605
2606         return size;
2607 }
2608
2609 /*******************************************************************
2610  * init a structure.
2611  ********************************************************************/
2612
2613 bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
2614                                const POLICY_HND *hnd,
2615                                const fstring architecture,
2616                                uint32 level, uint32 clientmajor, uint32 clientminor,
2617                                RPC_BUFFER *buffer, uint32 offered)
2618 {      
2619         if (q_u == NULL)
2620                 return False;
2621
2622         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2623
2624         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
2625
2626         q_u->level=level;
2627         q_u->clientmajorversion=clientmajor;
2628         q_u->clientminorversion=clientminor;
2629
2630         q_u->buffer=buffer;
2631         q_u->offered=offered;
2632
2633         return True;
2634 }
2635
2636 /*******************************************************************
2637  * read a structure.
2638  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2639  ********************************************************************/
2640
2641 bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
2642 {
2643         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
2644         depth++;
2645
2646         if(!prs_align(ps))
2647                 return False;
2648         
2649         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2650                 return False;
2651         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
2652                 return False;
2653         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
2654                 return False;
2655         
2656         if(!prs_align(ps))
2657                 return False;
2658         if(!prs_uint32("level", ps, depth, &q_u->level))
2659                 return False;
2660                 
2661         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2662                 return False;
2663
2664         if(!prs_align(ps))
2665                 return False;
2666
2667         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2668                 return False;
2669                 
2670         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
2671                 return False;
2672         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
2673                 return False;
2674
2675         return True;
2676 }
2677
2678 /*******************************************************************
2679  * read a structure.
2680  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2681  ********************************************************************/
2682
2683 bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
2684 {
2685         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
2686         depth++;
2687
2688         if (!prs_align(ps))
2689                 return False;
2690                 
2691         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2692                 return False;
2693
2694         if (!prs_align(ps))
2695                 return False;
2696         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2697                 return False;
2698         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
2699                 return False;
2700         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
2701                 return False;           
2702         if (!prs_werror("status", ps, depth, &r_u->status))
2703                 return False;
2704
2705         return True;            
2706 }
2707
2708 /*******************************************************************
2709  * init a structure.
2710  ********************************************************************/
2711
2712 bool make_spoolss_q_enumprinters(
2713         SPOOL_Q_ENUMPRINTERS *q_u, 
2714         uint32 flags, 
2715         char *servername, 
2716         uint32 level, 
2717         RPC_BUFFER *buffer, 
2718         uint32 offered
2719 )
2720 {
2721         q_u->flags=flags;
2722         
2723         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
2724         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
2725
2726         q_u->level=level;
2727         q_u->buffer=buffer;
2728         q_u->offered=offered;
2729
2730         return True;
2731 }
2732
2733 /*******************************************************************
2734  * init a structure.
2735  ********************************************************************/
2736
2737 bool make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
2738                                 fstring servername, uint32 level, 
2739                                 RPC_BUFFER *buffer, uint32 offered)
2740 {
2741         q_u->name_ptr = (servername != NULL) ? 1 : 0;
2742         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
2743
2744         q_u->level=level;
2745         q_u->buffer=buffer;
2746         q_u->offered=offered;
2747
2748         return True;
2749 }
2750
2751 /*******************************************************************
2752  * read a structure.
2753  * called from spoolss_enumprinters (srv_spoolss.c)
2754  ********************************************************************/
2755
2756 bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
2757 {
2758         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
2759         depth++;
2760
2761         if (!prs_align(ps))
2762                 return False;
2763
2764         if (!prs_uint32("flags", ps, depth, &q_u->flags))
2765                 return False;
2766         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
2767                 return False;
2768
2769         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
2770                 return False;
2771                 
2772         if (!prs_align(ps))
2773                 return False;
2774         if (!prs_uint32("level", ps, depth, &q_u->level))
2775                 return False;
2776
2777         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2778                 return False;
2779
2780         if (!prs_align(ps))
2781                 return False;
2782         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2783                 return False;
2784
2785         return True;
2786 }
2787
2788 /*******************************************************************
2789  Parse a SPOOL_R_ENUMPRINTERS structure.
2790  ********************************************************************/
2791
2792 bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
2793 {
2794         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
2795         depth++;
2796
2797         if (!prs_align(ps))
2798                 return False;
2799                 
2800         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2801                 return False;
2802
2803         if (!prs_align(ps))
2804                 return False;
2805                 
2806         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2807                 return False;
2808                 
2809         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2810                 return False;
2811                 
2812         if (!prs_werror("status", ps, depth, &r_u->status))
2813                 return False;
2814
2815         return True;            
2816 }
2817
2818 /*******************************************************************
2819  * write a structure.
2820  * called from spoolss_r_enum_printers (srv_spoolss.c)
2821  *
2822  ********************************************************************/
2823
2824 bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
2825 {       
2826         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
2827         depth++;
2828
2829         if (!prs_align(ps))
2830                 return False;
2831                 
2832         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2833                 return False;
2834
2835         if (!prs_align(ps))
2836                 return False;
2837
2838         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2839                 return False;
2840                 
2841         if (!prs_werror("status", ps, depth, &r_u->status))
2842                 return False;
2843
2844         return True;            
2845 }
2846
2847 /*******************************************************************
2848  * read a structure.
2849  * called from spoolss_getprinter (srv_spoolss.c)
2850  ********************************************************************/
2851
2852 bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
2853 {
2854         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
2855         depth++;
2856
2857         if (!prs_align(ps))
2858                 return False;
2859
2860         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2861                 return False;
2862         if (!prs_uint32("level", ps, depth, &q_u->level))
2863                 return False;
2864
2865         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2866                 return False;
2867
2868         if (!prs_align(ps))
2869                 return False;
2870         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2871                 return False;
2872
2873         return True;
2874 }
2875
2876 /*******************************************************************
2877  * init a structure.
2878  ********************************************************************/
2879
2880 bool make_spoolss_q_getprinter(
2881         TALLOC_CTX *mem_ctx,
2882         SPOOL_Q_GETPRINTER *q_u, 
2883         const POLICY_HND *hnd, 
2884         uint32 level, 
2885         RPC_BUFFER *buffer, 
2886         uint32 offered
2887 )
2888 {
2889         if (q_u == NULL)
2890         {
2891                 return False;
2892         }
2893         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2894
2895         q_u->level=level;
2896         q_u->buffer=buffer;
2897         q_u->offered=offered;
2898
2899         return True;
2900 }
2901
2902 /*******************************************************************
2903  * init a structure.
2904  ********************************************************************/
2905 bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
2906                                 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
2907                                 uint32 command)
2908 {
2909         SEC_DESC *secdesc;
2910         DEVICEMODE *devmode;
2911
2912         if (!q_u || !info)
2913                 return False;
2914         
2915         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2916
2917         q_u->level = level;
2918         q_u->info.level = level;
2919         q_u->info.info_ptr = 1; /* Info is != NULL, see above */
2920         switch (level) {
2921
2922           /* There's no such thing as a setprinter level 1 */
2923
2924         case 2:
2925                 secdesc = info->printers_2->secdesc;
2926                 devmode = info->printers_2->devmode;
2927                 
2928                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
2929 #if 1   /* JERRY TEST */
2930                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
2931                 if (!q_u->secdesc_ctr)
2932                         return False;
2933                 q_u->secdesc_ctr->sd = secdesc;
2934                 q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
2935
2936                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
2937                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
2938                 q_u->devmode_ctr.devmode = devmode;
2939 #else
2940                 q_u->secdesc_ctr = NULL;
2941         
2942                 q_u->devmode_ctr.devmode_ptr = 0;
2943                 q_u->devmode_ctr.size = 0;
2944                 q_u->devmode_ctr.devmode = NULL;
2945 #endif
2946                 break;
2947         case 3:
2948                 secdesc = info->printers_3->secdesc;
2949                 
2950                 make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
2951                 
2952                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
2953                 if (!q_u->secdesc_ctr)
2954                         return False;
2955                 q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
2956                 q_u->secdesc_ctr->sd = secdesc;
2957
2958                 break;
2959         case 7:
2960                 make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
2961                 break;
2962
2963         default: 
2964                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
2965                         break;
2966         }
2967
2968         
2969         q_u->command = command;
2970
2971         return True;
2972 }
2973
2974
2975 /*******************************************************************
2976 ********************************************************************/  
2977
2978 bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
2979 {               
2980         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
2981         depth++;
2982
2983         if(!prs_align(ps))
2984                 return False;
2985         
2986         if(!prs_werror("status", ps, depth, &r_u->status))
2987                 return False;
2988
2989         return True;
2990 }
2991
2992 /*******************************************************************
2993  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
2994 ********************************************************************/  
2995
2996 bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
2997 {
2998         uint32 ptr_sec_desc = 0;
2999
3000         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
3001         depth++;
3002
3003         if(!prs_align(ps))
3004                 return False;
3005
3006         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
3007                 return False;
3008         if(!prs_uint32("level", ps, depth, &q_u->level))
3009                 return False;
3010         
3011         /* check for supported levels and structures we know about */
3012                 
3013         switch ( q_u->level ) {
3014                 case 0:
3015                 case 2:
3016                 case 3:
3017                 case 7:
3018                         /* supported levels */
3019                         break;
3020                 default:
3021                         DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
3022                                 q_u->level));
3023                         return True;
3024         }
3025                         
3026
3027         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3028                 return False;
3029
3030         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3031                 return False;
3032         
3033         if(!prs_align(ps))
3034                 return False;
3035
3036         switch (q_u->level)
3037         {
3038                 case 2:
3039                 {
3040                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3041                         break;
3042                 }
3043                 case 3:
3044                 {
3045                         /* FIXME ! Our parsing here is wrong I think,
3046                          * but for a level3 it makes no sense for
3047                          * ptr_sec_desc to be NULL. JRA. Based on
3048                          * a Vista sniff from Martin Zielinski <mz@seh.de>.
3049                          */
3050                         if (UNMARSHALLING(ps)) {
3051                                 ptr_sec_desc = 1;
3052                         } else {
3053                                 ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3054                         }
3055                         break;
3056                 }
3057         }
3058         if (ptr_sec_desc)
3059         {
3060                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3061                         return False;
3062         } else {
3063                 uint32 dummy = 0;
3064
3065                 /* Parse a NULL security descriptor.  This should really
3066                    happen inside the sec_io_desc_buf() function. */
3067
3068                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3069                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3070                         return False;
3071                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3072                         return False;
3073         }
3074         
3075         if(!prs_uint32("command", ps, depth, &q_u->command))
3076                 return False;
3077
3078         return True;
3079 }
3080
3081 /*******************************************************************
3082 ********************************************************************/  
3083
3084 bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
3085 {               
3086         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
3087         depth++;
3088
3089         if (!prs_align(ps))
3090                 return False;
3091                 
3092         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3093                 return False;
3094
3095         if (!prs_align(ps))
3096                 return False;
3097                 
3098         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3099                 return False;
3100                 
3101         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3102                 return False;
3103                 
3104         if (!prs_werror("status", ps, depth, &r_u->status))
3105                 return False;
3106
3107         return True;            
3108 }
3109
3110 /*******************************************************************
3111 ********************************************************************/  
3112
3113 bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
3114                                 uint32 firstjob,
3115                                 uint32 numofjobs,
3116                                 uint32 level,
3117                                 RPC_BUFFER *buffer,
3118                                 uint32 offered)
3119 {
3120         if (q_u == NULL)
3121         {
3122                 return False;
3123         }
3124         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3125         q_u->firstjob = firstjob;
3126         q_u->numofjobs = numofjobs;
3127         q_u->level = level;
3128         q_u->buffer= buffer;
3129         q_u->offered = offered;
3130         return True;
3131 }
3132
3133 /*******************************************************************
3134 ********************************************************************/  
3135
3136 bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
3137 {
3138         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
3139         depth++;
3140
3141         if (!prs_align(ps))
3142                 return False;
3143
3144         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
3145                 return False;
3146                 
3147         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
3148                 return False;
3149         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
3150                 return False;
3151         if (!prs_uint32("level", ps, depth, &q_u->level))
3152                 return False;
3153
3154         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3155                 return False;   
3156
3157         if(!prs_align(ps))
3158                 return False;
3159
3160         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3161                 return False;
3162
3163         return True;
3164 }
3165
3166 /*******************************************************************
3167  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
3168 ********************************************************************/  
3169
3170 bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
3171 {
3172         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
3173         depth++;
3174
3175         if (!prs_align(ps))
3176                 return False;
3177                 
3178         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3179                 return False;
3180
3181         if (!prs_align(ps))
3182                 return False;
3183                 
3184         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3185                 return False;
3186                 
3187         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3188                 return False;
3189                 
3190         if (!prs_werror("status", ps, depth, &r_u->status))
3191                 return False;
3192
3193         return True;            
3194 }
3195
3196 /*******************************************************************
3197  * init a structure.
3198  ********************************************************************/
3199
3200 bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
3201                                 const char *name,
3202                                 const char *environment,
3203                                 uint32 level,
3204                                 RPC_BUFFER *buffer, uint32 offered)
3205 {
3206         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
3207         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
3208
3209         q_u->level=level;
3210         q_u->buffer=buffer;
3211         q_u->offered=offered;
3212
3213         return True;
3214 }
3215
3216 /*******************************************************************
3217  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
3218 ********************************************************************/  
3219
3220 bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
3221 {
3222
3223         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
3224         depth++;
3225
3226         if (!prs_align(ps))
3227                 return False;
3228                 
3229         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3230                 return False;
3231         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
3232                 return False;
3233                 
3234         if (!prs_align(ps))
3235                 return False;
3236         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
3237                 return False;
3238         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3239                 return False;
3240                 
3241         if (!prs_align(ps))
3242                 return False;
3243         if (!prs_uint32("level", ps, depth, &q_u->level))
3244                 return False;
3245                 
3246         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3247                 return False;
3248
3249         if (!prs_align(ps))
3250                 return False;
3251                 
3252         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3253                 return False;
3254
3255         return True;
3256 }
3257
3258 /*******************************************************************
3259 ********************************************************************/  
3260
3261 bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
3262 {
3263
3264         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
3265         depth++;
3266
3267         if (!prs_align(ps))
3268                 return False;                   
3269         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3270                 return False;           
3271         if (!prs_uint32("level", ps, depth, &q_u->level))
3272                 return False;   
3273         
3274         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3275                 return False;
3276
3277         if (!prs_align(ps))
3278                 return False;
3279         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3280                 return False;
3281
3282         return True;
3283 }
3284
3285 /*******************************************************************
3286 ********************************************************************/  
3287
3288 bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
3289 {
3290         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
3291         depth++;
3292
3293         if (!prs_align(ps))
3294                 return False;
3295                 
3296         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3297                 return False;
3298
3299         if (!prs_align(ps))
3300                 return False;
3301                 
3302         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
3303                 return False;
3304                 
3305         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
3306                 return False;
3307                 
3308         if (!prs_werror("status", ps, depth, &r_u->status))
3309                 return False;
3310
3311         return True;
3312 }
3313
3314 /*******************************************************************
3315  Parse a SPOOL_R_ENUMPORTS structure.
3316 ********************************************************************/  
3317
3318 bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
3319 {
3320         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
3321         depth++;
3322
3323         if (!prs_align(ps))
3324                 return False;
3325                 
3326         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3327                 return False;
3328
3329         if (!prs_align(ps))
3330                 return False;
3331                 
3332         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3333                 return False;
3334                 
3335         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3336                 return False;
3337                 
3338         if (!prs_werror("status", ps, depth, &r_u->status))
3339                 return False;
3340
3341         return True;            
3342 }
3343
3344 /*******************************************************************
3345 ********************************************************************/  
3346
3347 bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
3348 {
3349         prs_debug(ps, depth, desc, "");
3350         depth++;
3351
3352         if (!prs_align(ps))
3353                 return False;
3354
3355         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
3356                 return False;
3357         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
3358                 return False;
3359
3360         if (!prs_align(ps))
3361                 return False;
3362         if (!prs_uint32("level", ps, depth, &q_u->level))
3363                 return False;
3364                 
3365         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3366                 return False;
3367
3368         if (!prs_align(ps))
3369                 return False;
3370         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3371                 return False;
3372
3373         return True;
3374 }
3375
3376 /*******************************************************************
3377  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
3378 ********************************************************************/  
3379
3380 bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
3381 {       
3382         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
3383         depth++;
3384                 
3385         if(!prs_align(ps))
3386                 return False;
3387
3388         if(!prs_uint32("flags", ps, depth, &il->flags))
3389                 return False;
3390         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
3391                 return False;
3392         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
3393                 return False;
3394         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3395                 return False;
3396                 
3397         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
3398                 return False;
3399         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3400                 return False;
3401         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3402                 return False;
3403
3404         return True;
3405 }
3406
3407 /*******************************************************************
3408  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
3409 ********************************************************************/  
3410
3411 bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
3412 {       
3413         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
3414         depth++;
3415                 
3416         if(!prs_align(ps))
3417                 return False;
3418
3419         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
3420                 return False;
3421
3422         return True;
3423 }
3424
3425 /*******************************************************************
3426  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
3427 ********************************************************************/  
3428
3429 bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
3430 {       
3431         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
3432         depth++;
3433                 
3434         if(!prs_align(ps))
3435                 return False;
3436
3437         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
3438                 return False;
3439         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
3440                 return False;
3441         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
3442                 return False;
3443         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
3444                 return False;
3445
3446         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
3447                 return False;
3448         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3449                 return False;
3450         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
3451                 return False;
3452         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
3453                 return False;
3454         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
3455                 return False;
3456         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
3457                 return False;
3458         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
3459                 return False;
3460         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
3461                 return False;
3462         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
3463                 return False;
3464
3465         if(!prs_uint32("attributes", ps, depth, &il->attributes))
3466                 return False;
3467         if(!prs_uint32("priority", ps, depth, &il->priority))
3468                 return False;
3469         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
3470                 return False;
3471         if(!prs_uint32("starttime", ps, depth, &il->starttime))
3472                 return False;
3473         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
3474                 return False;
3475         if(!prs_uint32("status", ps, depth, &il->status))
3476                 return False;
3477         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
3478                 return False;
3479         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
3480                 return False;
3481
3482         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
3483                 return False;
3484         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
3485                 return False;
3486         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
3487                 return False;
3488         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
3489                 return False;
3490         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
3491                 return False;
3492         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3493                 return False;
3494         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
3495                 return False;
3496         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
3497                 return False;
3498         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
3499                 return False;
3500         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
3501                 return False;
3502         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
3503                 return False;
3504
3505         return True;
3506 }
3507
3508 bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
3509 {       
3510         prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
3511         depth++;
3512                 
3513         if(!prs_align(ps))
3514                 return False;
3515
3516         if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
3517                 return False;
3518         if(!prs_uint32("action", ps, depth, &il->action))
3519                 return False;
3520
3521         if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
3522                 return False;
3523         return True;
3524 }
3525
3526 /*******************************************************************
3527 ********************************************************************/  
3528
3529 bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
3530 {
3531         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
3532         depth++;
3533
3534         if(!prs_align(ps))
3535                 return False;
3536         if(!prs_uint32("level", ps, depth, &il->level))
3537                 return False;
3538         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
3539                 return False;
3540         
3541         /* if no struct inside just return */
3542         if (il->info_ptr==0) {
3543                 if (UNMARSHALLING(ps)) {
3544                         il->info_1=NULL;
3545                         il->info_2=NULL;
3546                 }
3547                 return True;
3548         }
3549                         
3550         switch (il->level) {
3551                 /*
3552                  * level 0 is used by setprinter when managing the queue
3553                  * (hold, stop, start a queue)
3554                  */
3555                 case 0:
3556                         break;
3557                 /* DOCUMENT ME!!! What is level 1 used for? */
3558                 case 1:
3559                 {
3560                         if (UNMARSHALLING(ps)) {
3561                                 if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
3562                                         return False;
3563                         }
3564                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
3565                                 return False;
3566                         break;          
3567                 }
3568                 /* 
3569                  * level 2 is used by addprinter
3570                  * and by setprinter when updating printer's info
3571                  */     
3572                 case 2:
3573                         if (UNMARSHALLING(ps)) {
3574                                 if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
3575                                         return False;
3576                         }
3577                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
3578                                 return False;
3579                         break;          
3580                 /* DOCUMENT ME!!! What is level 3 used for? */
3581                 case 3:
3582                 {
3583                         if (UNMARSHALLING(ps)) {
3584                                 if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
3585                                         return False;
3586                         }
3587                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
3588                                 return False;
3589                         break;          
3590                 }
3591                 case 7:
3592                         if (UNMARSHALLING(ps))
3593                                 if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
3594                                         return False;
3595                         if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
3596                                 return False;
3597                         break;
3598         }
3599
3600         return True;
3601 }
3602
3603 /*******************************************************************
3604 ********************************************************************/  
3605
3606 bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
3607 {
3608         uint32 ptr_sec_desc = 0;
3609
3610         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
3611         depth++;
3612
3613         if(!prs_align(ps))
3614                 return False;
3615
3616         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
3617                 return False;
3618         if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
3619                 return False;
3620
3621         if(!prs_align(ps))
3622                 return False;
3623
3624         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3625                 return False;
3626         
3627         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3628                 return False;
3629         
3630         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3631                 return False;
3632
3633         if(!prs_align(ps))
3634                 return False;
3635
3636         switch (q_u->level) {
3637                 case 2:
3638                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3639                         break;
3640                 case 3:
3641                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3642                         break;
3643         }
3644         if (ptr_sec_desc) {
3645                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3646                         return False;
3647         } else {
3648                 uint32 dummy = 0;
3649
3650                 /* Parse a NULL security descriptor.  This should really
3651                         happen inside the sec_io_desc_buf() function. */
3652
3653                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3654                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3655                         return False;
3656                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3657                         return False;
3658         }
3659
3660         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
3661                 return False;
3662         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
3663                 return False;
3664
3665         return True;
3666 }
3667
3668 /*******************************************************************
3669 ********************************************************************/  
3670
3671 bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
3672                                prs_struct *ps, int depth)
3673 {
3674         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
3675         depth++;
3676         
3677         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
3678                 return False;
3679
3680         if(!prs_werror("status", ps, depth, &r_u->status))
3681                 return False;
3682
3683         return True;
3684 }
3685
3686 /*******************************************************************
3687 ********************************************************************/  
3688
3689 bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
3690                                           prs_struct *ps, int depth)
3691 {       
3692         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
3693         
3694         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
3695         depth++;
3696                 
3697         /* reading */
3698         if (UNMARSHALLING(ps)) {
3699                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
3700                 if(il == NULL)
3701                         return False;
3702                 *q_u=il;
3703         }
3704         else {
3705                 il=*q_u;
3706         }
3707         
3708         if(!prs_align(ps))
3709                 return False;
3710
3711         if(!prs_uint32("cversion", ps, depth, &il->cversion))
3712                 return False;
3713         if(!prs_uint32("name", ps, depth, &il->name_ptr))
3714                 return False;
3715         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
3716                 return False;
3717         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
3718                 return False;
3719         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
3720                 return False;
3721         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
3722                 return False;
3723         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
3724                 return False;
3725         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
3726                 return False;
3727         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3728                 return False;
3729         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
3730                 return False;
3731         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
3732                 return False;
3733
3734         if(!prs_align(ps))
3735                 return False;
3736         
3737         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3738                 return False;
3739         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
3740                 return False;
3741         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
3742                 return False;
3743         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
3744                 return False;
3745         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
3746                 return False;
3747         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
3748                 return False;
3749         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
3750                 return False;
3751         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
3752                 return False;
3753
3754         if(!prs_align(ps))
3755                 return False;
3756                 
3757         if (il->dependentfiles_ptr)
3758                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
3759
3760         return True;
3761 }
3762
3763 /*******************************************************************
3764 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
3765 ********************************************************************/  
3766
3767 bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
3768                                           prs_struct *ps, int depth)
3769 {       
3770         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
3771         
3772         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
3773         depth++;
3774                 
3775         /* reading */
3776         if (UNMARSHALLING(ps)) {
3777                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
3778                 if(il == NULL)
3779                         return False;
3780                 *q_u=il;
3781         }
3782         else {
3783                 il=*q_u;
3784         }
3785         
3786         if(!prs_align(ps))
3787                 return False;
3788
3789         /* 
3790          * I know this seems weird, but I have no other explanation.
3791          * This is observed behavior on both NT4 and 2K servers.
3792          * --jerry
3793          */
3794          
3795         if (!prs_align_uint64(ps))
3796                 return False;
3797
3798         /* parse the main elements the packet */
3799
3800         if(!prs_uint32("cversion       ", ps, depth, &il->version))
3801                 return False;
3802         if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
3803                 return False;
3804         if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
3805                 return False;
3806         if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
3807                 return False;
3808         if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
3809                 return False;
3810         if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
3811                 return False;
3812         if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
3813                 return False;
3814         if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
3815                 return False;
3816         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3817                 return False;
3818         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
3819                 return False;
3820         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
3821                 return False;
3822         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
3823                 return False;
3824         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
3825                 return False;
3826         if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
3827                 return False;
3828         if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
3829                 return False;
3830         if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
3831                 return False;
3832         if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
3833                 return False;
3834         if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
3835                 return False;
3836         if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
3837                 return False;
3838         if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
3839                 return False;
3840
3841         /* parse the structures in the packet */
3842
3843         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3844                 return False;
3845         if(!prs_align(ps))
3846                 return False;
3847
3848         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
3849                 return False;
3850         if(!prs_align(ps))
3851                 return False;
3852
3853         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
3854                 return False;
3855         if(!prs_align(ps))
3856                 return False;
3857
3858         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
3859                 return False;
3860         if(!prs_align(ps))
3861                 return False;
3862
3863         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
3864                 return False;
3865         if(!prs_align(ps))
3866                 return False;
3867
3868         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
3869                 return False;
3870         if(!prs_align(ps))
3871                 return False;
3872
3873         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
3874                 return False;
3875         if(!prs_align(ps))
3876                 return False;
3877
3878         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
3879                 return False;
3880         if(!prs_align(ps))
3881                 return False;
3882         if (il->dependentfiles_ptr) {
3883                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
3884                         return False;
3885                 if(!prs_align(ps))
3886                         return False;
3887         }
3888         if (il->previousnames_ptr) {
3889                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
3890                         return False;
3891                 if(!prs_align(ps))
3892                         return False;
3893         }
3894         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
3895                 return False;
3896         if(!prs_align(ps))
3897                 return False;
3898         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
3899                 return False;
3900         if(!prs_align(ps))
3901                 return False;
3902         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
3903                 return False;
3904         if(!prs_align(ps))
3905                 return False;
3906         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
3907                 return False;
3908
3909         return True;
3910 }
3911
3912 /*******************************************************************
3913  convert a buffer of UNICODE strings null terminated
3914  the buffer is terminated by a NULL
3915  
3916  convert to an dos codepage array (null terminated)
3917  
3918  dynamically allocate memory
3919  
3920 ********************************************************************/  
3921
3922 static bool uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
3923 {
3924         fstring f;
3925         int n = 0;
3926         char *src;
3927
3928         if (buf5==NULL)
3929                 return False;
3930
3931         src = (char *)buf5->buffer;
3932         *ar = SMB_MALLOC_ARRAY(fstring, 1);
3933         if (!*ar) {
3934                 return False;
3935         }
3936
3937         while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
3938                 rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
3939                 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
3940                 *ar = SMB_REALLOC_ARRAY(*ar, fstring, n+2);
3941                 if (!*ar) {
3942                         return False;
3943                 }
3944                 fstrcpy((*ar)[n], f);
3945                 n++;
3946         }
3947
3948         fstrcpy((*ar)[n], "");
3949  
3950         return True;
3951 }
3952
3953 /*******************************************************************
3954  read a UNICODE array with null terminated strings 
3955  and null terminated array 
3956  and size of array at beginning
3957 ********************************************************************/  
3958
3959 bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
3960 {
3961         if (buffer==NULL) return False;
3962
3963         buffer->offset=0;
3964         buffer->uni_str_len=buffer->uni_max_len;
3965         
3966         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
3967                 return False;
3968
3969         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
3970                 return False;
3971
3972         return True;
3973 }
3974
3975 /*******************************************************************
3976 ********************************************************************/  
3977
3978 bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
3979 {
3980         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
3981         depth++;
3982
3983         if(!prs_align(ps))
3984                 return False;
3985         if(!prs_uint32("level", ps, depth, &il->level))
3986                 return False;
3987         if(!prs_uint32("ptr", ps, depth, &il->ptr))
3988                 return False;
3989
3990         if (il->ptr==0)
3991                 return True;
3992                 
3993         switch (il->level) {
3994                 case 3:
3995                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
3996                                 return False;
3997                         break;          
3998                 case 6:
3999                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
4000                                 return False;
4001                         break;          
4002         default:
4003                 return False;
4004         }
4005
4006         return True;
4007 }
4008
4009 /*******************************************************************
4010  init a SPOOL_Q_ADDPRINTERDRIVER struct
4011  ******************************************************************/
4012
4013 bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
4014                                 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
4015                                 uint32 level, PRINTER_DRIVER_CTR *info)
4016 {
4017         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
4018         
4019         if (!srv_name || !info) {
4020                 return False;
4021         }
4022
4023         q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */
4024         init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
4025         
4026         q_u->level = level;
4027         
4028         q_u->info.level = level;
4029         q_u->info.ptr = 1;      /* Info is != NULL, see above */
4030         switch (level)
4031         {
4032         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
4033         case 3 :
4034                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
4035                 break;
4036                 
4037         default:
4038                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
4039                 break;
4040         }
4041         
4042         return True;
4043 }
4044
4045 bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
4046         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
4047                                 DRIVER_INFO_3 *info3)
4048 {
4049         uint32          len = 0;
4050         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
4051
4052         if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
4053                 return False;
4054
4055         inf->cversion   = info3->version;
4056         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
4057         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
4058         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
4059         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
4060         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
4061         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
4062         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
4063         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
4064
4065         init_unistr2_from_unistr(inf, &inf->name, &info3->name);
4066         init_unistr2_from_unistr(inf, &inf->environment, &info3->architecture);
4067         init_unistr2_from_unistr(inf, &inf->driverpath, &info3->driverpath);
4068         init_unistr2_from_unistr(inf, &inf->datafile, &info3->datafile);
4069         init_unistr2_from_unistr(inf, &inf->configfile, &info3->configfile);
4070         init_unistr2_from_unistr(inf, &inf->helpfile, &info3->helpfile);
4071         init_unistr2_from_unistr(inf, &inf->monitorname, &info3->monitorname);
4072         init_unistr2_from_unistr(inf, &inf->defaultdatatype, &info3->defaultdatatype);
4073
4074         if (info3->dependentfiles) {
4075                 bool done = False;
4076                 bool null_char = False;
4077                 uint16 *ptr = info3->dependentfiles;
4078
4079                 while (!done) {
4080                         switch (*ptr) {
4081                                 case 0:
4082                                         /* the null_char bool is used to help locate
4083                                            two '\0's back to back */
4084                                         if (null_char) {
4085                                                 done = True;
4086                                         } else {
4087                                                 null_char = True;
4088                                         }
4089                                         break;
4090                                         
4091                                 default:
4092                                         null_char = False;
4093                                         break;                          
4094                         }
4095                         len++;
4096                         ptr++;
4097                 }
4098         }
4099
4100         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
4101         inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0;
4102         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) {
4103                 SAFE_FREE(inf);
4104                 return False;
4105         }
4106         
4107         *spool_drv_info = inf;
4108         
4109         return True;
4110 }
4111
4112 /*******************************************************************
4113  make a BUFFER5 struct from a uint16*
4114  ******************************************************************/
4115
4116 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
4117 {
4118
4119         buf5->buf_len = len;
4120         if (src) {
4121                 if (len) {
4122                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
4123                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
4124                                 return False;
4125                         }
4126                 } else {
4127                         buf5->buffer = NULL;
4128                 }
4129         } else {
4130                 buf5->buffer=NULL;
4131         }
4132         
4133         return True;
4134 }
4135
4136 /*******************************************************************
4137  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
4138  ********************************************************************/  
4139
4140 bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
4141 {
4142         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
4143         depth++;
4144
4145         if(!prs_align(ps))
4146                 return False;
4147
4148         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
4149                 return False;
4150         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4151                 return False;
4152                 
4153         if(!prs_align(ps))
4154                 return False;
4155         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4156                 return False;
4157
4158         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
4159                 return False;
4160
4161         return True;
4162 }
4163
4164 /*******************************************************************
4165 ********************************************************************/  
4166
4167 bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
4168 {
4169         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
4170         depth++;
4171
4172         if(!prs_werror("status", ps, depth, &q_u->status))
4173                 return False;
4174
4175         return True;
4176 }
4177
4178 /*******************************************************************
4179  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
4180  ********************************************************************/  
4181
4182 bool spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
4183 {
4184         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
4185         depth++;
4186
4187         if(!prs_align(ps))
4188                 return False;
4189
4190         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
4191                 return False;
4192         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4193                 return False;
4194                 
4195         if(!prs_align(ps))
4196                 return False;
4197         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4198                 return False;
4199
4200         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
4201                 return False;
4202
4203         if(!prs_align(ps))
4204                 return False;
4205         if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
4206                 return False;
4207                 
4208         return True;
4209 }
4210
4211 /*******************************************************************
4212 ********************************************************************/  
4213
4214 bool spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
4215 {
4216         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
4217         depth++;
4218
4219         if(!prs_werror("status", ps, depth, &q_u->status))
4220                 return False;
4221
4222         return True;
4223 }
4224
4225 /*******************************************************************
4226 ********************************************************************/  
4227
4228 bool uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
4229                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
4230 {
4231         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
4232         
4233         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
4234         
4235         if (*asc==NULL)
4236         {
4237                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
4238                 if(*asc == NULL)
4239                         return False;
4240                 ZERO_STRUCTP(*asc);
4241         }       
4242
4243         d=*asc;
4244
4245         d->cversion=uni->cversion;
4246
4247         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name));
4248         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment));
4249         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath));
4250         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile));
4251         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile));
4252         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile));
4253         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname));
4254         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype));
4255
4256         DEBUGADD(8,( "version:         %d\n", d->cversion));
4257         DEBUGADD(8,( "name:            %s\n", d->name));
4258         DEBUGADD(8,( "environment:     %s\n", d->environment));
4259         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
4260         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
4261         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
4262         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
4263         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
4264         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
4265
4266         if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
4267                 return True;
4268         
4269         SAFE_FREE(*asc);
4270         return False;
4271 }
4272
4273 /*******************************************************************
4274 ********************************************************************/  
4275 bool uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
4276                                 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
4277 {
4278         NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
4279         
4280         DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
4281         
4282         if (*asc==NULL)
4283         {
4284                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
4285                 if(*asc == NULL)
4286                         return False;
4287                 ZERO_STRUCTP(*asc);
4288         }       
4289
4290         d=*asc;
4291
4292         d->version=uni->version;
4293
4294         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name));
4295         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment));
4296         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath));
4297         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile));
4298         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile));
4299         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile));
4300         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname));
4301         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype));
4302
4303         DEBUGADD(8,( "version:         %d\n", d->version));
4304         DEBUGADD(8,( "name:            %s\n", d->name));
4305         DEBUGADD(8,( "environment:     %s\n", d->environment));
4306         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
4307         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
4308         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
4309         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
4310         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
4311         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
4312
4313         if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
4314                 goto error;
4315         if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
4316                 goto error;
4317         
4318         return True;
4319         
4320 error:
4321         SAFE_FREE(*asc);
4322         return False;
4323 }
4324
4325 bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
4326                               NT_PRINTER_INFO_LEVEL_2  *d)
4327 {
4328         DEBUG(7,("Converting from UNICODE to ASCII\n"));
4329         
4330         d->attributes=uni->attributes;
4331         d->priority=uni->priority;
4332         d->default_priority=uni->default_priority;
4333         d->starttime=uni->starttime;
4334         d->untiltime=uni->untiltime;
4335         d->status=uni->status;
4336         d->cjobs=uni->cjobs;
4337         
4338         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername));
4339         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername));
4340         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename));
4341         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname));
4342         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername));
4343         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment));
4344         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location));
4345         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile));
4346         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor));
4347         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype));
4348         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters));
4349
4350         return True;
4351 }
4352
4353 /*******************************************************************
4354  * init a structure.
4355  ********************************************************************/
4356
4357 bool make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
4358                                 fstring servername, fstring env_name, uint32 level,
4359                                 RPC_BUFFER *buffer, uint32 offered)
4360 {
4361         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
4362         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
4363
4364         q_u->level=level;
4365         q_u->buffer=buffer;
4366         q_u->offered=offered;
4367
4368         return True;
4369 }
4370
4371 /*******************************************************************
4372  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
4373 ********************************************************************/  
4374
4375 bool spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
4376 {
4377         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
4378         depth++;
4379
4380         if(!prs_align(ps))
4381                 return False;
4382         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4383                 return False;
4384         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
4385                 return False;
4386
4387         if(!prs_align(ps))
4388                 return False;
4389                 
4390         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
4391                 return False;
4392         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4393                 return False;
4394                 
4395         if(!prs_align(ps))
4396                 return False;
4397
4398         if(!prs_uint32("level", ps, depth, &q_u->level))
4399                 return False;
4400                 
4401         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4402                 return False;
4403                 
4404         if(!prs_align(ps))
4405                 return False;
4406                 
4407         if(!prs_uint32("offered", ps, depth, &q_u->offered))
4408                 return False;
4409
4410         return True;
4411 }
4412
4413 /*******************************************************************
4414  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
4415 ********************************************************************/  
4416
4417 bool spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
4418 {               
4419         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
4420         depth++;
4421
4422         if (!prs_align(ps))
4423                 return False;
4424                 
4425         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4426                 return False;
4427
4428         if (!prs_align(ps))
4429                 return False;
4430                 
4431         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4432                 return False;
4433                 
4434         if (!prs_werror("status", ps, depth, &r_u->status))
4435                 return False;
4436
4437         return True;            
4438 }
4439
4440 /*******************************************************************
4441 ********************************************************************/  
4442
4443 bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
4444 {               
4445         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
4446         depth++;
4447
4448         if (!prs_align(ps))
4449                 return False;
4450                 
4451         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4452                 return False;
4453
4454         if (!prs_align(ps))
4455                 return False;
4456                 
4457         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4458                 return False;
4459                 
4460         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4461                 return False;
4462                 
4463         if (!prs_werror("status", ps, depth, &r_u->status))
4464                 return False;
4465
4466         return True;            
4467 }
4468
4469 /*******************************************************************
4470 ********************************************************************/  
4471
4472 bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
4473 {
4474         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
4475         depth++;
4476
4477         if (!prs_align(ps))
4478                 return False;
4479                 
4480         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4481                 return False;
4482         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4483                 return False;
4484                 
4485         if (!prs_align(ps))
4486                 return False;
4487                 
4488         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
4489                 return False;
4490         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4491                 return False;
4492         
4493         if (!prs_align(ps))
4494                 return False;
4495                 
4496         if (!prs_uint32("level", ps, depth, &q_u->level))
4497                 return False;
4498                 
4499         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4500                 return False;
4501
4502         if (!prs_align(ps))
4503                 return False;
4504
4505         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4506                 return False;
4507
4508         return True;
4509 }
4510
4511 /*******************************************************************
4512 ********************************************************************/  
4513
4514 bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
4515 {               
4516         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
4517         depth++;
4518
4519         if (!prs_align(ps))
4520                 return False;
4521                 
4522         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4523                 return False;
4524
4525         if (!prs_align(ps))
4526                 return False;
4527                 
4528         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4529                 return False;
4530                 
4531         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4532                 return False;
4533                 
4534         if (!prs_werror("status", ps, depth, &r_u->status))
4535                 return False;
4536
4537         return True;            
4538 }
4539
4540 /*******************************************************************
4541 ********************************************************************/  
4542
4543 bool spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
4544 {
4545         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
4546         depth++;
4547
4548         if (!prs_align(ps))
4549                 return False;
4550                 
4551         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4552                 return False;
4553         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4554                 return False;
4555                 
4556         if (!prs_align(ps))
4557                 return False;
4558                 
4559         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
4560                 return False;
4561         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
4562                 return False;
4563         
4564         if (!prs_align(ps))
4565                 return False;
4566                 
4567         if (!prs_uint32("level", ps, depth, &q_u->level))
4568                 return False;
4569                 
4570         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
4571                 return False;
4572
4573         if (!prs_align(ps))
4574                 return False;
4575
4576         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4577                 return False;
4578
4579         return True;
4580 }
4581
4582 /*******************************************************************
4583  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
4584 ********************************************************************/  
4585
4586 bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
4587 {
4588         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
4589         depth++;
4590
4591         if (!prs_align(ps))
4592                 return False;
4593                 
4594         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4595                 return False;
4596         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4597                 return False;
4598                 
4599         if (!prs_align(ps))
4600                 return False;
4601                                 
4602         if (!prs_uint32("level", ps, depth, &q_u->level))
4603                 return False;
4604                 
4605         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4606                 return False;
4607
4608         if (!prs_align(ps))
4609                 return False;
4610
4611         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4612                 return False;
4613
4614         return True;
4615 }
4616
4617 /*******************************************************************
4618 ********************************************************************/  
4619
4620 bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
4621 {               
4622         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
4623         depth++;
4624
4625         if (!prs_align(ps))
4626                 return False;
4627                 
4628         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4629                 return False;
4630
4631         if (!prs_align(ps))
4632                 return False;
4633                 
4634         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4635                 return False;
4636                 
4637         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4638                 return False;
4639                 
4640         if (!prs_werror("status", ps, depth, &r_u->status))
4641                 return False;
4642
4643         return True;            
4644 }
4645
4646 /*******************************************************************
4647 ********************************************************************/  
4648
4649 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
4650 {       
4651         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
4652         depth++;
4653
4654         if(!prs_align(ps))
4655                 return False;
4656         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
4657                 return False;
4658
4659         if (UNMARSHALLING(ps) && r_u->valuesize) {
4660                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
4661                 if (!r_u->value) {
4662                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
4663                         return False;
4664                 }
4665         }
4666
4667         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
4668                 return False;
4669
4670         if(!prs_align(ps))
4671                 return False;
4672
4673         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
4674                 return False;
4675
4676         if(!prs_uint32("type", ps, depth, &r_u->type))
4677                 return False;
4678
4679         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
4680                 return False;
4681
4682         if (UNMARSHALLING(ps) && r_u->datasize) {
4683                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
4684                 if (!r_u->data) {
4685                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
4686                         return False;
4687                 }
4688         }
4689
4690         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
4691                 return False;
4692         if(!prs_align(ps))
4693                 return False;
4694
4695         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
4696                 return False;
4697         if(!prs_werror("status", ps, depth, &r_u->status))
4698                 return False;
4699
4700         return True;
4701 }
4702
4703 /*******************************************************************
4704 ********************************************************************/  
4705
4706 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
4707 {
4708         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
4709         depth++;
4710
4711         if(!prs_align(ps))
4712                 return False;
4713         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4714                 return False;
4715         if(!prs_uint32("index", ps, depth, &q_u->index))
4716                 return False;
4717         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
4718                 return False;
4719         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
4720                 return False;
4721
4722         return True;
4723 }
4724
4725 /*******************************************************************
4726 ********************************************************************/  
4727
4728 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
4729                 const POLICY_HND *hnd,
4730                 uint32 idx, uint32 valuelen, uint32 datalen)
4731 {
4732         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4733         q_u->index=idx;
4734         q_u->valuesize=valuelen;
4735         q_u->datasize=datalen;
4736
4737         return True;
4738 }
4739
4740 /*******************************************************************
4741 ********************************************************************/  
4742
4743 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
4744                                       const POLICY_HND *hnd, const char *key,
4745                                       uint32 size)
4746 {
4747         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4748         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
4749         q_u->size = size;
4750
4751         return True;
4752 }
4753
4754 /*******************************************************************
4755 ********************************************************************/  
4756 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
4757                                    char* value, uint32 data_type, char* data, uint32 data_size)
4758 {
4759         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4760         q_u->type = data_type;
4761         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
4762
4763         q_u->max_len = q_u->real_len = data_size;
4764         q_u->data = (unsigned char *)data;
4765         
4766         return True;
4767 }
4768
4769 /*******************************************************************
4770 ********************************************************************/  
4771
4772 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
4773 {
4774         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
4775         depth++;
4776
4777         if(!prs_align(ps))
4778                 return False;
4779         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4780                 return False;
4781         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
4782                 return False;
4783
4784         if(!prs_align(ps))
4785                 return False;
4786
4787         if(!prs_uint32("type", ps, depth, &q_u->type))
4788                 return False;
4789
4790         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
4791                 return False;
4792
4793         switch (q_u->type)
4794         {
4795                 case REG_SZ:
4796                 case REG_BINARY:
4797                 case REG_DWORD:
4798                 case REG_MULTI_SZ:
4799                         if (q_u->max_len) {
4800                                 if (UNMARSHALLING(ps))
4801                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
4802                                 if(q_u->data == NULL)
4803                                         return False;
4804                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
4805                                         return False;
4806                         }
4807                         if(!prs_align(ps))
4808                                 return False;
4809                         break;
4810         }       
4811         
4812         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
4813                 return False;
4814
4815         return True;
4816 }
4817
4818 /*******************************************************************
4819 ********************************************************************/  
4820
4821 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
4822 {
4823         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
4824         depth++;
4825
4826         if(!prs_align(ps))
4827                 return False;
4828         if(!prs_werror("status",     ps, depth, &r_u->status))
4829                 return False;
4830
4831         return True;
4832 }
4833
4834 /*******************************************************************
4835 ********************************************************************/  
4836 bool spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
4837 {
4838         prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
4839         depth++;
4840
4841         if (!prs_align(ps))
4842                 return False;
4843         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4844                 return False;
4845
4846         if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
4847                 return False;
4848                 
4849         if (q_u->datatype_ptr) {
4850                 if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
4851                 return False;
4852         }
4853
4854         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4855                 return False;
4856
4857         return True;
4858 }
4859
4860
4861 /*******************************************************************
4862 ********************************************************************/  
4863 bool spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
4864 {
4865         prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
4866         depth++;
4867
4868         if(!prs_align(ps))
4869                 return False;
4870         if(!prs_werror("status",     ps, depth, &r_u->status))
4871                 return False;
4872
4873         return True;
4874 }
4875
4876 /*******************************************************************
4877  Parse a SPOOL_R_GETJOB structure.
4878 ********************************************************************/  
4879
4880 bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
4881 {               
4882         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
4883         depth++;
4884
4885         if (!prs_align(ps))
4886                 return False;
4887                 
4888         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4889                 return False;
4890
4891         if (!prs_align(ps))
4892                 return False;
4893                 
4894         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4895                 return False;
4896                 
4897         if (!prs_werror("status", ps, depth, &r_u->status))
4898                 return False;
4899
4900         return True;            
4901 }
4902
4903 /*******************************************************************
4904  Parse a SPOOL_Q_GETJOB structure.
4905 ********************************************************************/  
4906
4907 bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
4908 {
4909         prs_debug(ps, depth, desc, "");
4910         depth++;
4911
4912         if(!prs_align(ps))
4913                 return False;
4914
4915         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4916                 return False;
4917         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4918                 return False;
4919         if(!prs_uint32("level", ps, depth, &q_u->level))
4920                 return False;
4921         
4922         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4923                 return False;
4924
4925         if(!prs_align(ps))
4926                 return False;
4927         
4928         if(!prs_uint32("offered", ps, depth, &q_u->offered))
4929                 return False;
4930
4931         return True;
4932 }
4933
4934 void free_devmode(DEVICEMODE *devmode)
4935 {
4936         if (devmode!=NULL) {
4937                 SAFE_FREE(devmode->dev_private);
4938                 SAFE_FREE(devmode);
4939         }
4940 }
4941
4942 void free_printer_info_1(PRINTER_INFO_1 *printer)
4943 {
4944         SAFE_FREE(printer);
4945 }
4946
4947 void free_printer_info_2(PRINTER_INFO_2 *printer)
4948 {
4949         if (printer!=NULL) {
4950                 free_devmode(printer->devmode);
4951                 printer->devmode = NULL;
4952                 SAFE_FREE(printer);
4953         }
4954 }
4955
4956 void free_printer_info_3(PRINTER_INFO_3 *printer)
4957 {
4958         SAFE_FREE(printer);
4959 }
4960
4961 void free_printer_info_4(PRINTER_INFO_4 *printer)
4962 {
4963         SAFE_FREE(printer);
4964 }
4965
4966 void free_printer_info_5(PRINTER_INFO_5 *printer)
4967 {
4968         SAFE_FREE(printer);
4969 }
4970
4971 void free_printer_info_6(PRINTER_INFO_6 *printer)
4972 {
4973         SAFE_FREE(printer);
4974 }
4975
4976 void free_printer_info_7(PRINTER_INFO_7 *printer)
4977 {
4978         SAFE_FREE(printer);
4979 }
4980
4981 void free_job_info_2(JOB_INFO_2 *job)
4982 {
4983     if (job!=NULL)
4984         free_devmode(job->devmode);
4985 }
4986
4987 #if 0   /* JERRY - not currently used but could be :-) */
4988
4989 /*******************************************************************
4990  Deep copy a SPOOL_NOTIFY_INFO_DATA structure
4991  ******************************************************************/
4992 static bool copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, 
4993                                 SPOOL_NOTIFY_INFO_DATA *src, int n)
4994 {
4995         int i;
4996
4997         memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
4998         
4999         for (i=0; i<n; i++) {
5000                 int len;
5001                 uint16 *s = NULL;
5002                 
5003                 if (src->size != POINTER) 
5004                         continue;
5005                 len = src->notify_data.data.length;
5006                 s = SMB_MALLOC_ARRAY(uint16, len);
5007                 if (s == NULL) {
5008                         DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
5009                         return False;
5010                 }
5011                 
5012                 memcpy(s, src->notify_data.data.string, len*2);
5013                 dst->notify_data.data.string = s;
5014         }
5015         
5016         return True;
5017 }
5018
5019 /*******************************************************************
5020  Deep copy a SPOOL_NOTIFY_INFO structure
5021  ******************************************************************/
5022 static bool copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
5023 {
5024         if (!dst) {
5025                 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
5026                 return False;
5027         }
5028                 
5029         dst->version = src->version;
5030         dst->flags   = src->flags;
5031         dst->count   = src->count;
5032         
5033         if (dst->count) 
5034         {
5035                 dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count);
5036                 
5037                 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
5038                         dst->count));
5039
5040                 if (dst->data == NULL) {
5041                         DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", 
5042                                 dst->count));
5043                         return False;
5044                 }
5045                 
5046                 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
5047         }
5048         
5049         return True;
5050 }
5051 #endif  /* JERRY */
5052
5053 /*******************************************************************
5054  * init a structure.
5055  ********************************************************************/
5056
5057 bool make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
5058                                 uint32 change_low, uint32 change_high,
5059                                 SPOOL_NOTIFY_INFO *info)
5060 {      
5061         if (q_u == NULL)
5062                 return False;
5063
5064         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5065
5066         q_u->change_low=change_low;
5067         q_u->change_high=change_high;
5068
5069         q_u->unknown0=0x0;
5070         q_u->unknown1=0x0;
5071
5072         q_u->info_ptr=0x0FF0ADDE;
5073
5074         q_u->info.version=2;
5075         
5076         if (info->count) {
5077                 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
5078                         info->count));
5079                 q_u->info.version = info->version;
5080                 q_u->info.flags   = info->flags;
5081                 q_u->info.count   = info->count;
5082                 /* pointer field - be careful! */
5083                 q_u->info.data    = info->data;
5084         }
5085         else  {
5086         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
5087         q_u->info.count=0;
5088         }
5089
5090         return True;
5091 }
5092
5093 /*******************************************************************
5094  Parse a SPOOL_Q_REPLY_RRPCN structure.
5095 ********************************************************************/  
5096
5097 bool spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
5098 {
5099         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
5100         depth++;
5101
5102         if(!prs_align(ps))
5103                 return False;
5104
5105         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5106                 return False;
5107
5108         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
5109                 return False;
5110
5111         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
5112                 return False;
5113
5114         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
5115                 return False;
5116
5117         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
5118                 return False;
5119
5120         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
5121                 return False;
5122
5123         if(q_u->info_ptr!=0)
5124                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
5125                         return False;
5126                 
5127         return True;
5128 }
5129
5130 /*******************************************************************
5131  Parse a SPOOL_R_REPLY_RRPCN structure.
5132 ********************************************************************/  
5133
5134 bool spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
5135 {               
5136         prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
5137         depth++;
5138
5139         if (!prs_align(ps))
5140                 return False;
5141
5142         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
5143                 return False;
5144
5145         if (!prs_werror("status", ps, depth, &r_u->status))
5146                 return False;
5147
5148         return True;            
5149 }
5150
5151 /*******************************************************************
5152  * read a structure.
5153  ********************************************************************/  
5154 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
5155                                    POLICY_HND *hnd, const char *key, 
5156                                    uint32 size)
5157 {
5158         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
5159
5160         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5161         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5162         q_u->size = size;
5163
5164         return True;
5165 }
5166
5167 /*******************************************************************
5168  * read a structure.
5169  ********************************************************************/  
5170
5171 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
5172 {
5173         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
5174         depth++;
5175
5176         if(!prs_align(ps))
5177                 return False;
5178         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5179                 return False;
5180                 
5181         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
5182                 return False;
5183
5184         if(!prs_align(ps))
5185                 return False;
5186         
5187         if(!prs_uint32("size", ps, depth, &q_u->size))
5188                 return False;
5189
5190         return True;
5191 }
5192
5193 /*******************************************************************
5194  * write a structure.
5195  ********************************************************************/  
5196
5197 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
5198 {
5199         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
5200         depth++;
5201
5202         if(!prs_align(ps))
5203                 return False;
5204
5205         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
5206                 return False;
5207         
5208         if(!prs_align(ps))
5209                 return False;
5210
5211         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
5212                 return False;
5213
5214         if(!prs_werror("status",     ps, depth, &r_u->status))
5215                 return False;
5216
5217         return True;
5218 }
5219
5220 /*******************************************************************
5221  * read a structure.
5222  ********************************************************************/  
5223
5224 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
5225 {
5226         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
5227         depth++;
5228
5229         if(!prs_align(ps))
5230                 return False;
5231         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5232                 return False;
5233                 
5234         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
5235                 return False;
5236
5237         if(!prs_align(ps))
5238                 return False;
5239         
5240         if(!prs_uint32("size", ps, depth, &q_u->size))
5241                 return False;
5242
5243         return True;
5244 }
5245
5246 /*******************************************************************
5247 ********************************************************************/  
5248
5249 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
5250                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
5251 {
5252         int     i;
5253         uint32  valuename_offset,
5254                 data_offset,
5255                 current_offset;
5256         const uint32 basic_unit = 20; /* size of static portion of enum_values */
5257
5258         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
5259         depth++;        
5260
5261         /* 
5262          * offset data begins at 20 bytes per structure * size_of_array.
5263          * Don't forget the uint32 at the beginning 
5264          * */
5265         
5266         current_offset = basic_unit * ctr->size_of_array;
5267         
5268         /* first loop to write basic enum_value information */
5269         
5270         if (UNMARSHALLING(ps) && ctr->size_of_array) {
5271                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
5272                 if (!ctr->values)
5273                         return False;
5274         }
5275
5276         for (i=0; i<ctr->size_of_array; i++) {
5277                 uint32 base_offset, return_offset;
5278
5279                 base_offset = prs_offset(ps);
5280
5281                 valuename_offset = current_offset;
5282                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
5283                         return False;
5284
5285                 /* Read or write the value. */
5286
5287                 return_offset = prs_offset(ps);
5288
5289                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
5290                         return False;
5291                 }
5292
5293                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
5294                         return False;
5295
5296                 /* And go back. */
5297                 if (!prs_set_offset(ps, return_offset))
5298                         return False;
5299
5300                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
5301                         return False;
5302         
5303                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
5304                         return False;
5305         
5306                 data_offset = ctr->values[i].value_len + valuename_offset;
5307                 
5308                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
5309                         return False;
5310
5311                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
5312                         return False;
5313                         
5314                 /* Read or write the data. */
5315
5316                 return_offset = prs_offset(ps);
5317
5318                 if (!prs_set_offset(ps, base_offset + data_offset)) {
5319                         return False;
5320                 }
5321
5322                 if ( ctr->values[i].data_len ) {
5323                         if ( UNMARSHALLING(ps) ) {
5324                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
5325                                 if (!ctr->values[i].data)
5326                                         return False;
5327                         }
5328                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
5329                                 return False;
5330                 }
5331
5332                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
5333                 /* account for 2 byte alignment */
5334                 current_offset += (current_offset % 2);
5335
5336                 /* Remember how far we got. */
5337                 data_offset = prs_offset(ps);
5338
5339                 /* And go back. */
5340                 if (!prs_set_offset(ps, return_offset))
5341                         return False;
5342
5343         }
5344
5345         /* Go to the last data offset we got to. */
5346
5347         if (!prs_set_offset(ps, data_offset))
5348                 return False;
5349
5350         /* And ensure we're 2 byte aligned. */
5351
5352         if ( !prs_align_uint16(ps) )
5353                 return False;
5354
5355         return True;    
5356 }
5357
5358 /*******************************************************************
5359  * write a structure.
5360  ********************************************************************/  
5361
5362 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
5363 {
5364         uint32 data_offset, end_offset;
5365         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
5366         depth++;
5367
5368         if(!prs_align(ps))
5369                 return False;
5370
5371         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
5372                 return False;
5373
5374         data_offset = prs_offset(ps);
5375
5376         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
5377                 return False;
5378
5379         if(!prs_align(ps))
5380                 return False;
5381
5382         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
5383                 return False;
5384
5385         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
5386                 return False;
5387
5388         if(!prs_werror("status",     ps, depth, &r_u->status))
5389                 return False;
5390
5391         r_u->ctr.size_of_array = r_u->returned;
5392
5393         end_offset = prs_offset(ps);
5394
5395         if (!prs_set_offset(ps, data_offset))
5396                 return False;
5397
5398         if (r_u->ctr.size)
5399                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
5400                         return False;
5401
5402         if (!prs_set_offset(ps, end_offset))
5403                 return False;
5404         return True;
5405 }
5406
5407 /*******************************************************************
5408  * write a structure.
5409  ********************************************************************/  
5410
5411 /* 
5412    uint32 GetPrintProcessorDirectory(
5413        [in] unistr2 *name,
5414        [in] unistr2 *environment,
5415        [in] uint32 level,
5416        [in,out] RPC_BUFFER buffer,
5417        [in] uint32 offered,
5418        [out] uint32 needed,
5419        [out] uint32 returned
5420    );
5421
5422 */
5423
5424 bool make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered)
5425 {
5426         DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
5427
5428         init_unistr2(&q_u->name, name, UNI_STR_TERMINATE);
5429         init_unistr2(&q_u->environment, environment, UNI_STR_TERMINATE);
5430
5431         q_u->level = level;
5432
5433         q_u->buffer = buffer;
5434         q_u->offered = offered;
5435
5436         return True;
5437 }
5438
5439 bool spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
5440 {
5441         uint32 ptr = 0;
5442
5443         prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
5444         depth++;
5445
5446         if(!prs_align(ps))
5447                 return False;   
5448
5449         if (!prs_uint32("ptr", ps, depth, &ptr)) 
5450                 return False;
5451
5452         if (ptr) {
5453                 if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5454                         return False;
5455         }
5456
5457         if (!prs_align(ps))
5458                 return False;
5459
5460         if (!prs_uint32("ptr", ps, depth, &ptr))
5461                 return False;
5462
5463         if (ptr) {
5464                 if(!smb_io_unistr2("environment", &q_u->environment, True, 
5465                                    ps, depth))
5466                         return False;
5467         }
5468
5469         if (!prs_align(ps))
5470                 return False;
5471
5472         if(!prs_uint32("level",   ps, depth, &q_u->level))
5473                 return False;
5474
5475         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5476                 return False;
5477         
5478         if(!prs_align(ps))
5479                 return False;
5480
5481         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5482                 return False;
5483
5484         return True;
5485 }
5486
5487 /*******************************************************************
5488  * write a structure.
5489  ********************************************************************/  
5490
5491 bool spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
5492 {
5493         prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
5494         depth++;
5495
5496         if(!prs_align(ps))
5497                 return False;
5498
5499         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5500                 return False;
5501         
5502         if(!prs_align(ps))
5503                 return False;
5504
5505         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
5506                 return False;
5507                 
5508         if(!prs_werror("status",     ps, depth, &r_u->status))
5509                 return False;
5510
5511         return True;
5512 }
5513
5514 bool smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
5515 {
5516         prs_struct *ps=&buffer->prs;
5517
5518         prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
5519         depth++;
5520
5521         buffer->struct_start=prs_offset(ps);
5522
5523         if (!smb_io_unistr(desc, &info->name, ps, depth))
5524                 return False;
5525
5526         return True;
5527 }
5528
5529 /*******************************************************************
5530  * init a structure.
5531  ********************************************************************/
5532
5533 bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
5534                               uint32 level, RPC_BUFFER *buffer,
5535                               uint32 offered)
5536 {
5537         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
5538         q_u->level = level;
5539         q_u->buffer=buffer;
5540         q_u->offered=offered;
5541
5542         return True;
5543 }
5544
5545 /*******************************************************************
5546  * init a structure.
5547  ********************************************************************/
5548
5549 bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
5550                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
5551                            uint32 offered)
5552 {
5553         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
5554         q_u->jobid = jobid;
5555         q_u->level = level;
5556         q_u->buffer = buffer;
5557         q_u->offered = offered;
5558
5559         return True;
5560 }
5561
5562 /*******************************************************************
5563  * init a structure.
5564  ********************************************************************/
5565
5566 bool make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
5567                              uint32 flags, uint32 options, const char *localmachine,
5568                              uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
5569 {
5570         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
5571
5572         q_u->flags = flags;
5573         q_u->options = options;
5574
5575         q_u->localmachine_ptr = 1;
5576
5577         init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
5578
5579         q_u->printerlocal = printerlocal;
5580
5581         if (option)
5582                 q_u->option_ptr = 1;
5583
5584         q_u->option = option;
5585
5586         return True;
5587 }
5588
5589
5590 /*******************************************************************
5591  ********************************************************************/  
5592
5593 bool spoolss_io_q_xcvdataport(const char *desc, SPOOL_Q_XCVDATAPORT *q_u, prs_struct *ps, int depth)
5594 {
5595         prs_debug(ps, depth, desc, "spoolss_io_q_xcvdataport");
5596         depth++;
5597
5598         if(!prs_align(ps))
5599                 return False;   
5600
5601         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5602                 return False;
5603                 
5604         if(!smb_io_unistr2("", &q_u->dataname, True, ps, depth))
5605                 return False;
5606
5607         if (!prs_align(ps))
5608                 return False;
5609
5610         if(!prs_rpcbuffer("", ps, depth, &q_u->indata))
5611                 return False;
5612                 
5613         if (!prs_align(ps))
5614                 return False;
5615
5616         if (!prs_uint32("indata_len", ps, depth, &q_u->indata_len))
5617                 return False;
5618         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5619                 return False;
5620         if (!prs_uint32("unknown", ps, depth, &q_u->unknown))
5621                 return False;
5622         
5623         return True;
5624 }
5625
5626 /*******************************************************************
5627  ********************************************************************/  
5628
5629 bool spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_struct *ps, int depth)
5630 {
5631         prs_debug(ps, depth, desc, "spoolss_io_r_xcvdataport");
5632         depth++;
5633
5634         if(!prs_align(ps))
5635                 return False;
5636         if(!prs_rpcbuffer("", ps, depth, &r_u->outdata))
5637                 return False;
5638                 
5639         if (!prs_align(ps))
5640                 return False;
5641
5642         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5643                 return False;
5644         if (!prs_uint32("unknown", ps, depth, &r_u->unknown))
5645                 return False;
5646
5647         if(!prs_werror("status", ps, depth, &r_u->status))
5648                 return False;
5649
5650         return True;
5651 }
5652
5653 /*******************************************************************
5654  ********************************************************************/  
5655
5656 bool make_monitorui_buf( RPC_BUFFER *buf, const char *dllname )
5657 {
5658         UNISTR string;
5659         
5660         if ( !buf )
5661                 return False;
5662
5663         init_unistr( &string, dllname );
5664
5665         if ( !prs_unistr( "ui_dll", &buf->prs, 0, &string ) )
5666                 return False;
5667
5668         return True;
5669 }
5670
5671 /*******************************************************************
5672  ********************************************************************/  
5673  
5674 #define PORT_DATA_1_PAD    540
5675
5676 static bool smb_io_port_data_1( const char *desc, RPC_BUFFER *buf, int depth, SPOOL_PORT_DATA_1 *p1 )
5677 {
5678         prs_struct *ps = &buf->prs;
5679         uint8 padding[PORT_DATA_1_PAD];
5680
5681         prs_debug(ps, depth, desc, "smb_io_port_data_1");
5682         depth++;
5683
5684         if(!prs_align(ps))
5685                 return False;   
5686
5687         if( !prs_uint16s(True, "portname", ps, depth, p1->portname, MAX_PORTNAME))
5688                 return False;
5689
5690         if (!prs_uint32("version", ps, depth, &p1->version))
5691                 return False;
5692         if (!prs_uint32("protocol", ps, depth, &p1->protocol))
5693                 return False;
5694         if (!prs_uint32("size", ps, depth, &p1->size))
5695                 return False;
5696         if (!prs_uint32("reserved", ps, depth, &p1->reserved))
5697                 return False;
5698
5699         if( !prs_uint16s(True, "hostaddress", ps, depth, p1->hostaddress, MAX_NETWORK_NAME))
5700                 return False;
5701         if( !prs_uint16s(True, "snmpcommunity", ps, depth, p1->snmpcommunity, MAX_SNMP_COMM_NAME))
5702                 return False;
5703
5704         if (!prs_uint32("dblspool", ps, depth, &p1->dblspool))
5705                 return False;
5706                 
5707         if( !prs_uint16s(True, "queue", ps, depth, p1->queue, MAX_QUEUE_NAME))
5708                 return False;
5709         if( !prs_uint16s(True, "ipaddress", ps, depth, p1->ipaddress, MAX_IPADDR_STRING))
5710                 return False;
5711
5712         if( !prs_uint8s(False, "", ps, depth, padding, PORT_DATA_1_PAD))
5713                 return False;
5714                 
5715         if (!prs_uint32("port", ps, depth, &p1->port))
5716                 return False;
5717         if (!prs_uint32("snmpenabled", ps, depth, &p1->snmpenabled))
5718                 return False;
5719         if (!prs_uint32("snmpdevindex", ps, depth, &p1->snmpdevindex))
5720                 return False;
5721                 
5722         return True;
5723 }
5724
5725 /*******************************************************************
5726  ********************************************************************/  
5727
5728 bool convert_port_data_1( NT_PORT_DATA_1 *port1, RPC_BUFFER *buf ) 
5729 {
5730         SPOOL_PORT_DATA_1 spdata_1;
5731         
5732         ZERO_STRUCT( spdata_1 );
5733         
5734         if ( !smb_io_port_data_1( "port_data_1", buf, 0, &spdata_1 ) )
5735                 return False;
5736                 
5737         rpcstr_pull(port1->name, spdata_1.portname, sizeof(port1->name), -1, 0);
5738         rpcstr_pull(port1->queue, spdata_1.queue, sizeof(port1->queue), -1, 0);
5739         rpcstr_pull(port1->hostaddr, spdata_1.hostaddress, sizeof(port1->hostaddr), -1, 0);
5740         
5741         port1->port = spdata_1.port;
5742         
5743         switch ( spdata_1.protocol ) {
5744         case 1:
5745                 port1->protocol = PORT_PROTOCOL_DIRECT;
5746                 break;
5747         case 2:
5748                 port1->protocol = PORT_PROTOCOL_LPR;
5749                 break;
5750         default:
5751                 DEBUG(3,("convert_port_data_1: unknown protocol [%d]!\n", 
5752                         spdata_1.protocol));
5753                 return False;
5754         }
5755
5756         return True;
5757 }