s3-spoolss: remove old spoolss_StartDocPrinter.
[ab/samba.git/.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 ********************************************************************/  
762
763 static bool spoolss_io_printer_default(const char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
764 {
765         if (pd==NULL)
766                 return False;
767
768         prs_debug(ps, depth, desc, "spoolss_io_printer_default");
769         depth++;
770
771         if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
772                 return False;
773
774         if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
775                 return False;
776         
777         if (!prs_align(ps))
778                 return False;
779
780         if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
781                 return False;
782
783         if (!prs_align(ps))
784                 return False;
785
786         if (!prs_uint32("access_required", ps, depth, &pd->access_required))
787                 return False;
788
789         return True;
790 }
791
792 /*******************************************************************
793  * init a structure.
794  ********************************************************************/
795
796 bool make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
797                 const fstring printername, 
798                 const fstring datatype, 
799                 uint32 access_required,
800                 const fstring clientname,
801                 const fstring user_name)
802 {
803         DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
804
805         q_u->printername = TALLOC_P( talloc_tos(), UNISTR2 );
806         if (!q_u->printername) {
807                 return False;
808         }
809         init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
810
811         q_u->printer_default.datatype_ptr = 0;
812
813         q_u->printer_default.devmode_cont.size=0;
814         q_u->printer_default.devmode_cont.devmode_ptr=0;
815         q_u->printer_default.devmode_cont.devmode=NULL;
816         q_u->printer_default.access_required=access_required;
817
818         q_u->user_switch = 1;
819         
820         q_u->user_ctr.level                 = 1;
821         q_u->user_ctr.user.user1            = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
822         if (!q_u->user_ctr.user.user1) {
823                 return False;
824         }
825         q_u->user_ctr.user.user1->size      = strlen(clientname) + strlen(user_name) + 10;
826         q_u->user_ctr.user.user1->build     = 1381;
827         q_u->user_ctr.user.user1->major     = 2;
828         q_u->user_ctr.user.user1->minor     = 0;
829         q_u->user_ctr.user.user1->processor = 0;
830
831         q_u->user_ctr.user.user1->client_name = TALLOC_P( talloc_tos(), UNISTR2 );
832         if (!q_u->user_ctr.user.user1->client_name) {
833                 return False;
834         }
835         q_u->user_ctr.user.user1->user_name   = TALLOC_P( talloc_tos(), UNISTR2 );
836         if (!q_u->user_ctr.user.user1->user_name) {
837                 return False;
838         }
839
840         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
841         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
842         
843         return True;
844 }
845
846 /*******************************************************************
847  * init a structure.
848  ********************************************************************/
849
850 bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
851         const char *srv_name, const char* clientname, const char* user_name,
852         uint32 level, PRINTER_INFO_CTR *ctr)
853 {
854         DEBUG(5,("make_spoolss_q_addprinterex\n"));
855         
856         if (!ctr || !ctr->printers_2) 
857                 return False;
858
859         ZERO_STRUCTP(q_u);
860
861         q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
862         if (!q_u->server_name) {
863                 return False;
864         }
865         init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
866
867         q_u->level = level;
868         
869         q_u->info.level = level;
870         q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
871         switch (level) {
872                 case 2:
873                         /* init q_u->info.info2 from *info */
874                         if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
875                                 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
876                                 return False;
877                         }
878                         break;
879                 default :
880                         break;
881         }
882
883         q_u->user_switch=1;
884
885         q_u->user_ctr.level                 = 1;
886         q_u->user_ctr.user.user1            = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
887         if (!q_u->user_ctr.user.user1) {
888                 return False;
889         }
890         q_u->user_ctr.user.user1->build     = 1381;
891         q_u->user_ctr.user.user1->major     = 2; 
892         q_u->user_ctr.user.user1->minor     = 0;
893         q_u->user_ctr.user.user1->processor = 0;
894
895         q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
896         if (!q_u->user_ctr.user.user1->client_name) {
897                 return False;
898         }
899         q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
900         if (!q_u->user_ctr.user.user1->user_name) {
901                 return False;
902         }
903         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
904         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
905
906         q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
907                                    q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
908         
909         return True;
910 }
911         
912 /*******************************************************************
913 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
914 *******************************************************************/
915
916 bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
917                                 PRINTER_INFO_2 *info)
918 {
919
920         SPOOL_PRINTER_INFO_LEVEL_2 *inf;
921
922         /* allocate the necessary memory */
923         if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
924                 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
925                 return False;
926         }
927
928         inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
929         inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
930         inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
931         inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
932         inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
933         inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
934         inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
935         inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
936         inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
937         inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
938         inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
939         inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
940         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
941         inf->attributes         = info->attributes;
942         inf->priority           = info->priority;
943         inf->default_priority   = info->defaultpriority;
944         inf->starttime          = info->starttime;
945         inf->untiltime          = info->untiltime;
946         inf->cjobs              = info->cjobs;
947         inf->averageppm = info->averageppm;
948         init_unistr2_from_unistr(inf, &inf->servername, &info->servername);
949         init_unistr2_from_unistr(inf, &inf->printername, &info->printername);
950         init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename);
951         init_unistr2_from_unistr(inf, &inf->portname, &info->portname);
952         init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername);
953         init_unistr2_from_unistr(inf, &inf->comment, &info->comment);
954         init_unistr2_from_unistr(inf, &inf->location, &info->location);
955         init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile);
956         init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor);
957         init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
958         init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters);
959         init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
960
961         *spool_info2 = inf;
962
963         return True;
964 }
965
966 /*******************************************************************
967 create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
968 *******************************************************************/
969
970 bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, 
971                                 PRINTER_INFO_3 *info)
972 {
973
974         SPOOL_PRINTER_INFO_LEVEL_3 *inf;
975
976         /* allocate the necessary memory */
977         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
978                 DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
979                 return False;
980         }
981         
982         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
983
984         *spool_info3 = inf;
985
986         return True;
987 }
988
989 /*******************************************************************
990 create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
991 *******************************************************************/
992
993 bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, 
994                                 PRINTER_INFO_7 *info)
995 {
996
997         SPOOL_PRINTER_INFO_LEVEL_7 *inf;
998
999         /* allocate the necessary memory */
1000         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
1001                 DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
1002                 return False;
1003         }
1004
1005         inf->guid_ptr = (info->guid.buffer!=NULL)?1:0;
1006         inf->action = info->action;
1007         init_unistr2_from_unistr(inf, &inf->guid, &info->guid);
1008
1009         *spool_info7 = inf;
1010
1011         return True;
1012 }
1013
1014
1015 /*******************************************************************
1016  * read a structure.
1017  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1018  ********************************************************************/
1019
1020 bool spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
1021 {
1022         if (q_u == NULL)
1023                 return False;
1024
1025         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
1026         depth++;
1027
1028         if (!prs_align(ps))
1029                 return False;
1030
1031         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1032                 return False;
1033         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1034                 return False;
1035         
1036         if (!prs_align(ps))
1037                 return False;
1038
1039         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1040                 return False;
1041                 
1042         return True;
1043 }
1044
1045 /*******************************************************************
1046  * write a structure.
1047  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1048  * called from spoolss_open_printer_ex (cli_spoolss.c)
1049  ********************************************************************/
1050
1051 bool spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
1052 {
1053         if (r_u == NULL) return False;
1054
1055         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
1056         depth++;
1057         
1058         if (!prs_align(ps))
1059                 return False;
1060
1061         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1062                 return False;   
1063
1064         if (!prs_werror("status", ps, depth, &(r_u->status)))
1065                 return False;
1066                 
1067         return True;
1068 }
1069
1070
1071 /*******************************************************************
1072  * read a structure.
1073  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1074  ********************************************************************/
1075
1076 bool spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
1077 {
1078         if (q_u == NULL)
1079                 return False;
1080
1081         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
1082         depth++;
1083
1084         if (!prs_align(ps))
1085                 return False;
1086
1087         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1088                 return False;
1089         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1090                 return False;
1091         
1092         if (!prs_align(ps))
1093                 return False;
1094
1095         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1096                 return False;
1097
1098         if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
1099                 return False;   
1100         if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
1101                 return False;
1102         
1103         return True;
1104 }
1105
1106 /*******************************************************************
1107  * write a structure.
1108  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1109  * called from spoolss_open_printer_ex (cli_spoolss.c)
1110  ********************************************************************/
1111
1112 bool spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
1113 {
1114         if (r_u == NULL) return False;
1115
1116         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
1117         depth++;
1118         
1119         if (!prs_align(ps))
1120                 return False;
1121
1122         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1123                 return False;
1124
1125         if (!prs_werror("status", ps, depth, &(r_u->status)))
1126                 return False;
1127
1128         return True;
1129 }
1130
1131 /*******************************************************************
1132  * make a structure.
1133  ********************************************************************/
1134
1135 bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
1136                                    const POLICY_HND *handle,
1137                                    const char *valuename, uint32 size)
1138 {
1139         if (q_u == NULL) return False;
1140
1141         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
1142
1143         q_u->handle = *handle;
1144         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1145         q_u->size = size;
1146
1147         return True;
1148 }
1149
1150 /*******************************************************************
1151  * make a structure.
1152  ********************************************************************/
1153
1154 bool make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
1155                                      const POLICY_HND *handle,
1156                                      const char *keyname, 
1157                                      const char *valuename, uint32 size)
1158 {
1159         if (q_u == NULL) return False;
1160
1161         DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
1162
1163         q_u->handle = *handle;
1164         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1165         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
1166         q_u->size = size;
1167
1168         return True;
1169 }
1170
1171 /*******************************************************************
1172  * read a structure.
1173  * called from spoolss_q_getprinterdata (srv_spoolss.c)
1174  ********************************************************************/
1175
1176 bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
1177 {
1178         if (q_u == NULL)
1179                 return False;
1180
1181         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
1182         depth++;
1183
1184         if (!prs_align(ps))
1185                 return False;
1186         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1187                 return False;
1188         if (!prs_align(ps))
1189                 return False;
1190         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1191                 return False;
1192         if (!prs_align(ps))
1193                 return False;
1194         if (!prs_uint32("size", ps, depth, &q_u->size))
1195                 return False;
1196
1197         return True;
1198 }
1199
1200 /*******************************************************************
1201  * write a structure.
1202  * called from spoolss_r_getprinterdata (srv_spoolss.c)
1203  ********************************************************************/
1204
1205 bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
1206 {
1207         if (r_u == NULL)
1208                 return False;
1209
1210         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
1211         depth++;
1212
1213         if (!prs_align(ps))
1214                 return False;
1215         if (!prs_uint32("type", ps, depth, &r_u->type))
1216                 return False;
1217         if (!prs_uint32("size", ps, depth, &r_u->size))
1218                 return False;
1219         
1220         if (UNMARSHALLING(ps) && r_u->size) {
1221                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
1222                 if(!r_u->data)
1223                         return False;
1224         }
1225
1226         if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
1227                 return False;
1228                 
1229         if (!prs_align(ps))
1230                 return False;
1231         
1232         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1233                 return False;
1234         if (!prs_werror("status", ps, depth, &r_u->status))
1235                 return False;
1236                 
1237         return True;
1238 }
1239
1240 /*******************************************************************
1241  * read a structure.
1242  * called from spoolss_q_rffpcnex (srv_spoolss.c)
1243  ********************************************************************/
1244
1245 bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1246 {
1247         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1248         depth++;
1249
1250         if(!prs_align(ps))
1251                 return False;
1252
1253         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1254                 return False;
1255         if(!prs_uint32("flags", ps, depth, &q_u->flags))
1256                 return False;
1257         if(!prs_uint32("options", ps, depth, &q_u->options))
1258                 return False;
1259         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1260                 return False;
1261         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1262                 return False;
1263
1264         if(!prs_align(ps))
1265                 return False;
1266                 
1267         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1268                 return False;
1269
1270         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1271                 return False;
1272         
1273         if (q_u->option_ptr!=0) {
1274         
1275                 if (UNMARSHALLING(ps))
1276                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1277                                 return False;
1278         
1279                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1280                         return False;
1281         }
1282         
1283         return True;
1284 }
1285
1286 /*******************************************************************
1287  * write a structure.
1288  * called from spoolss_r_rffpcnex (srv_spoolss.c)
1289  ********************************************************************/
1290
1291 bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1292 {
1293         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1294         depth++;
1295
1296         if(!prs_werror("status", ps, depth, &r_u->status))
1297                 return False;
1298
1299         return True;
1300 }
1301
1302 /*******************************************************************
1303  * read a structure.
1304  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1305  ********************************************************************/
1306
1307 bool spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1308 {
1309         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1310         depth++;
1311
1312         if(!prs_align(ps))
1313                 return False;
1314
1315         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1316                 return False;
1317
1318         if(!prs_uint32("change", ps, depth, &q_u->change))
1319                 return False;
1320         
1321         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1322                 return False;
1323         
1324         if (q_u->option_ptr!=0) {
1325         
1326                 if (UNMARSHALLING(ps))
1327                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1328                                 return False;
1329         
1330                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1331                         return False;
1332         }
1333
1334         return True;
1335 }
1336
1337 /*******************************************************************
1338  * write a structure.
1339  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
1340  ********************************************************************/
1341
1342 bool spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
1343 {
1344         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
1345         depth++;
1346
1347         if(!prs_align(ps))
1348                 return False;
1349                 
1350         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
1351                 return False;
1352
1353         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
1354                 return False;
1355         
1356         if(!prs_align(ps))
1357                 return False;
1358         if(!prs_werror("status", ps, depth, &r_u->status))
1359                 return False;
1360
1361         return True;
1362 }
1363
1364 /*******************************************************************
1365  * return the length of a uint16 (obvious, but the code is clean)
1366  ********************************************************************/
1367
1368 static uint32 size_of_uint16(uint16 *value)
1369 {
1370         return (sizeof(*value));
1371 }
1372
1373 /*******************************************************************
1374  * return the length of a uint32 (obvious, but the code is clean)
1375  ********************************************************************/
1376
1377 static uint32 size_of_uint32(uint32 *value)
1378 {
1379         return (sizeof(*value));
1380 }
1381
1382 /*******************************************************************
1383  * return the length of a NTTIME (obvious, but the code is clean)
1384  ********************************************************************/
1385
1386 static uint32 size_of_nttime(NTTIME *value)
1387 {
1388         return (sizeof(*value));
1389 }
1390
1391 /*******************************************************************
1392  * return the length of a uint32 (obvious, but the code is clean)
1393  ********************************************************************/
1394
1395 static uint32 size_of_device_mode(DEVICEMODE *devmode)
1396 {
1397         if (devmode==NULL)
1398                 return (4);
1399         else 
1400                 return (4+devmode->size+devmode->driverextra);
1401 }
1402
1403 /*******************************************************************
1404  * return the length of a uint32 (obvious, but the code is clean)
1405  ********************************************************************/
1406
1407 static uint32 size_of_systemtime(SYSTEMTIME *systime)
1408 {
1409         if (systime==NULL)
1410                 return (4);
1411         else 
1412                 return (sizeof(SYSTEMTIME) +4);
1413 }
1414
1415 /*******************************************************************
1416  Parse a DEVMODE structure and its relative pointer.
1417 ********************************************************************/
1418
1419 static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
1420 {
1421         prs_struct *ps=&buffer->prs;
1422
1423         prs_debug(ps, depth, desc, "smb_io_reldevmode");
1424         depth++;
1425
1426         if (MARSHALLING(ps)) {
1427                 uint32 struct_offset = prs_offset(ps);
1428                 uint32 relative_offset;
1429                 
1430                 if (*devmode == NULL) {
1431                         relative_offset=0;
1432                         if (!prs_uint32("offset", ps, depth, &relative_offset))
1433                                 return False;
1434                         DEBUG(8, ("boing, the devmode was NULL\n"));
1435                         
1436                         return True;
1437                 }
1438                 
1439                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
1440
1441                 /* mz:  we have to align the device mode for VISTA */
1442                 if (buffer->string_at_end % 4) {
1443                         buffer->string_at_end += 4 - (buffer->string_at_end % 4);
1444                 }
1445
1446                 if(!prs_set_offset(ps, buffer->string_at_end))
1447                         return False;
1448                 
1449                 /* write the DEVMODE */
1450                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1451                         return False;
1452
1453                 if(!prs_set_offset(ps, struct_offset))
1454                         return False;
1455                 
1456                 relative_offset=buffer->string_at_end - buffer->struct_start;
1457                 /* write its offset */
1458                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1459                         return False;
1460         }
1461         else {
1462                 uint32 old_offset;
1463                 
1464                 /* read the offset */
1465                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
1466                         return False;
1467                 if (buffer->string_at_end == 0) {
1468                         *devmode = NULL;
1469                         return True;
1470                 }
1471
1472                 old_offset = prs_offset(ps);
1473                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
1474                         return False;
1475
1476                 /* read the string */
1477                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
1478                         return False;
1479                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1480                         return False;
1481
1482                 if(!prs_set_offset(ps, old_offset))
1483                         return False;
1484         }
1485         return True;
1486 }
1487
1488 /*******************************************************************
1489  Parse a PRINTER_INFO_0 structure.
1490 ********************************************************************/  
1491
1492 bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
1493 {
1494         prs_struct *ps=&buffer->prs;
1495
1496         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
1497         depth++;        
1498         
1499         buffer->struct_start=prs_offset(ps);
1500
1501         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1502                 return False;
1503         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
1504                 return False;
1505         
1506         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
1507                 return False;
1508         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
1509                 return False;
1510         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
1511                 return False;
1512
1513         if(!prs_uint16("year", ps, depth, &info->year))
1514                 return False;
1515         if(!prs_uint16("month", ps, depth, &info->month))
1516                 return False;
1517         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
1518                 return False;
1519         if(!prs_uint16("day", ps, depth, &info->day))
1520                 return False;
1521         if(!prs_uint16("hour", ps, depth, &info->hour))
1522                 return False;
1523         if(!prs_uint16("minute", ps, depth, &info->minute))
1524                 return False;
1525         if(!prs_uint16("second", ps, depth, &info->second))
1526                 return False;
1527         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
1528                 return False;
1529
1530         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
1531                 return False;
1532         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
1533                 return False;
1534
1535         if(!prs_uint16("major_version", ps, depth, &info->major_version))
1536                 return False;
1537         if(!prs_uint16("build_version", ps, depth, &info->build_version))
1538                 return False;
1539         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
1540                 return False;
1541         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
1542                 return False;
1543         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
1544                 return False;
1545         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
1546                 return False;
1547         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
1548                 return False;
1549         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
1550                 return False;
1551         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
1552                 return False;
1553         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
1554                 return False;
1555         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
1556                 return False;
1557         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
1558                 return False;
1559         if(!prs_uint32("change_id", ps, depth, &info->change_id))
1560                 return False;
1561         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
1562                 return False;
1563         if(!prs_uint32("status"   , ps, depth, &info->status))
1564                 return False;
1565         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
1566                 return False;
1567         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
1568                 return False;
1569         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
1570                 return False;
1571         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
1572                 return False;
1573         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
1574                 return False;
1575         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
1576                 return False;
1577         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
1578                 return False;
1579         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
1580                 return False;
1581         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
1582                 return False;
1583         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
1584                 return False;
1585
1586         return True;
1587 }
1588
1589 /*******************************************************************
1590  Parse a PRINTER_INFO_1 structure.
1591 ********************************************************************/  
1592
1593 bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
1594 {
1595         prs_struct *ps=&buffer->prs;
1596
1597         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
1598         depth++;        
1599         
1600         buffer->struct_start=prs_offset(ps);
1601
1602         if (!prs_uint32("flags", ps, depth, &info->flags))
1603                 return False;
1604         if (!smb_io_relstr("description", buffer, depth, &info->description))
1605                 return False;
1606         if (!smb_io_relstr("name", buffer, depth, &info->name))
1607                 return False;
1608         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
1609                 return False;   
1610
1611         return True;
1612 }
1613
1614 /*******************************************************************
1615  Parse a PRINTER_INFO_2 structure.
1616 ********************************************************************/  
1617
1618 bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
1619 {
1620         prs_struct *ps=&buffer->prs;
1621         uint32 dm_offset, sd_offset, current_offset;
1622         uint32 dummy_value = 0, has_secdesc = 0;
1623
1624         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
1625         depth++;        
1626         
1627         buffer->struct_start=prs_offset(ps);
1628         
1629         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
1630                 return False;
1631         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1632                 return False;
1633         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
1634                 return False;
1635         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
1636                 return False;
1637         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
1638                 return False;
1639         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
1640                 return False;
1641         if (!smb_io_relstr("location", buffer, depth, &info->location))
1642                 return False;
1643
1644         /* save current offset and wind forwared by a uint32 */
1645         dm_offset = prs_offset(ps);
1646         if (!prs_uint32("devmode", ps, depth, &dummy_value))
1647                 return False;
1648         
1649         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
1650                 return False;
1651         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1652                 return False;
1653         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
1654                 return False;
1655         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
1656                 return False;
1657
1658         /* save current offset for the sec_desc */
1659         sd_offset = prs_offset(ps);
1660         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
1661                 return False;
1662
1663         
1664         /* save current location so we can pick back up here */
1665         current_offset = prs_offset(ps);
1666         
1667         /* parse the devmode */
1668         if (!prs_set_offset(ps, dm_offset))
1669                 return False;
1670         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1671                 return False;
1672         
1673         /* parse the sec_desc */
1674         if (info->secdesc) {
1675                 if (!prs_set_offset(ps, sd_offset))
1676                         return False;
1677                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
1678                         return False;
1679         }
1680
1681         /* pick up where we left off */
1682         if (!prs_set_offset(ps, current_offset))
1683                 return False;
1684
1685         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1686                 return False;
1687         if (!prs_uint32("priority", ps, depth, &info->priority))
1688                 return False;
1689         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
1690                 return False;
1691         if (!prs_uint32("starttime", ps, depth, &info->starttime))
1692                 return False;
1693         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
1694                 return False;
1695         if (!prs_uint32("status", ps, depth, &info->status))
1696                 return False;
1697         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
1698                 return False;
1699         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
1700                 return False;
1701
1702         return True;
1703 }
1704
1705 /*******************************************************************
1706  Parse a PRINTER_INFO_3 structure.
1707 ********************************************************************/  
1708
1709 bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
1710 {
1711         uint32 offset = 0;
1712         prs_struct *ps=&buffer->prs;
1713
1714         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
1715         depth++;        
1716         
1717         buffer->struct_start=prs_offset(ps);
1718         
1719         if (MARSHALLING(ps)) {
1720                 /* Ensure the SD is 8 byte aligned in the buffer. */
1721                 uint32 start = prs_offset(ps); /* Remember the start position. */
1722                 uint32 off_val = 0;
1723
1724                 /* Write a dummy value. */
1725                 if (!prs_uint32("offset", ps, depth, &off_val))
1726                         return False;
1727
1728                 /* 8 byte align. */
1729                 if (!prs_align_uint64(ps))
1730                         return False;
1731
1732                 /* Remember where we must seek back to write the SD. */
1733                 offset = prs_offset(ps);
1734
1735                 /* Calculate the real offset for the SD. */
1736
1737                 off_val = offset - start;
1738
1739                 /* Seek back to where we store the SD offset & store. */
1740                 prs_set_offset(ps, start);
1741                 if (!prs_uint32("offset", ps, depth, &off_val))
1742                         return False;
1743
1744                 /* Return to after the 8 byte align. */
1745                 prs_set_offset(ps, offset);
1746
1747         } else {
1748                 if (!prs_uint32("offset", ps, depth, &offset))
1749                         return False;
1750                 /* Seek within the buffer. */
1751                 if (!prs_set_offset(ps, offset))
1752                         return False;
1753         }
1754         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
1755                 return False;
1756
1757         return True;
1758 }
1759
1760 /*******************************************************************
1761  Parse a PRINTER_INFO_4 structure.
1762 ********************************************************************/  
1763
1764 bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
1765 {
1766         prs_struct *ps=&buffer->prs;
1767
1768         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
1769         depth++;        
1770         
1771         buffer->struct_start=prs_offset(ps);
1772         
1773         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1774                 return False;
1775         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
1776                 return False;
1777         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1778                 return False;
1779         return True;
1780 }
1781
1782 /*******************************************************************
1783  Parse a PRINTER_INFO_5 structure.
1784 ********************************************************************/  
1785
1786 bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
1787 {
1788         prs_struct *ps=&buffer->prs;
1789
1790         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
1791         depth++;        
1792         
1793         buffer->struct_start=prs_offset(ps);
1794         
1795         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1796                 return False;
1797         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
1798                 return False;
1799         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1800                 return False;
1801         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
1802                 return False;
1803         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
1804                 return False;
1805         return True;
1806 }
1807
1808 /*******************************************************************
1809  Parse a PRINTER_INFO_6 structure.
1810 ********************************************************************/  
1811
1812 bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
1813                            PRINTER_INFO_6 *info, int depth)
1814 {
1815         prs_struct *ps=&buffer->prs;
1816
1817         prs_debug(ps, depth, desc, "smb_io_printer_info_6");
1818         depth++;        
1819         
1820         if (!prs_uint32("status", ps, depth, &info->status))
1821                 return False;
1822
1823         return True;
1824 }
1825
1826 /*******************************************************************
1827  Parse a PRINTER_INFO_7 structure.
1828 ********************************************************************/  
1829
1830 bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
1831 {
1832         prs_struct *ps=&buffer->prs;
1833
1834         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
1835         depth++;        
1836         
1837         buffer->struct_start=prs_offset(ps);
1838         
1839         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
1840                 return False;
1841         if (!prs_uint32("action", ps, depth, &info->action))
1842                 return False;
1843         return True;
1844 }
1845
1846 /*******************************************************************
1847  Parse a PORT_INFO_1 structure.
1848 ********************************************************************/  
1849
1850 bool smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
1851 {
1852         prs_struct *ps=&buffer->prs;
1853
1854         prs_debug(ps, depth, desc, "smb_io_port_info_1");
1855         depth++;        
1856         
1857         buffer->struct_start=prs_offset(ps);
1858         
1859         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1860                 return False;
1861
1862         return True;
1863 }
1864
1865 /*******************************************************************
1866  Parse a PORT_INFO_2 structure.
1867 ********************************************************************/  
1868
1869 bool smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
1870 {
1871         prs_struct *ps=&buffer->prs;
1872
1873         prs_debug(ps, depth, desc, "smb_io_port_info_2");
1874         depth++;        
1875         
1876         buffer->struct_start=prs_offset(ps);
1877         
1878         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1879                 return False;
1880         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
1881                 return False;
1882         if (!smb_io_relstr("description", buffer, depth, &info->description))
1883                 return False;
1884         if (!prs_uint32("port_type", ps, depth, &info->port_type))
1885                 return False;
1886         if (!prs_uint32("reserved", ps, depth, &info->reserved))
1887                 return False;
1888
1889         return True;
1890 }
1891
1892 /*******************************************************************
1893  Parse a DRIVER_INFO_1 structure.
1894 ********************************************************************/
1895
1896 bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
1897 {
1898         prs_struct *ps=&buffer->prs;
1899
1900         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
1901         depth++;        
1902         
1903         buffer->struct_start=prs_offset(ps);
1904
1905         if (!smb_io_relstr("name", buffer, depth, &info->name))
1906                 return False;
1907
1908         return True;
1909 }
1910
1911 /*******************************************************************
1912  Parse a DRIVER_INFO_2 structure.
1913 ********************************************************************/
1914
1915 bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
1916 {
1917         prs_struct *ps=&buffer->prs;
1918
1919         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
1920         depth++;        
1921         
1922         buffer->struct_start=prs_offset(ps);
1923
1924         if (!prs_uint32("version", ps, depth, &info->version))
1925                 return False;
1926         if (!smb_io_relstr("name", buffer, depth, &info->name))
1927                 return False;
1928         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1929                 return False;
1930         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1931                 return False;
1932         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
1933                 return False;
1934         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
1935                 return False;
1936
1937         return True;
1938 }
1939
1940 /*******************************************************************
1941  Parse a DRIVER_INFO_3 structure.
1942 ********************************************************************/
1943
1944 bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
1945 {
1946         prs_struct *ps=&buffer->prs;
1947
1948         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
1949         depth++;        
1950         
1951         buffer->struct_start=prs_offset(ps);
1952
1953         if (!prs_uint32("version", ps, depth, &info->version))
1954                 return False;
1955         if (!smb_io_relstr("name", buffer, depth, &info->name))
1956                 return False;
1957         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1958                 return False;
1959         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1960                 return False;
1961         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
1962                 return False;
1963         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
1964                 return False;
1965         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
1966                 return False;
1967
1968         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
1969                 return False;
1970
1971         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
1972                 return False;
1973         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
1974                 return False;
1975
1976         return True;
1977 }
1978
1979 /*******************************************************************
1980  Parse a DRIVER_INFO_6 structure.
1981 ********************************************************************/
1982
1983 bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
1984 {
1985         prs_struct *ps=&buffer->prs;
1986
1987         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
1988         depth++;        
1989         
1990         buffer->struct_start=prs_offset(ps);
1991
1992         if (!prs_uint32("version", ps, depth, &info->version))
1993                 return False;
1994         if (!smb_io_relstr("name", buffer, depth, &info->name))
1995                 return False;
1996         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1997                 return False;
1998         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1999                 return False;
2000         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2001                 return False;
2002         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2003                 return False;
2004         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2005                 return False;
2006
2007         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2008                 return False;
2009
2010         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2011                 return False;
2012         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2013                 return False;
2014
2015         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2016                 return False;
2017
2018         if (!prs_uint64("date", ps, depth, &info->driver_date))
2019                 return False;
2020
2021         if (!prs_uint32("padding", ps, depth, &info->padding))
2022                 return False;
2023
2024         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2025                 return False;
2026
2027         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2028                 return False;
2029
2030         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2031                 return False;
2032         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2033                 return False;
2034         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2035                 return False;
2036         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2037                 return False;
2038         
2039         return True;
2040 }
2041
2042 /*******************************************************************
2043  Parse a JOB_INFO_1 structure.
2044 ********************************************************************/  
2045
2046 bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2047 {
2048         prs_struct *ps=&buffer->prs;
2049
2050         prs_debug(ps, depth, desc, "smb_io_job_info_1");
2051         depth++;        
2052         
2053         buffer->struct_start=prs_offset(ps);
2054
2055         if (!prs_uint32("jobid", ps, depth, &info->jobid))
2056                 return False;
2057         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2058                 return False;
2059         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2060                 return False;
2061         if (!smb_io_relstr("username", buffer, depth, &info->username))
2062                 return False;
2063         if (!smb_io_relstr("document", buffer, depth, &info->document))
2064                 return False;
2065         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2066                 return False;
2067         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2068                 return False;
2069         if (!prs_uint32("status", ps, depth, &info->status))
2070                 return False;
2071         if (!prs_uint32("priority", ps, depth, &info->priority))
2072                 return False;
2073         if (!prs_uint32("position", ps, depth, &info->position))
2074                 return False;
2075         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2076                 return False;
2077         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2078                 return False;
2079         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2080                 return False;
2081
2082         return True;
2083 }
2084
2085 /*******************************************************************
2086  Parse a JOB_INFO_2 structure.
2087 ********************************************************************/  
2088
2089 bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2090 {       
2091         uint32 pipo=0;
2092         prs_struct *ps=&buffer->prs;
2093         
2094         prs_debug(ps, depth, desc, "smb_io_job_info_2");
2095         depth++;        
2096
2097         buffer->struct_start=prs_offset(ps);
2098         
2099         if (!prs_uint32("jobid",ps, depth, &info->jobid))
2100                 return False;
2101         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2102                 return False;
2103         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2104                 return False;
2105         if (!smb_io_relstr("username", buffer, depth, &info->username))
2106                 return False;
2107         if (!smb_io_relstr("document", buffer, depth, &info->document))
2108                 return False;
2109         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2110                 return False;
2111         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2112                 return False;
2113
2114         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2115                 return False;
2116         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2117                 return False;
2118         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2119                 return False;
2120         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2121                 return False;
2122         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2123                 return False;
2124
2125 /*      SEC_DESC sec_desc;*/
2126         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2127                 return False;
2128
2129         if (!prs_uint32("status",ps, depth, &info->status))
2130                 return False;
2131         if (!prs_uint32("priority",ps, depth, &info->priority))
2132                 return False;
2133         if (!prs_uint32("position",ps, depth, &info->position)) 
2134                 return False;
2135         if (!prs_uint32("starttime",ps, depth, &info->starttime))
2136                 return False;
2137         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
2138                 return False;
2139         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2140                 return False;
2141         if (!prs_uint32("size",ps, depth, &info->size))
2142                 return False;
2143         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2144                 return False;
2145         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2146                 return False;
2147         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2148                 return False;
2149
2150         return True;
2151 }
2152
2153 /*******************************************************************
2154 ********************************************************************/  
2155
2156 bool smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
2157 {
2158         prs_struct *ps=&buffer->prs;
2159         
2160         prs_debug(ps, depth, desc, "smb_io_form_1");
2161         depth++;
2162                 
2163         buffer->struct_start=prs_offset(ps);
2164         
2165         if (!prs_uint32("flag", ps, depth, &info->flag))
2166                 return False;
2167                 
2168         if (!smb_io_relstr("name", buffer, depth, &info->name))
2169                 return False;
2170
2171         if (!prs_uint32("width", ps, depth, &info->width))
2172                 return False;
2173         if (!prs_uint32("length", ps, depth, &info->length))
2174                 return False;
2175         if (!prs_uint32("left", ps, depth, &info->left))
2176                 return False;
2177         if (!prs_uint32("top", ps, depth, &info->top))
2178                 return False;
2179         if (!prs_uint32("right", ps, depth, &info->right))
2180                 return False;
2181         if (!prs_uint32("bottom", ps, depth, &info->bottom))
2182                 return False;
2183
2184         return True;
2185 }
2186
2187
2188
2189 /*******************************************************************
2190  Parse a DRIVER_DIRECTORY_1 structure.
2191 ********************************************************************/  
2192
2193 bool smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2194 {
2195         prs_struct *ps=&buffer->prs;
2196
2197         prs_debug(ps, depth, desc, "smb_io_driverdir_1");
2198         depth++;
2199
2200         buffer->struct_start=prs_offset(ps);
2201
2202         if (!smb_io_unistr(desc, &info->name, ps, depth))
2203                 return False;
2204
2205         return True;
2206 }
2207
2208 /*******************************************************************
2209  Parse a PORT_INFO_1 structure.
2210 ********************************************************************/  
2211
2212 bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2213 {
2214         prs_struct *ps=&buffer->prs;
2215
2216         prs_debug(ps, depth, desc, "smb_io_port_1");
2217         depth++;
2218
2219         buffer->struct_start=prs_offset(ps);
2220
2221         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2222                 return False;
2223
2224         return True;
2225 }
2226
2227 /*******************************************************************
2228  Parse a PORT_INFO_2 structure.
2229 ********************************************************************/  
2230
2231 bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2232 {
2233         prs_struct *ps=&buffer->prs;
2234
2235         prs_debug(ps, depth, desc, "smb_io_port_2");
2236         depth++;
2237
2238         buffer->struct_start=prs_offset(ps);
2239
2240         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2241                 return False;
2242         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2243                 return False;
2244         if(!smb_io_relstr("description", buffer, depth, &info->description))
2245                 return False;
2246         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2247                 return False;
2248         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2249                 return False;
2250
2251         return True;
2252 }
2253
2254 /*******************************************************************
2255 ********************************************************************/  
2256
2257 bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2258 {
2259         prs_struct *ps=&buffer->prs;
2260
2261         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2262         depth++;        
2263
2264         buffer->struct_start=prs_offset(ps);
2265         
2266         if (smb_io_relstr("name", buffer, depth, &info->name))
2267                 return False;
2268
2269         return True;
2270 }
2271
2272 /*******************************************************************
2273 ********************************************************************/  
2274
2275 bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2276 {
2277         prs_struct *ps=&buffer->prs;
2278
2279         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2280         depth++;        
2281
2282         buffer->struct_start=prs_offset(ps);
2283         
2284         if (smb_io_relstr("name", buffer, depth, &info->name))
2285                 return False;
2286
2287         return True;
2288 }
2289
2290 /*******************************************************************
2291 ********************************************************************/  
2292
2293 bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2294 {
2295         prs_struct *ps=&buffer->prs;
2296
2297         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2298         depth++;        
2299
2300         buffer->struct_start=prs_offset(ps);
2301
2302         if (!smb_io_relstr("name", buffer, depth, &info->name))
2303                 return False;
2304
2305         return True;
2306 }
2307
2308 /*******************************************************************
2309 ********************************************************************/  
2310
2311 bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2312 {
2313         prs_struct *ps=&buffer->prs;
2314
2315         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2316         depth++;        
2317
2318         buffer->struct_start=prs_offset(ps);
2319
2320         if (!smb_io_relstr("name", buffer, depth, &info->name))
2321                 return False;
2322         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
2323                 return False;
2324         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2325                 return False;
2326
2327         return True;
2328 }
2329
2330 /*******************************************************************
2331 return the size required by a struct in the stream
2332 ********************************************************************/  
2333
2334 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2335 {
2336         int size=0;
2337         
2338         size+=size_of_relative_string( &info->printername );
2339         size+=size_of_relative_string( &info->servername );
2340
2341         size+=size_of_uint32( &info->cjobs);
2342         size+=size_of_uint32( &info->total_jobs);
2343         size+=size_of_uint32( &info->total_bytes);
2344
2345         size+=size_of_uint16( &info->year);
2346         size+=size_of_uint16( &info->month);
2347         size+=size_of_uint16( &info->dayofweek);
2348         size+=size_of_uint16( &info->day);
2349         size+=size_of_uint16( &info->hour);
2350         size+=size_of_uint16( &info->minute);
2351         size+=size_of_uint16( &info->second);
2352         size+=size_of_uint16( &info->milliseconds);
2353
2354         size+=size_of_uint32( &info->global_counter);
2355         size+=size_of_uint32( &info->total_pages);
2356
2357         size+=size_of_uint16( &info->major_version);
2358         size+=size_of_uint16( &info->build_version);
2359
2360         size+=size_of_uint32( &info->unknown7);
2361         size+=size_of_uint32( &info->unknown8);
2362         size+=size_of_uint32( &info->unknown9);
2363         size+=size_of_uint32( &info->session_counter);
2364         size+=size_of_uint32( &info->unknown11);
2365         size+=size_of_uint32( &info->printer_errors);
2366         size+=size_of_uint32( &info->unknown13);
2367         size+=size_of_uint32( &info->unknown14);
2368         size+=size_of_uint32( &info->unknown15);
2369         size+=size_of_uint32( &info->unknown16);
2370         size+=size_of_uint32( &info->change_id);
2371         size+=size_of_uint32( &info->unknown18);
2372         size+=size_of_uint32( &info->status);
2373         size+=size_of_uint32( &info->unknown20);
2374         size+=size_of_uint32( &info->c_setprinter);
2375         
2376         size+=size_of_uint16( &info->unknown22);
2377         size+=size_of_uint16( &info->unknown23);
2378         size+=size_of_uint16( &info->unknown24);
2379         size+=size_of_uint16( &info->unknown25);
2380         size+=size_of_uint16( &info->unknown26);
2381         size+=size_of_uint16( &info->unknown27);
2382         size+=size_of_uint16( &info->unknown28);
2383         size+=size_of_uint16( &info->unknown29);
2384         
2385         return size;
2386 }
2387
2388 /*******************************************************************
2389 return the size required by a struct in the stream
2390 ********************************************************************/  
2391
2392 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
2393 {
2394         int size=0;
2395                 
2396         size+=size_of_uint32( &info->flags );   
2397         size+=size_of_relative_string( &info->description );
2398         size+=size_of_relative_string( &info->name );
2399         size+=size_of_relative_string( &info->comment );
2400
2401         return size;
2402 }
2403
2404 /*******************************************************************
2405 return the size required by a struct in the stream
2406 ********************************************************************/
2407
2408 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
2409 {
2410         uint32 size=0;
2411                 
2412         size += 4;
2413         
2414         size += ndr_size_security_descriptor( info->secdesc, NULL, 0 );
2415
2416         size+=size_of_device_mode( info->devmode );
2417         
2418         size+=size_of_relative_string( &info->servername );
2419         size+=size_of_relative_string( &info->printername );
2420         size+=size_of_relative_string( &info->sharename );
2421         size+=size_of_relative_string( &info->portname );
2422         size+=size_of_relative_string( &info->drivername );
2423         size+=size_of_relative_string( &info->comment );
2424         size+=size_of_relative_string( &info->location );
2425         
2426         size+=size_of_relative_string( &info->sepfile );
2427         size+=size_of_relative_string( &info->printprocessor );
2428         size+=size_of_relative_string( &info->datatype );
2429         size+=size_of_relative_string( &info->parameters );
2430
2431         size+=size_of_uint32( &info->attributes );
2432         size+=size_of_uint32( &info->priority );
2433         size+=size_of_uint32( &info->defaultpriority );
2434         size+=size_of_uint32( &info->starttime );
2435         size+=size_of_uint32( &info->untiltime );
2436         size+=size_of_uint32( &info->status );
2437         size+=size_of_uint32( &info->cjobs );
2438         size+=size_of_uint32( &info->averageppm );      
2439                 
2440         /* 
2441          * add any adjustments for alignment.  This is
2442          * not optimal since we could be calling this
2443          * function from a loop (e.g. enumprinters), but 
2444          * it is easier to maintain the calculation here and
2445          * not place the burden on the caller to remember.   --jerry
2446          */
2447         if ((size % 4) != 0)
2448                 size += 4 - (size % 4);
2449         
2450         return size;
2451 }
2452
2453 /*******************************************************************
2454 return the size required by a struct in the stream
2455 ********************************************************************/
2456
2457 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
2458 {
2459         uint32 size=0;
2460                 
2461         size+=size_of_relative_string( &info->printername );
2462         size+=size_of_relative_string( &info->servername );
2463
2464         size+=size_of_uint32( &info->attributes );
2465         return size;
2466 }
2467
2468 /*******************************************************************
2469 return the size required by a struct in the stream
2470 ********************************************************************/
2471
2472 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
2473 {
2474         uint32 size=0;
2475                 
2476         size+=size_of_relative_string( &info->printername );
2477         size+=size_of_relative_string( &info->portname );
2478
2479         size+=size_of_uint32( &info->attributes );
2480         size+=size_of_uint32( &info->device_not_selected_timeout );
2481         size+=size_of_uint32( &info->transmission_retry_timeout );
2482         return size;
2483 }
2484
2485 /*******************************************************************
2486 return the size required by a struct in the stream
2487 ********************************************************************/
2488
2489 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
2490 {
2491         return sizeof(uint32);
2492 }
2493
2494 /*******************************************************************
2495 return the size required by a struct in the stream
2496 ********************************************************************/
2497
2498 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
2499 {
2500         /* The 8 is for the self relative pointer - 8 byte aligned.. */
2501         return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 );
2502 }
2503
2504 /*******************************************************************
2505 return the size required by a struct in the stream
2506 ********************************************************************/
2507
2508 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
2509 {
2510         uint32 size=0;
2511                 
2512         size+=size_of_relative_string( &info->guid );
2513         size+=size_of_uint32( &info->action );
2514         return size;
2515 }
2516
2517 /*******************************************************************
2518 return the size required by a struct in the stream
2519 ********************************************************************/
2520
2521 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
2522 {
2523         int size=0;
2524         size+=size_of_relative_string( &info->name );
2525
2526         return size;
2527 }
2528
2529 /*******************************************************************
2530 return the size required by a struct in the stream
2531 ********************************************************************/
2532
2533 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
2534 {
2535         int size=0;
2536         size+=size_of_uint32( &info->version ); 
2537         size+=size_of_relative_string( &info->name );
2538         size+=size_of_relative_string( &info->architecture );
2539         size+=size_of_relative_string( &info->driverpath );
2540         size+=size_of_relative_string( &info->datafile );
2541         size+=size_of_relative_string( &info->configfile );
2542
2543         return size;
2544 }
2545
2546 /*******************************************************************
2547 return the size required by a string array.
2548 ********************************************************************/
2549
2550 uint32 spoolss_size_string_array(uint16 *string)
2551 {
2552         uint32 i = 0;
2553
2554         if (string) {
2555                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
2556         }
2557         i=i+2; /* to count all chars including the leading zero */
2558         i=2*i; /* because we need the value in bytes */
2559         i=i+4; /* the offset pointer size */
2560
2561         return i;
2562 }
2563
2564 /*******************************************************************
2565 return the size required by a struct in the stream
2566 ********************************************************************/
2567
2568 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
2569 {
2570         int size=0;
2571
2572         size+=size_of_uint32( &info->version ); 
2573         size+=size_of_relative_string( &info->name );
2574         size+=size_of_relative_string( &info->architecture );
2575         size+=size_of_relative_string( &info->driverpath );
2576         size+=size_of_relative_string( &info->datafile );
2577         size+=size_of_relative_string( &info->configfile );
2578         size+=size_of_relative_string( &info->helpfile );
2579         size+=size_of_relative_string( &info->monitorname );
2580         size+=size_of_relative_string( &info->defaultdatatype );
2581         
2582         size+=spoolss_size_string_array(info->dependentfiles);
2583
2584         return size;
2585 }
2586
2587 /*******************************************************************
2588 return the size required by a struct in the stream
2589 ********************************************************************/
2590
2591 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
2592 {
2593         uint32 size=0;
2594
2595         size+=size_of_uint32( &info->version ); 
2596         size+=size_of_relative_string( &info->name );
2597         size+=size_of_relative_string( &info->architecture );
2598         size+=size_of_relative_string( &info->driverpath );
2599         size+=size_of_relative_string( &info->datafile );
2600         size+=size_of_relative_string( &info->configfile );
2601         size+=size_of_relative_string( &info->helpfile );
2602
2603         size+=spoolss_size_string_array(info->dependentfiles);
2604
2605         size+=size_of_relative_string( &info->monitorname );
2606         size+=size_of_relative_string( &info->defaultdatatype );
2607         
2608         size+=spoolss_size_string_array(info->previousdrivernames);
2609
2610         size+=size_of_nttime(&info->driver_date);
2611         size+=size_of_uint32( &info->padding ); 
2612         size+=size_of_uint32( &info->driver_version_low );      
2613         size+=size_of_uint32( &info->driver_version_high );     
2614         size+=size_of_relative_string( &info->mfgname );
2615         size+=size_of_relative_string( &info->oem_url );
2616         size+=size_of_relative_string( &info->hardware_id );
2617         size+=size_of_relative_string( &info->provider );
2618
2619         return size;
2620 }
2621
2622 /*******************************************************************
2623 return the size required by a struct in the stream
2624 ********************************************************************/  
2625
2626 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
2627 {
2628         int size=0;
2629         size+=size_of_uint32( &info->jobid );
2630         size+=size_of_relative_string( &info->printername );
2631         size+=size_of_relative_string( &info->machinename );
2632         size+=size_of_relative_string( &info->username );
2633         size+=size_of_relative_string( &info->document );
2634         size+=size_of_relative_string( &info->datatype );
2635         size+=size_of_relative_string( &info->text_status );
2636         size+=size_of_uint32( &info->status );
2637         size+=size_of_uint32( &info->priority );
2638         size+=size_of_uint32( &info->position );
2639         size+=size_of_uint32( &info->totalpages );
2640         size+=size_of_uint32( &info->pagesprinted );
2641         size+=size_of_systemtime( &info->submitted );
2642
2643         return size;
2644 }
2645
2646 /*******************************************************************
2647 return the size required by a struct in the stream
2648 ********************************************************************/  
2649
2650 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
2651 {
2652         int size=0;
2653
2654         size+=4; /* size of sec desc ptr */
2655
2656         size+=size_of_uint32( &info->jobid );
2657         size+=size_of_relative_string( &info->printername );
2658         size+=size_of_relative_string( &info->machinename );
2659         size+=size_of_relative_string( &info->username );
2660         size+=size_of_relative_string( &info->document );
2661         size+=size_of_relative_string( &info->notifyname );
2662         size+=size_of_relative_string( &info->datatype );
2663         size+=size_of_relative_string( &info->printprocessor );
2664         size+=size_of_relative_string( &info->parameters );
2665         size+=size_of_relative_string( &info->drivername );
2666         size+=size_of_device_mode( info->devmode );
2667         size+=size_of_relative_string( &info->text_status );
2668 /*      SEC_DESC sec_desc;*/
2669         size+=size_of_uint32( &info->status );
2670         size+=size_of_uint32( &info->priority );
2671         size+=size_of_uint32( &info->position );
2672         size+=size_of_uint32( &info->starttime );
2673         size+=size_of_uint32( &info->untiltime );
2674         size+=size_of_uint32( &info->totalpages );
2675         size+=size_of_uint32( &info->size );
2676         size+=size_of_systemtime( &info->submitted );
2677         size+=size_of_uint32( &info->timeelapsed );
2678         size+=size_of_uint32( &info->pagesprinted );
2679
2680         return size;
2681 }
2682
2683 /*******************************************************************
2684 return the size required by a struct in the stream
2685 ********************************************************************/
2686
2687 uint32 spoolss_size_form_1(FORM_1 *info)
2688 {
2689         int size=0;
2690
2691         size+=size_of_uint32( &info->flag );
2692         size+=size_of_relative_string( &info->name );
2693         size+=size_of_uint32( &info->width );
2694         size+=size_of_uint32( &info->length );
2695         size+=size_of_uint32( &info->left );
2696         size+=size_of_uint32( &info->top );
2697         size+=size_of_uint32( &info->right );
2698         size+=size_of_uint32( &info->bottom );
2699
2700         return size;
2701 }
2702
2703 /*******************************************************************
2704 return the size required by a struct in the stream
2705 ********************************************************************/  
2706
2707 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
2708 {
2709         int size=0;
2710
2711         size+=size_of_relative_string( &info->port_name );
2712
2713         return size;
2714 }
2715
2716 /*******************************************************************
2717 return the size required by a struct in the stream
2718 ********************************************************************/  
2719
2720 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
2721 {
2722         int size=0;
2723
2724         size=str_len_uni(&info->name);  /* the string length       */
2725         size=size+1;                    /* add the leading zero    */
2726         size=size*2;                    /* convert in char         */
2727
2728         return size;
2729 }
2730
2731 /*******************************************************************
2732 return the size required by a struct in the stream
2733 ********************************************************************/  
2734
2735 uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
2736 {
2737         int size=0;
2738
2739         size=str_len_uni(&info->name);  /* the string length       */
2740         size=size+1;                    /* add the leading zero    */
2741         size=size*2;                    /* convert in char         */
2742
2743         return size;
2744 }
2745
2746 /*******************************************************************
2747 return the size required by a struct in the stream
2748 ********************************************************************/  
2749
2750 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
2751 {
2752         int size=0;
2753
2754         size+=size_of_relative_string( &info->port_name );
2755         size+=size_of_relative_string( &info->monitor_name );
2756         size+=size_of_relative_string( &info->description );
2757
2758         size+=size_of_uint32( &info->port_type );
2759         size+=size_of_uint32( &info->reserved );
2760
2761         return size;
2762 }
2763
2764 /*******************************************************************
2765 return the size required by a struct in the stream
2766 ********************************************************************/  
2767
2768 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
2769 {
2770         int size=0;
2771         size+=size_of_relative_string( &info->name );
2772
2773         return size;
2774 }
2775
2776 /*******************************************************************
2777 return the size required by a struct in the stream
2778 ********************************************************************/  
2779
2780 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
2781 {
2782         int size=0;
2783         size+=size_of_relative_string( &info->name );
2784
2785         return size;
2786 }
2787
2788 /*******************************************************************
2789 return the size required by a struct in the stream
2790 ********************************************************************/  
2791 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
2792 {
2793         uint32  size = 0; 
2794         
2795         if (!p)
2796                 return 0;
2797         
2798         /* uint32(offset) + uint32(length) + length) */
2799         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
2800         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
2801         
2802         size += size_of_uint32(&p->type);
2803                        
2804         return size;
2805 }
2806
2807 /*******************************************************************
2808 return the size required by a struct in the stream
2809 ********************************************************************/  
2810
2811 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
2812 {
2813         int size=0;
2814         size+=size_of_relative_string( &info->name );
2815
2816         return size;
2817 }
2818
2819 /*******************************************************************
2820 return the size required by a struct in the stream
2821 ********************************************************************/  
2822
2823 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
2824 {
2825         int size=0;
2826         size+=size_of_relative_string( &info->name);
2827         size+=size_of_relative_string( &info->environment);
2828         size+=size_of_relative_string( &info->dll_name);
2829
2830         return size;
2831 }
2832
2833 /*******************************************************************
2834  * init a structure.
2835  ********************************************************************/
2836
2837 bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
2838                                const POLICY_HND *hnd,
2839                                const fstring architecture,
2840                                uint32 level, uint32 clientmajor, uint32 clientminor,
2841                                RPC_BUFFER *buffer, uint32 offered)
2842 {      
2843         if (q_u == NULL)
2844                 return False;
2845
2846         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2847
2848         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
2849
2850         q_u->level=level;
2851         q_u->clientmajorversion=clientmajor;
2852         q_u->clientminorversion=clientminor;
2853
2854         q_u->buffer=buffer;
2855         q_u->offered=offered;
2856
2857         return True;
2858 }
2859
2860 /*******************************************************************
2861  * read a structure.
2862  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2863  ********************************************************************/
2864
2865 bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
2866 {
2867         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
2868         depth++;
2869
2870         if(!prs_align(ps))
2871                 return False;
2872         
2873         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2874                 return False;
2875         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
2876                 return False;
2877         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
2878                 return False;
2879         
2880         if(!prs_align(ps))
2881                 return False;
2882         if(!prs_uint32("level", ps, depth, &q_u->level))
2883                 return False;
2884                 
2885         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2886                 return False;
2887
2888         if(!prs_align(ps))
2889                 return False;
2890
2891         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2892                 return False;
2893                 
2894         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
2895                 return False;
2896         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
2897                 return False;
2898
2899         return True;
2900 }
2901
2902 /*******************************************************************
2903  * read a structure.
2904  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2905  ********************************************************************/
2906
2907 bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
2908 {
2909         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
2910         depth++;
2911
2912         if (!prs_align(ps))
2913                 return False;
2914                 
2915         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2916                 return False;
2917
2918         if (!prs_align(ps))
2919                 return False;
2920         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2921                 return False;
2922         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
2923                 return False;
2924         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
2925                 return False;           
2926         if (!prs_werror("status", ps, depth, &r_u->status))
2927                 return False;
2928
2929         return True;            
2930 }
2931
2932 /*******************************************************************
2933  * init a structure.
2934  ********************************************************************/
2935
2936 bool make_spoolss_q_enumprinters(
2937         SPOOL_Q_ENUMPRINTERS *q_u, 
2938         uint32 flags, 
2939         char *servername, 
2940         uint32 level, 
2941         RPC_BUFFER *buffer, 
2942         uint32 offered
2943 )
2944 {
2945         q_u->flags=flags;
2946         
2947         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
2948         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
2949
2950         q_u->level=level;
2951         q_u->buffer=buffer;
2952         q_u->offered=offered;
2953
2954         return True;
2955 }
2956
2957 /*******************************************************************
2958  * init a structure.
2959  ********************************************************************/
2960
2961 bool make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
2962                                 fstring servername, uint32 level, 
2963                                 RPC_BUFFER *buffer, uint32 offered)
2964 {
2965         q_u->name_ptr = (servername != NULL) ? 1 : 0;
2966         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
2967
2968         q_u->level=level;
2969         q_u->buffer=buffer;
2970         q_u->offered=offered;
2971
2972         return True;
2973 }
2974
2975 /*******************************************************************
2976  * read a structure.
2977  * called from spoolss_enumprinters (srv_spoolss.c)
2978  ********************************************************************/
2979
2980 bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
2981 {
2982         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
2983         depth++;
2984
2985         if (!prs_align(ps))
2986                 return False;
2987
2988         if (!prs_uint32("flags", ps, depth, &q_u->flags))
2989                 return False;
2990         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
2991                 return False;
2992
2993         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
2994                 return False;
2995                 
2996         if (!prs_align(ps))
2997                 return False;
2998         if (!prs_uint32("level", ps, depth, &q_u->level))
2999                 return False;
3000
3001         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3002                 return False;
3003
3004         if (!prs_align(ps))
3005                 return False;
3006         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3007                 return False;
3008
3009         return True;
3010 }
3011
3012 /*******************************************************************
3013  Parse a SPOOL_R_ENUMPRINTERS structure.
3014  ********************************************************************/
3015
3016 bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
3017 {
3018         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
3019         depth++;
3020
3021         if (!prs_align(ps))
3022                 return False;
3023                 
3024         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3025                 return False;
3026
3027         if (!prs_align(ps))
3028                 return False;
3029                 
3030         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3031                 return False;
3032                 
3033         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3034                 return False;
3035                 
3036         if (!prs_werror("status", ps, depth, &r_u->status))
3037                 return False;
3038
3039         return True;            
3040 }
3041
3042 /*******************************************************************
3043  * write a structure.
3044  * called from spoolss_r_enum_printers (srv_spoolss.c)
3045  *
3046  ********************************************************************/
3047
3048 bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
3049 {       
3050         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
3051         depth++;
3052
3053         if (!prs_align(ps))
3054                 return False;
3055                 
3056         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3057                 return False;
3058
3059         if (!prs_align(ps))
3060                 return False;
3061
3062         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3063                 return False;
3064                 
3065         if (!prs_werror("status", ps, depth, &r_u->status))
3066                 return False;
3067
3068         return True;            
3069 }
3070
3071 /*******************************************************************
3072  * read a structure.
3073  * called from spoolss_getprinter (srv_spoolss.c)
3074  ********************************************************************/
3075
3076 bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
3077 {
3078         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
3079         depth++;
3080
3081         if (!prs_align(ps))
3082                 return False;
3083
3084         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3085                 return False;
3086         if (!prs_uint32("level", ps, depth, &q_u->level))
3087                 return False;
3088
3089         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3090                 return False;
3091
3092         if (!prs_align(ps))
3093                 return False;
3094         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3095                 return False;
3096
3097         return True;
3098 }
3099
3100 /*******************************************************************
3101  * init a structure.
3102  ********************************************************************/
3103
3104 bool make_spoolss_q_getprinter(
3105         TALLOC_CTX *mem_ctx,
3106         SPOOL_Q_GETPRINTER *q_u, 
3107         const POLICY_HND *hnd, 
3108         uint32 level, 
3109         RPC_BUFFER *buffer, 
3110         uint32 offered
3111 )
3112 {
3113         if (q_u == NULL)
3114         {
3115                 return False;
3116         }
3117         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3118
3119         q_u->level=level;
3120         q_u->buffer=buffer;
3121         q_u->offered=offered;
3122
3123         return True;
3124 }
3125
3126 /*******************************************************************
3127  * init a structure.
3128  ********************************************************************/
3129 bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
3130                                 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
3131                                 uint32 command)
3132 {
3133         SEC_DESC *secdesc;
3134         DEVICEMODE *devmode;
3135
3136         if (!q_u || !info)
3137                 return False;
3138         
3139         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3140
3141         q_u->level = level;
3142         q_u->info.level = level;
3143         q_u->info.info_ptr = 1; /* Info is != NULL, see above */
3144         switch (level) {
3145
3146           /* There's no such thing as a setprinter level 1 */
3147
3148         case 2:
3149                 secdesc = info->printers_2->secdesc;
3150                 devmode = info->printers_2->devmode;
3151                 
3152                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
3153 #if 1   /* JERRY TEST */
3154                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3155                 if (!q_u->secdesc_ctr)
3156                         return False;
3157                 q_u->secdesc_ctr->sd = secdesc;
3158                 q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3159
3160                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
3161                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
3162                 q_u->devmode_ctr.devmode = devmode;
3163 #else
3164                 q_u->secdesc_ctr = NULL;
3165         
3166                 q_u->devmode_ctr.devmode_ptr = 0;
3167                 q_u->devmode_ctr.size = 0;
3168                 q_u->devmode_ctr.devmode = NULL;
3169 #endif
3170                 break;
3171         case 3:
3172                 secdesc = info->printers_3->secdesc;
3173                 
3174                 make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
3175                 
3176                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3177                 if (!q_u->secdesc_ctr)
3178                         return False;
3179                 q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3180                 q_u->secdesc_ctr->sd = secdesc;
3181
3182                 break;
3183         case 7:
3184                 make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
3185                 break;
3186
3187         default: 
3188                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
3189                         break;
3190         }
3191
3192         
3193         q_u->command = command;
3194
3195         return True;
3196 }
3197
3198
3199 /*******************************************************************
3200 ********************************************************************/  
3201
3202 bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
3203 {               
3204         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
3205         depth++;
3206
3207         if(!prs_align(ps))
3208                 return False;
3209         
3210         if(!prs_werror("status", ps, depth, &r_u->status))
3211                 return False;
3212
3213         return True;
3214 }
3215
3216 /*******************************************************************
3217  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
3218 ********************************************************************/  
3219
3220 bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
3221 {
3222         uint32 ptr_sec_desc = 0;
3223
3224         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
3225         depth++;
3226
3227         if(!prs_align(ps))
3228                 return False;
3229
3230         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
3231                 return False;
3232         if(!prs_uint32("level", ps, depth, &q_u->level))
3233                 return False;
3234         
3235         /* check for supported levels and structures we know about */
3236                 
3237         switch ( q_u->level ) {
3238                 case 0:
3239                 case 2:
3240                 case 3:
3241                 case 7:
3242                         /* supported levels */
3243                         break;
3244                 default:
3245                         DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
3246                                 q_u->level));
3247                         return True;
3248         }
3249                         
3250
3251         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3252                 return False;
3253
3254         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3255                 return False;
3256         
3257         if(!prs_align(ps))
3258                 return False;
3259
3260         switch (q_u->level)
3261         {
3262                 case 2:
3263                 {
3264                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3265                         break;
3266                 }
3267                 case 3:
3268                 {
3269                         /* FIXME ! Our parsing here is wrong I think,
3270                          * but for a level3 it makes no sense for
3271                          * ptr_sec_desc to be NULL. JRA. Based on
3272                          * a Vista sniff from Martin Zielinski <mz@seh.de>.
3273                          */
3274                         if (UNMARSHALLING(ps)) {
3275                                 ptr_sec_desc = 1;
3276                         } else {
3277                                 ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3278                         }
3279                         break;
3280                 }
3281         }
3282         if (ptr_sec_desc)
3283         {
3284                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3285                         return False;
3286         } else {
3287                 uint32 dummy = 0;
3288
3289                 /* Parse a NULL security descriptor.  This should really
3290                    happen inside the sec_io_desc_buf() function. */
3291
3292                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3293                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3294                         return False;
3295                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3296                         return False;
3297         }
3298         
3299         if(!prs_uint32("command", ps, depth, &q_u->command))
3300                 return False;
3301
3302         return True;
3303 }
3304
3305 /*******************************************************************
3306 ********************************************************************/  
3307
3308 bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
3309 {               
3310         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
3311         depth++;
3312
3313         if (!prs_align(ps))
3314                 return False;
3315                 
3316         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3317                 return False;
3318
3319         if (!prs_align(ps))
3320                 return False;
3321                 
3322         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3323                 return False;
3324                 
3325         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3326                 return False;
3327                 
3328         if (!prs_werror("status", ps, depth, &r_u->status))
3329                 return False;
3330
3331         return True;            
3332 }
3333
3334 /*******************************************************************
3335 ********************************************************************/  
3336
3337 bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
3338                                 uint32 firstjob,
3339                                 uint32 numofjobs,
3340                                 uint32 level,
3341                                 RPC_BUFFER *buffer,
3342                                 uint32 offered)
3343 {
3344         if (q_u == NULL)
3345         {
3346                 return False;
3347         }
3348         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3349         q_u->firstjob = firstjob;
3350         q_u->numofjobs = numofjobs;
3351         q_u->level = level;
3352         q_u->buffer= buffer;
3353         q_u->offered = offered;
3354         return True;
3355 }
3356
3357 /*******************************************************************
3358 ********************************************************************/  
3359
3360 bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
3361 {
3362         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
3363         depth++;
3364
3365         if (!prs_align(ps))
3366                 return False;
3367
3368         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
3369                 return False;
3370                 
3371         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
3372                 return False;
3373         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
3374                 return False;
3375         if (!prs_uint32("level", ps, depth, &q_u->level))
3376                 return False;
3377
3378         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3379                 return False;   
3380
3381         if(!prs_align(ps))
3382                 return False;
3383
3384         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3385                 return False;
3386
3387         return True;
3388 }
3389
3390 /*******************************************************************
3391 ********************************************************************/  
3392
3393 bool spoolss_io_r_setjob(const char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
3394 {               
3395         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
3396         depth++;
3397
3398         if(!prs_align(ps))
3399                 return False;
3400         
3401         if(!prs_werror("status", ps, depth, &r_u->status))
3402                 return False;
3403
3404         return True;
3405 }
3406
3407 /*******************************************************************
3408 ********************************************************************/  
3409
3410 bool spoolss_io_q_setjob(const char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
3411 {
3412         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
3413         depth++;
3414
3415         if(!prs_align(ps))
3416                 return False;
3417
3418         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3419                 return False;
3420         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
3421                 return False;
3422         /* 
3423          * level is usually 0. If (level!=0) then I'm in trouble !
3424          * I will try to generate setjob command with level!=0, one day.
3425          */
3426         if(!prs_uint32("level", ps, depth, &q_u->level))
3427                 return False;
3428         if(!prs_uint32("command", ps, depth, &q_u->command))
3429                 return False;
3430
3431         return True;
3432 }
3433
3434 /*******************************************************************
3435  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
3436 ********************************************************************/  
3437
3438 bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
3439 {
3440         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
3441         depth++;
3442
3443         if (!prs_align(ps))
3444                 return False;
3445                 
3446         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3447                 return False;
3448
3449         if (!prs_align(ps))
3450                 return False;
3451                 
3452         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3453                 return False;
3454                 
3455         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3456                 return False;
3457                 
3458         if (!prs_werror("status", ps, depth, &r_u->status))
3459                 return False;
3460
3461         return True;            
3462 }
3463
3464 /*******************************************************************
3465  * init a structure.
3466  ********************************************************************/
3467
3468 bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
3469                                 const char *name,
3470                                 const char *environment,
3471                                 uint32 level,
3472                                 RPC_BUFFER *buffer, uint32 offered)
3473 {
3474         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
3475         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
3476
3477         q_u->level=level;
3478         q_u->buffer=buffer;
3479         q_u->offered=offered;
3480
3481         return True;
3482 }
3483
3484 /*******************************************************************
3485  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
3486 ********************************************************************/  
3487
3488 bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
3489 {
3490
3491         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
3492         depth++;
3493
3494         if (!prs_align(ps))
3495                 return False;
3496                 
3497         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3498                 return False;
3499         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
3500                 return False;
3501                 
3502         if (!prs_align(ps))
3503                 return False;
3504         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
3505                 return False;
3506         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3507                 return False;
3508                 
3509         if (!prs_align(ps))
3510                 return False;
3511         if (!prs_uint32("level", ps, depth, &q_u->level))
3512                 return False;
3513                 
3514         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3515                 return False;
3516
3517         if (!prs_align(ps))
3518                 return False;
3519                 
3520         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3521                 return False;
3522
3523         return True;
3524 }
3525
3526 /*******************************************************************
3527 ********************************************************************/  
3528
3529 bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
3530 {
3531
3532         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
3533         depth++;
3534
3535         if (!prs_align(ps))
3536                 return False;                   
3537         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3538                 return False;           
3539         if (!prs_uint32("level", ps, depth, &q_u->level))
3540                 return False;   
3541         
3542         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3543                 return False;
3544
3545         if (!prs_align(ps))
3546                 return False;
3547         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3548                 return False;
3549
3550         return True;
3551 }
3552
3553 /*******************************************************************
3554 ********************************************************************/  
3555
3556 bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
3557 {
3558         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
3559         depth++;
3560
3561         if (!prs_align(ps))
3562                 return False;
3563                 
3564         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3565                 return False;
3566
3567         if (!prs_align(ps))
3568                 return False;
3569                 
3570         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
3571                 return False;
3572                 
3573         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
3574                 return False;
3575                 
3576         if (!prs_werror("status", ps, depth, &r_u->status))
3577                 return False;
3578
3579         return True;
3580 }
3581
3582 /*******************************************************************
3583  Parse a SPOOL_R_ENUMPORTS structure.
3584 ********************************************************************/  
3585
3586 bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
3587 {
3588         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
3589         depth++;
3590
3591         if (!prs_align(ps))
3592                 return False;
3593                 
3594         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3595                 return False;
3596
3597         if (!prs_align(ps))
3598                 return False;
3599                 
3600         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3601                 return False;
3602                 
3603         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3604                 return False;
3605                 
3606         if (!prs_werror("status", ps, depth, &r_u->status))
3607                 return False;
3608
3609         return True;            
3610 }
3611
3612 /*******************************************************************
3613 ********************************************************************/  
3614
3615 bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
3616 {
3617         prs_debug(ps, depth, desc, "");
3618         depth++;
3619
3620         if (!prs_align(ps))
3621                 return False;
3622
3623         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
3624                 return False;
3625         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
3626                 return False;
3627
3628         if (!prs_align(ps))
3629                 return False;
3630         if (!prs_uint32("level", ps, depth, &q_u->level))
3631                 return False;
3632                 
3633         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3634                 return False;
3635
3636         if (!prs_align(ps))
3637                 return False;
3638         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3639                 return False;
3640
3641         return True;
3642 }
3643
3644 /*******************************************************************
3645  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
3646 ********************************************************************/  
3647
3648 bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
3649 {       
3650         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
3651         depth++;
3652                 
3653         if(!prs_align(ps))
3654                 return False;
3655
3656         if(!prs_uint32("flags", ps, depth, &il->flags))
3657                 return False;
3658         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
3659                 return False;
3660         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
3661                 return False;
3662         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3663                 return False;
3664                 
3665         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
3666                 return False;
3667         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3668                 return False;
3669         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3670                 return False;
3671
3672         return True;
3673 }
3674
3675 /*******************************************************************
3676  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
3677 ********************************************************************/  
3678
3679 bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
3680 {       
3681         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
3682         depth++;
3683                 
3684         if(!prs_align(ps))
3685                 return False;
3686
3687         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
3688                 return False;
3689
3690         return True;
3691 }
3692
3693 /*******************************************************************
3694  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
3695 ********************************************************************/  
3696
3697 bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
3698 {       
3699         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
3700         depth++;
3701                 
3702         if(!prs_align(ps))
3703                 return False;
3704
3705         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
3706                 return False;
3707         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
3708                 return False;
3709         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
3710                 return False;
3711         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
3712                 return False;
3713
3714         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
3715                 return False;
3716         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3717                 return False;
3718         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
3719                 return False;
3720         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
3721                 return False;
3722         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
3723                 return False;
3724         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
3725                 return False;
3726         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
3727                 return False;
3728         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
3729                 return False;
3730         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
3731                 return False;
3732
3733         if(!prs_uint32("attributes", ps, depth, &il->attributes))
3734                 return False;
3735         if(!prs_uint32("priority", ps, depth, &il->priority))
3736                 return False;
3737         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
3738                 return False;
3739         if(!prs_uint32("starttime", ps, depth, &il->starttime))
3740                 return False;
3741         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
3742                 return False;
3743         if(!prs_uint32("status", ps, depth, &il->status))
3744                 return False;
3745         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
3746                 return False;
3747         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
3748                 return False;
3749
3750         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
3751                 return False;
3752         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
3753                 return False;
3754         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
3755                 return False;
3756         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
3757                 return False;
3758         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
3759                 return False;
3760         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3761                 return False;
3762         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
3763                 return False;
3764         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
3765                 return False;
3766         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
3767                 return False;
3768         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
3769                 return False;
3770         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
3771                 return False;
3772
3773         return True;
3774 }
3775
3776 bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
3777 {       
3778         prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
3779         depth++;
3780                 
3781         if(!prs_align(ps))
3782                 return False;
3783
3784         if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
3785                 return False;
3786         if(!prs_uint32("action", ps, depth, &il->action))
3787                 return False;
3788
3789         if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
3790                 return False;
3791         return True;
3792 }
3793
3794 /*******************************************************************
3795 ********************************************************************/  
3796
3797 bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
3798 {
3799         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
3800         depth++;
3801
3802         if(!prs_align(ps))
3803                 return False;
3804         if(!prs_uint32("level", ps, depth, &il->level))
3805                 return False;
3806         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
3807                 return False;
3808         
3809         /* if no struct inside just return */
3810         if (il->info_ptr==0) {
3811                 if (UNMARSHALLING(ps)) {
3812                         il->info_1=NULL;
3813                         il->info_2=NULL;
3814                 }
3815                 return True;
3816         }
3817                         
3818         switch (il->level) {
3819                 /*
3820                  * level 0 is used by setprinter when managing the queue
3821                  * (hold, stop, start a queue)
3822                  */
3823                 case 0:
3824                         break;
3825                 /* DOCUMENT ME!!! What is level 1 used for? */
3826                 case 1:
3827                 {
3828                         if (UNMARSHALLING(ps)) {
3829                                 if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
3830                                         return False;
3831                         }
3832                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
3833                                 return False;
3834                         break;          
3835                 }
3836                 /* 
3837                  * level 2 is used by addprinter
3838                  * and by setprinter when updating printer's info
3839                  */     
3840                 case 2:
3841                         if (UNMARSHALLING(ps)) {
3842                                 if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
3843                                         return False;
3844                         }
3845                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
3846                                 return False;
3847                         break;          
3848                 /* DOCUMENT ME!!! What is level 3 used for? */
3849                 case 3:
3850                 {
3851                         if (UNMARSHALLING(ps)) {
3852                                 if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
3853                                         return False;
3854                         }
3855                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
3856                                 return False;
3857                         break;          
3858                 }
3859                 case 7:
3860                         if (UNMARSHALLING(ps))
3861                                 if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
3862                                         return False;
3863                         if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
3864                                 return False;
3865                         break;
3866         }
3867
3868         return True;
3869 }
3870
3871 /*******************************************************************
3872 ********************************************************************/  
3873
3874 bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
3875 {
3876         uint32 ptr_sec_desc = 0;
3877
3878         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
3879         depth++;
3880
3881         if(!prs_align(ps))
3882                 return False;
3883
3884         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
3885                 return False;
3886         if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
3887                 return False;
3888
3889         if(!prs_align(ps))
3890                 return False;
3891
3892         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3893                 return False;
3894         
3895         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3896                 return False;
3897         
3898         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3899                 return False;
3900
3901         if(!prs_align(ps))
3902                 return False;
3903
3904         switch (q_u->level) {
3905                 case 2:
3906                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3907                         break;
3908                 case 3:
3909                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3910                         break;
3911         }
3912         if (ptr_sec_desc) {
3913                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3914                         return False;
3915         } else {
3916                 uint32 dummy = 0;
3917
3918                 /* Parse a NULL security descriptor.  This should really
3919                         happen inside the sec_io_desc_buf() function. */
3920
3921                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3922                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3923                         return False;
3924                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3925                         return False;
3926         }
3927
3928         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
3929                 return False;
3930         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
3931                 return False;
3932
3933         return True;
3934 }
3935
3936 /*******************************************************************
3937 ********************************************************************/  
3938
3939 bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
3940                                prs_struct *ps, int depth)
3941 {
3942         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
3943         depth++;
3944         
3945         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
3946                 return False;
3947
3948         if(!prs_werror("status", ps, depth, &r_u->status))
3949                 return False;
3950
3951         return True;
3952 }
3953
3954 /*******************************************************************
3955 ********************************************************************/  
3956
3957 bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
3958                                           prs_struct *ps, int depth)
3959 {       
3960         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
3961         
3962         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
3963         depth++;
3964                 
3965         /* reading */
3966         if (UNMARSHALLING(ps)) {
3967                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
3968                 if(il == NULL)
3969                         return False;
3970                 *q_u=il;
3971         }
3972         else {
3973                 il=*q_u;
3974         }
3975         
3976         if(!prs_align(ps))
3977                 return False;
3978
3979         if(!prs_uint32("cversion", ps, depth, &il->cversion))
3980                 return False;
3981         if(!prs_uint32("name", ps, depth, &il->name_ptr))
3982                 return False;
3983         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
3984                 return False;
3985         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
3986                 return False;
3987         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
3988                 return False;
3989         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
3990                 return False;
3991         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
3992                 return False;
3993         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
3994                 return False;
3995         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3996                 return False;
3997         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
3998                 return False;
3999         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
4000                 return False;
4001
4002         if(!prs_align(ps))
4003                 return False;
4004         
4005         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4006                 return False;
4007         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4008                 return False;
4009         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4010                 return False;
4011         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4012                 return False;
4013         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4014                 return False;
4015         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4016                 return False;
4017         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4018                 return False;
4019         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4020                 return False;
4021
4022         if(!prs_align(ps))
4023                 return False;
4024                 
4025         if (il->dependentfiles_ptr)
4026                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
4027
4028         return True;
4029 }
4030
4031 /*******************************************************************
4032 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
4033 ********************************************************************/  
4034
4035 bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
4036                                           prs_struct *ps, int depth)
4037 {       
4038         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
4039         
4040         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
4041         depth++;
4042                 
4043         /* reading */
4044         if (UNMARSHALLING(ps)) {
4045                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
4046                 if(il == NULL)
4047                         return False;
4048                 *q_u=il;
4049         }
4050         else {
4051                 il=*q_u;
4052         }
4053         
4054         if(!prs_align(ps))
4055                 return False;
4056
4057         /* 
4058          * I know this seems weird, but I have no other explanation.
4059          * This is observed behavior on both NT4 and 2K servers.
4060          * --jerry
4061          */
4062          
4063         if (!prs_align_uint64(ps))
4064                 return False;
4065
4066         /* parse the main elements the packet */
4067
4068         if(!prs_uint32("cversion       ", ps, depth, &il->version))
4069                 return False;
4070         if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
4071                 return False;
4072         if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
4073                 return False;
4074         if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
4075                 return False;
4076         if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
4077                 return False;
4078         if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
4079                 return False;
4080         if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
4081                 return False;
4082         if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
4083                 return False;
4084         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4085                 return False;
4086         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
4087                 return False;
4088         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
4089                 return False;
4090         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
4091                 return False;
4092         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
4093                 return False;
4094         if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
4095                 return False;
4096         if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
4097                 return False;
4098         if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
4099                 return False;
4100         if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
4101                 return False;
4102         if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
4103                 return False;
4104         if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
4105                 return False;
4106         if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
4107                 return False;
4108
4109         /* parse the structures in the packet */
4110
4111         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4112                 return False;
4113         if(!prs_align(ps))
4114                 return False;
4115
4116         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4117                 return False;
4118         if(!prs_align(ps))
4119                 return False;
4120
4121         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4122                 return False;
4123         if(!prs_align(ps))
4124                 return False;
4125
4126         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4127                 return False;
4128         if(!prs_align(ps))
4129                 return False;
4130
4131         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4132                 return False;
4133         if(!prs_align(ps))
4134                 return False;
4135
4136         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4137                 return False;
4138         if(!prs_align(ps))
4139                 return False;
4140
4141         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4142                 return False;
4143         if(!prs_align(ps))
4144                 return False;
4145
4146         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4147                 return False;
4148         if(!prs_align(ps))
4149                 return False;
4150         if (il->dependentfiles_ptr) {
4151                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
4152                         return False;
4153                 if(!prs_align(ps))
4154                         return False;
4155         }
4156         if (il->previousnames_ptr) {
4157                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
4158                         return False;
4159                 if(!prs_align(ps))
4160                         return False;
4161         }
4162         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
4163                 return False;
4164         if(!prs_align(ps))
4165                 return False;
4166         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
4167                 return False;
4168         if(!prs_align(ps))
4169                 return False;
4170         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
4171                 return False;
4172         if(!prs_align(ps))
4173                 return False;
4174         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
4175                 return False;
4176
4177         return True;
4178 }
4179
4180 /*******************************************************************
4181  convert a buffer of UNICODE strings null terminated
4182  the buffer is terminated by a NULL
4183  
4184  convert to an dos codepage array (null terminated)
4185  
4186  dynamically allocate memory
4187  
4188 ********************************************************************/  
4189
4190 static bool uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
4191 {
4192         fstring f;
4193         int n = 0;
4194         char *src;
4195
4196         if (buf5==NULL)
4197                 return False;
4198
4199         src = (char *)buf5->buffer;
4200         *ar = SMB_MALLOC_ARRAY(fstring, 1);
4201         if (!*ar) {
4202                 return False;
4203         }
4204
4205         while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
4206                 rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
4207                 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
4208                 *ar = SMB_REALLOC_ARRAY(*ar, fstring, n+2);
4209                 if (!*ar) {
4210                         return False;
4211                 }
4212                 fstrcpy((*ar)[n], f);
4213                 n++;
4214         }
4215
4216         fstrcpy((*ar)[n], "");
4217  
4218         return True;
4219 }
4220
4221 /*******************************************************************
4222  read a UNICODE array with null terminated strings 
4223  and null terminated array 
4224  and size of array at beginning
4225 ********************************************************************/  
4226
4227 bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
4228 {
4229         if (buffer==NULL) return False;
4230
4231         buffer->offset=0;
4232         buffer->uni_str_len=buffer->uni_max_len;
4233         
4234         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
4235                 return False;
4236
4237         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
4238                 return False;
4239
4240         return True;
4241 }
4242
4243 /*******************************************************************
4244 ********************************************************************/  
4245
4246 bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
4247 {
4248         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
4249         depth++;
4250
4251         if(!prs_align(ps))
4252                 return False;
4253         if(!prs_uint32("level", ps, depth, &il->level))
4254                 return False;
4255         if(!prs_uint32("ptr", ps, depth, &il->ptr))
4256                 return False;
4257
4258         if (il->ptr==0)
4259                 return True;
4260                 
4261         switch (il->level) {
4262                 case 3:
4263                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
4264                                 return False;
4265                         break;          
4266                 case 6:
4267                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
4268                                 return False;
4269                         break;          
4270         default:
4271                 return False;
4272         }
4273
4274         return True;
4275 }
4276
4277 /*******************************************************************
4278  init a SPOOL_Q_ADDPRINTERDRIVER struct
4279  ******************************************************************/
4280
4281 bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
4282                                 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
4283                                 uint32 level, PRINTER_DRIVER_CTR *info)
4284 {
4285         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
4286         
4287         if (!srv_name || !info) {
4288                 return False;
4289         }
4290
4291         q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */
4292         init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
4293         
4294         q_u->level = level;
4295         
4296         q_u->info.level = level;
4297         q_u->info.ptr = 1;      /* Info is != NULL, see above */
4298         switch (level)
4299         {
4300         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
4301         case 3 :
4302                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
4303                 break;
4304                 
4305         default:
4306                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
4307                 break;
4308         }
4309         
4310         return True;
4311 }
4312
4313 bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
4314         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
4315                                 DRIVER_INFO_3 *info3)
4316 {
4317         uint32          len = 0;
4318         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
4319
4320         if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
4321                 return False;
4322
4323         inf->cversion   = info3->version;
4324         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
4325         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
4326         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
4327         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
4328         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
4329         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
4330         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
4331         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
4332
4333         init_unistr2_from_unistr(inf, &inf->name, &info3->name);
4334         init_unistr2_from_unistr(inf, &inf->environment, &info3->architecture);
4335         init_unistr2_from_unistr(inf, &inf->driverpath, &info3->driverpath);
4336         init_unistr2_from_unistr(inf, &inf->datafile, &info3->datafile);
4337         init_unistr2_from_unistr(inf, &inf->configfile, &info3->configfile);
4338         init_unistr2_from_unistr(inf, &inf->helpfile, &info3->helpfile);
4339         init_unistr2_from_unistr(inf, &inf->monitorname, &info3->monitorname);
4340         init_unistr2_from_unistr(inf, &inf->defaultdatatype, &info3->defaultdatatype);
4341
4342         if (info3->dependentfiles) {
4343                 bool done = False;
4344                 bool null_char = False;
4345                 uint16 *ptr = info3->dependentfiles;
4346
4347                 while (!done) {
4348                         switch (*ptr) {
4349                                 case 0:
4350                                         /* the null_char bool is used to help locate
4351                                            two '\0's back to back */
4352                                         if (null_char) {
4353                                                 done = True;
4354                                         } else {
4355                                                 null_char = True;
4356                                         }
4357                                         break;
4358                                         
4359                                 default:
4360                                         null_char = False;
4361                                         break;                          
4362                         }
4363                         len++;
4364                         ptr++;
4365                 }
4366         }
4367
4368         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
4369         inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0;
4370         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) {
4371                 SAFE_FREE(inf);
4372                 return False;
4373         }
4374         
4375         *spool_drv_info = inf;
4376         
4377         return True;
4378 }
4379
4380 /*******************************************************************
4381  make a BUFFER5 struct from a uint16*
4382  ******************************************************************/
4383
4384 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
4385 {
4386
4387         buf5->buf_len = len;
4388         if (src) {
4389                 if (len) {
4390                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
4391                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
4392                                 return False;
4393                         }
4394                 } else {
4395                         buf5->buffer = NULL;
4396                 }
4397         } else {
4398                 buf5->buffer=NULL;
4399         }
4400         
4401         return True;
4402 }
4403
4404 /*******************************************************************
4405  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
4406  ********************************************************************/  
4407
4408 bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
4409 {
4410         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
4411         depth++;
4412
4413         if(!prs_align(ps))
4414                 return False;
4415
4416         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
4417                 return False;
4418         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4419                 return False;
4420                 
4421         if(!prs_align(ps))
4422                 return False;
4423         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4424                 return False;
4425
4426         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
4427                 return False;
4428
4429         return True;
4430 }
4431
4432 /*******************************************************************
4433 ********************************************************************/  
4434
4435 bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
4436 {
4437         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
4438         depth++;
4439
4440         if(!prs_werror("status", ps, depth, &q_u->status))
4441                 return False;
4442
4443         return True;
4444 }
4445
4446 /*******************************************************************
4447  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
4448  ********************************************************************/  
4449
4450 bool spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
4451 {
4452         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
4453         depth++;
4454
4455         if(!prs_align(ps))
4456                 return False;
4457
4458         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
4459                 return False;
4460         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4461                 return False;
4462                 
4463         if(!prs_align(ps))
4464                 return False;
4465         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4466                 return False;
4467
4468         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
4469                 return False;
4470
4471         if(!prs_align(ps))
4472                 return False;
4473         if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
4474                 return False;
4475                 
4476         return True;
4477 }
4478
4479 /*******************************************************************
4480 ********************************************************************/  
4481
4482 bool spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
4483 {
4484         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
4485         depth++;
4486
4487         if(!prs_werror("status", ps, depth, &q_u->status))
4488                 return False;
4489
4490         return True;
4491 }
4492
4493 /*******************************************************************
4494 ********************************************************************/  
4495
4496 bool uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
4497                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
4498 {
4499         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
4500         
4501         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
4502         
4503         if (*asc==NULL)
4504         {
4505                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
4506                 if(*asc == NULL)
4507                         return False;
4508                 ZERO_STRUCTP(*asc);
4509         }       
4510
4511         d=*asc;
4512
4513         d->cversion=uni->cversion;
4514
4515         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name));
4516         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment));
4517         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath));
4518         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile));
4519         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile));
4520         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile));
4521         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname));
4522         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype));
4523
4524         DEBUGADD(8,( "version:         %d\n", d->cversion));
4525         DEBUGADD(8,( "name:            %s\n", d->name));
4526         DEBUGADD(8,( "environment:     %s\n", d->environment));
4527         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
4528         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
4529         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
4530         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
4531         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
4532         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
4533
4534         if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
4535                 return True;
4536         
4537         SAFE_FREE(*asc);
4538         return False;
4539 }
4540
4541 /*******************************************************************
4542 ********************************************************************/  
4543 bool uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
4544                                 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
4545 {
4546         NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
4547         
4548         DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
4549         
4550         if (*asc==NULL)
4551         {
4552                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
4553                 if(*asc == NULL)
4554                         return False;
4555                 ZERO_STRUCTP(*asc);
4556         }       
4557
4558         d=*asc;
4559
4560         d->version=uni->version;
4561
4562         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name));
4563         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment));
4564         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath));
4565         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile));
4566         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile));
4567         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile));
4568         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname));
4569         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype));
4570
4571         DEBUGADD(8,( "version:         %d\n", d->version));
4572         DEBUGADD(8,( "name:            %s\n", d->name));
4573         DEBUGADD(8,( "environment:     %s\n", d->environment));
4574         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
4575         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
4576         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
4577         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
4578         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
4579         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
4580
4581         if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
4582                 goto error;
4583         if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
4584                 goto error;
4585         
4586         return True;
4587         
4588 error:
4589         SAFE_FREE(*asc);
4590         return False;
4591 }
4592
4593 bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
4594                               NT_PRINTER_INFO_LEVEL_2  *d)
4595 {
4596         DEBUG(7,("Converting from UNICODE to ASCII\n"));
4597         
4598         d->attributes=uni->attributes;
4599         d->priority=uni->priority;
4600         d->default_priority=uni->default_priority;
4601         d->starttime=uni->starttime;
4602         d->untiltime=uni->untiltime;
4603         d->status=uni->status;
4604         d->cjobs=uni->cjobs;
4605         
4606         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername));
4607         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername));
4608         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename));
4609         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname));
4610         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername));
4611         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment));
4612         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location));
4613         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile));
4614         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor));
4615         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype));
4616         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters));
4617
4618         return True;
4619 }
4620
4621 /*******************************************************************
4622  * init a structure.
4623  ********************************************************************/
4624
4625 bool make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
4626                                 fstring servername, fstring env_name, uint32 level,
4627                                 RPC_BUFFER *buffer, uint32 offered)
4628 {
4629         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
4630         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
4631
4632         q_u->level=level;
4633         q_u->buffer=buffer;
4634         q_u->offered=offered;
4635
4636         return True;
4637 }
4638
4639 /*******************************************************************
4640  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
4641 ********************************************************************/  
4642
4643 bool spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
4644 {
4645         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
4646         depth++;
4647
4648         if(!prs_align(ps))
4649                 return False;
4650         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4651                 return False;
4652         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
4653                 return False;
4654
4655         if(!prs_align(ps))
4656                 return False;
4657                 
4658         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
4659                 return False;
4660         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4661                 return False;
4662                 
4663         if(!prs_align(ps))
4664                 return False;
4665
4666         if(!prs_uint32("level", ps, depth, &q_u->level))
4667                 return False;
4668                 
4669         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4670                 return False;
4671                 
4672         if(!prs_align(ps))
4673                 return False;
4674                 
4675         if(!prs_uint32("offered", ps, depth, &q_u->offered))
4676                 return False;
4677
4678         return True;
4679 }
4680
4681 /*******************************************************************
4682  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
4683 ********************************************************************/  
4684
4685 bool spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
4686 {               
4687         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
4688         depth++;
4689
4690         if (!prs_align(ps))
4691                 return False;
4692                 
4693         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4694                 return False;
4695
4696         if (!prs_align(ps))
4697                 return False;
4698                 
4699         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4700                 return False;
4701                 
4702         if (!prs_werror("status", ps, depth, &r_u->status))
4703                 return False;
4704
4705         return True;            
4706 }
4707
4708 /*******************************************************************
4709 ********************************************************************/  
4710
4711 bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
4712 {               
4713         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
4714         depth++;
4715
4716         if (!prs_align(ps))
4717                 return False;
4718                 
4719         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4720                 return False;
4721
4722         if (!prs_align(ps))
4723                 return False;
4724                 
4725         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4726                 return False;
4727                 
4728         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4729                 return False;
4730                 
4731         if (!prs_werror("status", ps, depth, &r_u->status))
4732                 return False;
4733
4734         return True;            
4735 }
4736
4737 /*******************************************************************
4738 ********************************************************************/  
4739
4740 bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
4741 {
4742         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
4743         depth++;
4744
4745         if (!prs_align(ps))
4746                 return False;
4747                 
4748         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4749                 return False;
4750         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4751                 return False;
4752                 
4753         if (!prs_align(ps))
4754                 return False;
4755                 
4756         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
4757                 return False;
4758         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4759                 return False;
4760         
4761         if (!prs_align(ps))
4762                 return False;
4763                 
4764         if (!prs_uint32("level", ps, depth, &q_u->level))
4765                 return False;
4766                 
4767         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4768                 return False;
4769
4770         if (!prs_align(ps))
4771                 return False;
4772
4773         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4774                 return False;
4775
4776         return True;
4777 }
4778
4779 /*******************************************************************
4780 ********************************************************************/  
4781
4782 bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
4783 {               
4784         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
4785         depth++;
4786
4787         if (!prs_align(ps))
4788                 return False;
4789                 
4790         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4791                 return False;
4792
4793         if (!prs_align(ps))
4794                 return False;
4795                 
4796         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4797                 return False;
4798                 
4799         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4800                 return False;
4801                 
4802         if (!prs_werror("status", ps, depth, &r_u->status))
4803                 return False;
4804
4805         return True;            
4806 }
4807
4808 /*******************************************************************
4809 ********************************************************************/  
4810
4811 bool spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
4812 {
4813         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
4814         depth++;
4815
4816         if (!prs_align(ps))
4817                 return False;
4818                 
4819         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4820                 return False;
4821         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4822                 return False;
4823                 
4824         if (!prs_align(ps))
4825                 return False;
4826                 
4827         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
4828                 return False;
4829         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
4830                 return False;
4831         
4832         if (!prs_align(ps))
4833                 return False;
4834                 
4835         if (!prs_uint32("level", ps, depth, &q_u->level))
4836                 return False;
4837                 
4838         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
4839                 return False;
4840
4841         if (!prs_align(ps))
4842                 return False;
4843
4844         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4845                 return False;
4846
4847         return True;
4848 }
4849
4850 /*******************************************************************
4851  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
4852 ********************************************************************/  
4853
4854 bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
4855 {
4856         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
4857         depth++;
4858
4859         if (!prs_align(ps))
4860                 return False;
4861                 
4862         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4863                 return False;
4864         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4865                 return False;
4866                 
4867         if (!prs_align(ps))
4868                 return False;
4869                                 
4870         if (!prs_uint32("level", ps, depth, &q_u->level))
4871                 return False;
4872                 
4873         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4874                 return False;
4875
4876         if (!prs_align(ps))
4877                 return False;
4878
4879         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4880                 return False;
4881
4882         return True;
4883 }
4884
4885 /*******************************************************************
4886 ********************************************************************/  
4887
4888 bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
4889 {               
4890         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
4891         depth++;
4892
4893         if (!prs_align(ps))
4894                 return False;
4895                 
4896         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4897                 return False;
4898
4899         if (!prs_align(ps))
4900                 return False;
4901                 
4902         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4903                 return False;
4904                 
4905         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4906                 return False;
4907                 
4908         if (!prs_werror("status", ps, depth, &r_u->status))
4909                 return False;
4910
4911         return True;            
4912 }
4913
4914 /*******************************************************************
4915 ********************************************************************/  
4916
4917 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
4918 {       
4919         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
4920         depth++;
4921
4922         if(!prs_align(ps))
4923                 return False;
4924         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
4925                 return False;
4926
4927         if (UNMARSHALLING(ps) && r_u->valuesize) {
4928                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
4929                 if (!r_u->value) {
4930                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
4931                         return False;
4932                 }
4933         }
4934
4935         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
4936                 return False;
4937
4938         if(!prs_align(ps))
4939                 return False;
4940
4941         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
4942                 return False;
4943
4944         if(!prs_uint32("type", ps, depth, &r_u->type))
4945                 return False;
4946
4947         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
4948                 return False;
4949
4950         if (UNMARSHALLING(ps) && r_u->datasize) {
4951                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
4952                 if (!r_u->data) {
4953                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
4954                         return False;
4955                 }
4956         }
4957
4958         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
4959                 return False;
4960         if(!prs_align(ps))
4961                 return False;
4962
4963         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
4964                 return False;
4965         if(!prs_werror("status", ps, depth, &r_u->status))
4966                 return False;
4967
4968         return True;
4969 }
4970
4971 /*******************************************************************
4972 ********************************************************************/  
4973
4974 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
4975 {
4976         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
4977         depth++;
4978
4979         if(!prs_align(ps))
4980                 return False;
4981         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4982                 return False;
4983         if(!prs_uint32("index", ps, depth, &q_u->index))
4984                 return False;
4985         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
4986                 return False;
4987         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
4988                 return False;
4989
4990         return True;
4991 }
4992
4993 /*******************************************************************
4994 ********************************************************************/  
4995
4996 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
4997                 const POLICY_HND *hnd,
4998                 uint32 idx, uint32 valuelen, uint32 datalen)
4999 {
5000         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5001         q_u->index=idx;
5002         q_u->valuesize=valuelen;
5003         q_u->datasize=datalen;
5004
5005         return True;
5006 }
5007
5008 /*******************************************************************
5009 ********************************************************************/  
5010
5011 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
5012                                       const POLICY_HND *hnd, const char *key,
5013                                       uint32 size)
5014 {
5015         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5016         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5017         q_u->size = size;
5018
5019         return True;
5020 }
5021
5022 /*******************************************************************
5023 ********************************************************************/  
5024 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
5025                                    char* value, uint32 data_type, char* data, uint32 data_size)
5026 {
5027         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5028         q_u->type = data_type;
5029         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
5030
5031         q_u->max_len = q_u->real_len = data_size;
5032         q_u->data = (unsigned char *)data;
5033         
5034         return True;
5035 }
5036
5037 /*******************************************************************
5038 ********************************************************************/  
5039 bool make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY_HND *hnd,
5040                                      char *key, char* value, uint32 data_type, char* data, 
5041                                      uint32 data_size)
5042 {
5043         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5044         q_u->type = data_type;
5045         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
5046         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5047
5048         q_u->max_len = q_u->real_len = data_size;
5049         q_u->data = (unsigned char *)data;
5050         
5051         return True;
5052 }
5053
5054 /*******************************************************************
5055 ********************************************************************/  
5056
5057 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
5058 {
5059         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
5060         depth++;
5061
5062         if(!prs_align(ps))
5063                 return False;
5064         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5065                 return False;
5066         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
5067                 return False;
5068
5069         if(!prs_align(ps))
5070                 return False;
5071
5072         if(!prs_uint32("type", ps, depth, &q_u->type))
5073                 return False;
5074
5075         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
5076                 return False;
5077
5078         switch (q_u->type)
5079         {
5080                 case REG_SZ:
5081                 case REG_BINARY:
5082                 case REG_DWORD:
5083                 case REG_MULTI_SZ:
5084                         if (q_u->max_len) {
5085                                 if (UNMARSHALLING(ps))
5086                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
5087                                 if(q_u->data == NULL)
5088                                         return False;
5089                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
5090                                         return False;
5091                         }
5092                         if(!prs_align(ps))
5093                                 return False;
5094                         break;
5095         }       
5096         
5097         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
5098                 return False;
5099
5100         return True;
5101 }
5102
5103 /*******************************************************************
5104 ********************************************************************/  
5105
5106 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
5107 {
5108         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
5109         depth++;
5110
5111         if(!prs_align(ps))
5112                 return False;
5113         if(!prs_werror("status",     ps, depth, &r_u->status))
5114                 return False;
5115
5116         return True;
5117 }
5118
5119 /*******************************************************************
5120 ********************************************************************/  
5121 bool spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
5122 {
5123         prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
5124         depth++;
5125
5126         if (!prs_align(ps))
5127                 return False;
5128         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5129                 return False;
5130
5131         if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
5132                 return False;
5133                 
5134         if (q_u->datatype_ptr) {
5135                 if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
5136                 return False;
5137         }
5138
5139         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
5140                 return False;
5141
5142         return True;
5143 }
5144
5145
5146 /*******************************************************************
5147 ********************************************************************/  
5148 bool spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
5149 {
5150         prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
5151         depth++;
5152
5153         if(!prs_align(ps))
5154                 return False;
5155         if(!prs_werror("status",     ps, depth, &r_u->status))
5156                 return False;
5157
5158         return True;
5159 }
5160
5161 /*******************************************************************
5162  Parse a SPOOL_R_GETJOB structure.
5163 ********************************************************************/  
5164
5165 bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
5166 {               
5167         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
5168         depth++;
5169
5170         if (!prs_align(ps))
5171                 return False;
5172                 
5173         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5174                 return False;
5175
5176         if (!prs_align(ps))
5177                 return False;
5178                 
5179         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5180                 return False;
5181                 
5182         if (!prs_werror("status", ps, depth, &r_u->status))
5183                 return False;
5184
5185         return True;            
5186 }
5187
5188 /*******************************************************************
5189  Parse a SPOOL_Q_GETJOB structure.
5190 ********************************************************************/  
5191
5192 bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
5193 {
5194         prs_debug(ps, depth, desc, "");
5195         depth++;
5196
5197         if(!prs_align(ps))
5198                 return False;
5199
5200         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5201                 return False;
5202         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
5203                 return False;
5204         if(!prs_uint32("level", ps, depth, &q_u->level))
5205                 return False;
5206         
5207         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5208                 return False;
5209
5210         if(!prs_align(ps))
5211                 return False;
5212         
5213         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5214                 return False;
5215
5216         return True;
5217 }
5218
5219 void free_devmode(DEVICEMODE *devmode)
5220 {
5221         if (devmode!=NULL) {
5222                 SAFE_FREE(devmode->dev_private);
5223                 SAFE_FREE(devmode);
5224         }
5225 }
5226
5227 void free_printer_info_1(PRINTER_INFO_1 *printer)
5228 {
5229         SAFE_FREE(printer);
5230 }
5231
5232 void free_printer_info_2(PRINTER_INFO_2 *printer)
5233 {
5234         if (printer!=NULL) {
5235                 free_devmode(printer->devmode);
5236                 printer->devmode = NULL;
5237                 SAFE_FREE(printer);
5238         }
5239 }
5240
5241 void free_printer_info_3(PRINTER_INFO_3 *printer)
5242 {
5243         SAFE_FREE(printer);
5244 }
5245
5246 void free_printer_info_4(PRINTER_INFO_4 *printer)
5247 {
5248         SAFE_FREE(printer);
5249 }
5250
5251 void free_printer_info_5(PRINTER_INFO_5 *printer)
5252 {
5253         SAFE_FREE(printer);
5254 }
5255
5256 void free_printer_info_6(PRINTER_INFO_6 *printer)
5257 {
5258         SAFE_FREE(printer);
5259 }
5260
5261 void free_printer_info_7(PRINTER_INFO_7 *printer)
5262 {
5263         SAFE_FREE(printer);
5264 }
5265
5266 void free_job_info_2(JOB_INFO_2 *job)
5267 {
5268     if (job!=NULL)
5269         free_devmode(job->devmode);
5270 }
5271
5272 /*******************************************************************
5273  * init a structure.
5274  ********************************************************************/
5275
5276 bool make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u, 
5277                                const fstring string, uint32 printer, uint32 type)
5278 {      
5279         if (q_u == NULL)
5280                 return False;
5281
5282         init_unistr2(&q_u->string, string, UNI_STR_TERMINATE);
5283
5284         q_u->printer=printer;
5285         q_u->type=type;
5286
5287         q_u->unknown0=0x0;
5288         q_u->unknown1=0x0;
5289
5290         return True;
5291 }
5292
5293 /*******************************************************************
5294  Parse a SPOOL_Q_REPLYOPENPRINTER structure.
5295 ********************************************************************/  
5296
5297 bool spoolss_io_q_replyopenprinter(const char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
5298 {
5299         prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
5300         depth++;
5301
5302         if(!prs_align(ps))
5303                 return False;
5304
5305         if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
5306                 return False;
5307
5308         if(!prs_align(ps))
5309                 return False;
5310
5311         if(!prs_uint32("printer", ps, depth, &q_u->printer))
5312                 return False;
5313         if(!prs_uint32("type", ps, depth, &q_u->type))
5314                 return False;
5315         
5316         if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
5317                 return False;
5318         if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
5319                 return False;
5320
5321         return True;
5322 }
5323
5324 /*******************************************************************
5325  Parse a SPOOL_R_REPLYOPENPRINTER structure.
5326 ********************************************************************/  
5327
5328 bool spoolss_io_r_replyopenprinter(const char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
5329 {               
5330         prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
5331         depth++;
5332
5333         if (!prs_align(ps))
5334                 return False;
5335
5336         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
5337                 return False;
5338
5339         if (!prs_werror("status", ps, depth, &r_u->status))
5340                 return False;
5341
5342         return True;            
5343 }
5344
5345 #if 0   /* JERRY - not currently used but could be :-) */
5346
5347 /*******************************************************************
5348  Deep copy a SPOOL_NOTIFY_INFO_DATA structure
5349  ******************************************************************/
5350 static bool copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, 
5351                                 SPOOL_NOTIFY_INFO_DATA *src, int n)
5352 {
5353         int i;
5354
5355         memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
5356         
5357         for (i=0; i<n; i++) {
5358                 int len;
5359                 uint16 *s = NULL;
5360                 
5361                 if (src->size != POINTER) 
5362                         continue;
5363                 len = src->notify_data.data.length;
5364                 s = SMB_MALLOC_ARRAY(uint16, len);
5365                 if (s == NULL) {
5366                         DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
5367                         return False;
5368                 }
5369                 
5370                 memcpy(s, src->notify_data.data.string, len*2);
5371                 dst->notify_data.data.string = s;
5372         }
5373         
5374         return True;
5375 }
5376
5377 /*******************************************************************
5378  Deep copy a SPOOL_NOTIFY_INFO structure
5379  ******************************************************************/
5380 static bool copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
5381 {
5382         if (!dst) {
5383                 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
5384                 return False;
5385         }
5386                 
5387         dst->version = src->version;
5388         dst->flags   = src->flags;
5389         dst->count   = src->count;
5390         
5391         if (dst->count) 
5392         {
5393                 dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count);
5394                 
5395                 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
5396                         dst->count));
5397
5398                 if (dst->data == NULL) {
5399                         DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", 
5400                                 dst->count));
5401                         return False;
5402                 }
5403                 
5404                 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
5405         }
5406         
5407         return True;
5408 }
5409 #endif  /* JERRY */
5410
5411 /*******************************************************************
5412  * init a structure.
5413  ********************************************************************/
5414
5415 bool make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
5416                                 uint32 change_low, uint32 change_high,
5417                                 SPOOL_NOTIFY_INFO *info)
5418 {      
5419         if (q_u == NULL)
5420                 return False;
5421
5422         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5423
5424         q_u->change_low=change_low;
5425         q_u->change_high=change_high;
5426
5427         q_u->unknown0=0x0;
5428         q_u->unknown1=0x0;
5429
5430         q_u->info_ptr=0x0FF0ADDE;
5431
5432         q_u->info.version=2;
5433         
5434         if (info->count) {
5435                 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
5436                         info->count));
5437                 q_u->info.version = info->version;
5438                 q_u->info.flags   = info->flags;
5439                 q_u->info.count   = info->count;
5440                 /* pointer field - be careful! */
5441                 q_u->info.data    = info->data;
5442         }
5443         else  {
5444         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
5445         q_u->info.count=0;
5446         }
5447
5448         return True;
5449 }
5450
5451 /*******************************************************************
5452  Parse a SPOOL_Q_REPLY_RRPCN structure.
5453 ********************************************************************/  
5454
5455 bool spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
5456 {
5457         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
5458         depth++;
5459
5460         if(!prs_align(ps))
5461                 return False;
5462
5463         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5464                 return False;
5465
5466         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
5467                 return False;
5468
5469         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
5470                 return False;
5471
5472         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
5473                 return False;
5474
5475         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
5476                 return False;
5477
5478         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
5479                 return False;
5480
5481         if(q_u->info_ptr!=0)
5482                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
5483                         return False;
5484                 
5485         return True;
5486 }
5487
5488 /*******************************************************************
5489  Parse a SPOOL_R_REPLY_RRPCN structure.
5490 ********************************************************************/  
5491
5492 bool spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
5493 {               
5494         prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
5495         depth++;
5496
5497         if (!prs_align(ps))
5498                 return False;
5499
5500         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
5501                 return False;
5502
5503         if (!prs_werror("status", ps, depth, &r_u->status))
5504                 return False;
5505
5506         return True;            
5507 }
5508
5509 /*******************************************************************
5510  * read a structure.
5511  * called from spoolss_q_getprinterdataex (srv_spoolss.c)
5512  ********************************************************************/
5513
5514 bool spoolss_io_q_getprinterdataex(const char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
5515 {
5516         if (q_u == NULL)
5517                 return False;
5518
5519         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
5520         depth++;
5521
5522         if (!prs_align(ps))
5523                 return False;
5524         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5525                 return False;
5526         if (!prs_align(ps))
5527                 return False;
5528         if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
5529                 return False;
5530         if (!prs_align(ps))
5531                 return False;
5532         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
5533                 return False;
5534         if (!prs_align(ps))
5535                 return False;
5536         if (!prs_uint32("size", ps, depth, &q_u->size))
5537                 return False;
5538
5539         return True;
5540 }
5541
5542 /*******************************************************************
5543  * write a structure.
5544  * called from spoolss_r_getprinterdataex (srv_spoolss.c)
5545  ********************************************************************/
5546
5547 bool spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
5548 {
5549         if (r_u == NULL)
5550                 return False;
5551
5552         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
5553         depth++;
5554
5555         if (!prs_align(ps))
5556                 return False;
5557         if (!prs_uint32("type", ps, depth, &r_u->type))
5558                 return False;
5559         if (!prs_uint32("size", ps, depth, &r_u->size))
5560                 return False;
5561         
5562         if (UNMARSHALLING(ps) && r_u->size) {
5563                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
5564                 if(!r_u->data)
5565                         return False;
5566         }
5567
5568         if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
5569                 return False;
5570                 
5571         if (!prs_align(ps))
5572                 return False;
5573         
5574         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5575                 return False;
5576         if (!prs_werror("status", ps, depth, &r_u->status))
5577                 return False;
5578                 
5579         return True;
5580 }
5581
5582 /*******************************************************************
5583  * read a structure.
5584  ********************************************************************/  
5585
5586 bool spoolss_io_q_setprinterdataex(const char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
5587 {
5588         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
5589         depth++;
5590
5591         if(!prs_align(ps))
5592                 return False;
5593         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5594                 return False;
5595         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
5596                 return False;
5597
5598         if(!prs_align(ps))
5599                 return False;
5600
5601         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
5602                 return False;
5603
5604         if(!prs_align(ps))
5605                 return False;
5606
5607         if(!prs_uint32("type", ps, depth, &q_u->type))
5608                 return False;
5609
5610         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
5611                 return False;
5612
5613         switch (q_u->type)
5614         {
5615                 case 0x1:
5616                 case 0x3:
5617                 case 0x4:
5618                 case 0x7:
5619                         if (q_u->max_len) {
5620                                 if (UNMARSHALLING(ps))
5621                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
5622                                 if(q_u->data == NULL)
5623                                         return False;
5624                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
5625                                         return False;
5626                         }
5627                         if(!prs_align(ps))
5628                                 return False;
5629                         break;
5630         }       
5631         
5632         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
5633                 return False;
5634
5635         return True;
5636 }
5637
5638 /*******************************************************************
5639  * write a structure.
5640  ********************************************************************/  
5641
5642 bool spoolss_io_r_setprinterdataex(const char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
5643 {
5644         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
5645         depth++;
5646
5647         if(!prs_align(ps))
5648                 return False;
5649         if(!prs_werror("status",     ps, depth, &r_u->status))
5650                 return False;
5651
5652         return True;
5653 }
5654
5655 /*******************************************************************
5656  * read a structure.
5657  ********************************************************************/  
5658 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
5659                                    POLICY_HND *hnd, const char *key, 
5660                                    uint32 size)
5661 {
5662         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
5663
5664         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5665         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5666         q_u->size = size;
5667
5668         return True;
5669 }
5670
5671 /*******************************************************************
5672  * read a structure.
5673  ********************************************************************/  
5674
5675 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
5676 {
5677         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
5678         depth++;
5679
5680         if(!prs_align(ps))
5681                 return False;
5682         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5683                 return False;
5684                 
5685         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
5686                 return False;
5687
5688         if(!prs_align(ps))
5689                 return False;
5690         
5691         if(!prs_uint32("size", ps, depth, &q_u->size))
5692                 return False;
5693
5694         return True;
5695 }
5696
5697 /*******************************************************************
5698  * write a structure.
5699  ********************************************************************/  
5700
5701 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
5702 {
5703         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
5704         depth++;
5705
5706         if(!prs_align(ps))
5707                 return False;
5708
5709         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
5710                 return False;
5711         
5712         if(!prs_align(ps))
5713                 return False;
5714
5715         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
5716                 return False;
5717
5718         if(!prs_werror("status",     ps, depth, &r_u->status))
5719                 return False;
5720
5721         return True;
5722 }
5723
5724 /*******************************************************************
5725  * read a structure.
5726  ********************************************************************/  
5727
5728 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
5729 {
5730         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
5731         depth++;
5732
5733         if(!prs_align(ps))
5734                 return False;
5735         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5736                 return False;
5737                 
5738         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
5739                 return False;
5740
5741         if(!prs_align(ps))
5742                 return False;
5743         
5744         if(!prs_uint32("size", ps, depth, &q_u->size))
5745                 return False;
5746
5747         return True;
5748 }
5749
5750 /*******************************************************************
5751 ********************************************************************/  
5752
5753 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
5754                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
5755 {
5756         int     i;
5757         uint32  valuename_offset,
5758                 data_offset,
5759                 current_offset;
5760         const uint32 basic_unit = 20; /* size of static portion of enum_values */
5761
5762         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
5763         depth++;        
5764
5765         /* 
5766          * offset data begins at 20 bytes per structure * size_of_array.
5767          * Don't forget the uint32 at the beginning 
5768          * */
5769         
5770         current_offset = basic_unit * ctr->size_of_array;
5771         
5772         /* first loop to write basic enum_value information */
5773         
5774         if (UNMARSHALLING(ps) && ctr->size_of_array) {
5775                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
5776                 if (!ctr->values)
5777                         return False;
5778         }
5779
5780         for (i=0; i<ctr->size_of_array; i++) {
5781                 uint32 base_offset, return_offset;
5782
5783                 base_offset = prs_offset(ps);
5784
5785                 valuename_offset = current_offset;
5786                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
5787                         return False;
5788
5789                 /* Read or write the value. */
5790
5791                 return_offset = prs_offset(ps);
5792
5793                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
5794                         return False;
5795                 }
5796
5797                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
5798                         return False;
5799
5800                 /* And go back. */
5801                 if (!prs_set_offset(ps, return_offset))
5802                         return False;
5803
5804                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
5805                         return False;
5806         
5807                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
5808                         return False;
5809         
5810                 data_offset = ctr->values[i].value_len + valuename_offset;
5811                 
5812                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
5813                         return False;
5814
5815                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
5816                         return False;
5817                         
5818                 /* Read or write the data. */
5819
5820                 return_offset = prs_offset(ps);
5821
5822                 if (!prs_set_offset(ps, base_offset + data_offset)) {
5823                         return False;
5824                 }
5825
5826                 if ( ctr->values[i].data_len ) {
5827                         if ( UNMARSHALLING(ps) ) {
5828                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
5829                                 if (!ctr->values[i].data)
5830                                         return False;
5831                         }
5832                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
5833                                 return False;
5834                 }
5835
5836                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
5837                 /* account for 2 byte alignment */
5838                 current_offset += (current_offset % 2);
5839
5840                 /* Remember how far we got. */
5841                 data_offset = prs_offset(ps);
5842
5843                 /* And go back. */
5844                 if (!prs_set_offset(ps, return_offset))
5845                         return False;
5846
5847         }
5848
5849         /* Go to the last data offset we got to. */
5850
5851         if (!prs_set_offset(ps, data_offset))
5852                 return False;
5853
5854         /* And ensure we're 2 byte aligned. */
5855
5856         if ( !prs_align_uint16(ps) )
5857                 return False;
5858
5859         return True;    
5860 }
5861
5862 /*******************************************************************
5863  * write a structure.
5864  ********************************************************************/  
5865
5866 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
5867 {
5868         uint32 data_offset, end_offset;
5869         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
5870         depth++;
5871
5872         if(!prs_align(ps))
5873                 return False;
5874
5875         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
5876                 return False;
5877
5878         data_offset = prs_offset(ps);
5879
5880         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
5881                 return False;
5882
5883         if(!prs_align(ps))
5884                 return False;
5885
5886         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
5887                 return False;
5888
5889         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
5890                 return False;
5891
5892         if(!prs_werror("status",     ps, depth, &r_u->status))
5893                 return False;
5894
5895         r_u->ctr.size_of_array = r_u->returned;
5896
5897         end_offset = prs_offset(ps);
5898
5899         if (!prs_set_offset(ps, data_offset))
5900                 return False;
5901
5902         if (r_u->ctr.size)
5903                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
5904                         return False;
5905
5906         if (!prs_set_offset(ps, end_offset))
5907                 return False;
5908         return True;
5909 }
5910
5911 /*******************************************************************
5912  * write a structure.
5913  ********************************************************************/  
5914
5915 /* 
5916    uint32 GetPrintProcessorDirectory(
5917        [in] unistr2 *name,
5918        [in] unistr2 *environment,
5919        [in] uint32 level,
5920        [in,out] RPC_BUFFER buffer,
5921        [in] uint32 offered,
5922        [out] uint32 needed,
5923        [out] uint32 returned
5924    );
5925
5926 */
5927
5928 bool make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered)
5929 {
5930         DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
5931
5932         init_unistr2(&q_u->name, name, UNI_STR_TERMINATE);
5933         init_unistr2(&q_u->environment, environment, UNI_STR_TERMINATE);
5934
5935         q_u->level = level;
5936
5937         q_u->buffer = buffer;
5938         q_u->offered = offered;
5939
5940         return True;
5941 }
5942
5943 bool spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
5944 {
5945         uint32 ptr = 0;
5946
5947         prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
5948         depth++;
5949
5950         if(!prs_align(ps))
5951                 return False;   
5952
5953         if (!prs_uint32("ptr", ps, depth, &ptr)) 
5954                 return False;
5955
5956         if (ptr) {
5957                 if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5958                         return False;
5959         }
5960
5961         if (!prs_align(ps))
5962                 return False;
5963
5964         if (!prs_uint32("ptr", ps, depth, &ptr))
5965                 return False;
5966
5967         if (ptr) {
5968                 if(!smb_io_unistr2("environment", &q_u->environment, True, 
5969                                    ps, depth))
5970                         return False;
5971         }
5972
5973         if (!prs_align(ps))
5974                 return False;
5975
5976         if(!prs_uint32("level",   ps, depth, &q_u->level))
5977                 return False;
5978
5979         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5980                 return False;
5981         
5982         if(!prs_align(ps))
5983                 return False;
5984
5985         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5986                 return False;
5987
5988         return True;
5989 }
5990
5991 /*******************************************************************
5992  * write a structure.
5993  ********************************************************************/  
5994
5995 bool spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
5996 {
5997         prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
5998         depth++;
5999
6000         if(!prs_align(ps))
6001                 return False;
6002
6003         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
6004                 return False;
6005         
6006         if(!prs_align(ps))
6007                 return False;
6008
6009         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
6010                 return False;
6011                 
6012         if(!prs_werror("status",     ps, depth, &r_u->status))
6013                 return False;
6014
6015         return True;
6016 }
6017
6018 bool smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
6019 {
6020         prs_struct *ps=&buffer->prs;
6021
6022         prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
6023         depth++;
6024
6025         buffer->struct_start=prs_offset(ps);
6026
6027         if (!smb_io_unistr(desc, &info->name, ps, depth))
6028                 return False;
6029
6030         return True;
6031 }
6032
6033 /*******************************************************************
6034  * init a structure.
6035  ********************************************************************/
6036
6037 bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
6038                               uint32 level, RPC_BUFFER *buffer,
6039                               uint32 offered)
6040 {
6041         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
6042         q_u->level = level;
6043         q_u->buffer=buffer;
6044         q_u->offered=offered;
6045
6046         return True;
6047 }
6048
6049 /*******************************************************************
6050  * init a structure.
6051  ********************************************************************/
6052
6053 bool make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle, 
6054                            uint32 jobid, uint32 level, uint32 command)
6055 {
6056         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
6057         q_u->jobid = jobid;
6058         q_u->level = level;
6059
6060         /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
6061            the server side code has it marked as unused. */
6062
6063         q_u->command = command;
6064
6065         return True;
6066 }
6067
6068 /*******************************************************************
6069  * init a structure.
6070  ********************************************************************/
6071
6072 bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
6073                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
6074                            uint32 offered)
6075 {
6076         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
6077         q_u->jobid = jobid;
6078         q_u->level = level;
6079         q_u->buffer = buffer;
6080         q_u->offered = offered;
6081
6082         return True;
6083 }
6084
6085 /*******************************************************************
6086  * init a structure.
6087  ********************************************************************/
6088
6089 bool make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
6090                              uint32 flags, uint32 options, const char *localmachine,
6091                              uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
6092 {
6093         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
6094
6095         q_u->flags = flags;
6096         q_u->options = options;
6097
6098         q_u->localmachine_ptr = 1;
6099
6100         init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
6101
6102         q_u->printerlocal = printerlocal;
6103
6104         if (option)
6105                 q_u->option_ptr = 1;
6106
6107         q_u->option = option;
6108
6109         return True;
6110 }
6111
6112
6113 /*******************************************************************
6114  ********************************************************************/  
6115
6116 bool spoolss_io_q_xcvdataport(const char *desc, SPOOL_Q_XCVDATAPORT *q_u, prs_struct *ps, int depth)
6117 {
6118         prs_debug(ps, depth, desc, "spoolss_io_q_xcvdataport");
6119         depth++;
6120
6121         if(!prs_align(ps))
6122                 return False;   
6123
6124         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6125                 return False;
6126                 
6127         if(!smb_io_unistr2("", &q_u->dataname, True, ps, depth))
6128                 return False;
6129
6130         if (!prs_align(ps))
6131                 return False;
6132
6133         if(!prs_rpcbuffer("", ps, depth, &q_u->indata))
6134                 return False;
6135                 
6136         if (!prs_align(ps))
6137                 return False;
6138
6139         if (!prs_uint32("indata_len", ps, depth, &q_u->indata_len))
6140                 return False;
6141         if (!prs_uint32("offered", ps, depth, &q_u->offered))
6142                 return False;
6143         if (!prs_uint32("unknown", ps, depth, &q_u->unknown))
6144                 return False;
6145         
6146         return True;
6147 }
6148
6149 /*******************************************************************
6150  ********************************************************************/  
6151
6152 bool spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_struct *ps, int depth)
6153 {
6154         prs_debug(ps, depth, desc, "spoolss_io_r_xcvdataport");
6155         depth++;
6156
6157         if(!prs_align(ps))
6158                 return False;
6159         if(!prs_rpcbuffer("", ps, depth, &r_u->outdata))
6160                 return False;
6161                 
6162         if (!prs_align(ps))
6163                 return False;
6164
6165         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6166                 return False;
6167         if (!prs_uint32("unknown", ps, depth, &r_u->unknown))
6168                 return False;
6169
6170         if(!prs_werror("status", ps, depth, &r_u->status))
6171                 return False;
6172
6173         return True;
6174 }
6175
6176 /*******************************************************************
6177  ********************************************************************/  
6178
6179 bool make_monitorui_buf( RPC_BUFFER *buf, const char *dllname )
6180 {
6181         UNISTR string;
6182         
6183         if ( !buf )
6184                 return False;
6185
6186         init_unistr( &string, dllname );
6187
6188         if ( !prs_unistr( "ui_dll", &buf->prs, 0, &string ) )
6189                 return False;
6190
6191         return True;
6192 }
6193
6194 /*******************************************************************
6195  ********************************************************************/  
6196  
6197 #define PORT_DATA_1_PAD    540
6198
6199 static bool smb_io_port_data_1( const char *desc, RPC_BUFFER *buf, int depth, SPOOL_PORT_DATA_1 *p1 )
6200 {
6201         prs_struct *ps = &buf->prs;
6202         uint8 padding[PORT_DATA_1_PAD];
6203
6204         prs_debug(ps, depth, desc, "smb_io_port_data_1");
6205         depth++;
6206
6207         if(!prs_align(ps))
6208                 return False;   
6209
6210         if( !prs_uint16s(True, "portname", ps, depth, p1->portname, MAX_PORTNAME))
6211                 return False;
6212
6213         if (!prs_uint32("version", ps, depth, &p1->version))
6214                 return False;
6215         if (!prs_uint32("protocol", ps, depth, &p1->protocol))
6216                 return False;
6217         if (!prs_uint32("size", ps, depth, &p1->size))
6218                 return False;
6219         if (!prs_uint32("reserved", ps, depth, &p1->reserved))
6220                 return False;
6221
6222         if( !prs_uint16s(True, "hostaddress", ps, depth, p1->hostaddress, MAX_NETWORK_NAME))
6223                 return False;
6224         if( !prs_uint16s(True, "snmpcommunity", ps, depth, p1->snmpcommunity, MAX_SNMP_COMM_NAME))
6225                 return False;
6226
6227         if (!prs_uint32("dblspool", ps, depth, &p1->dblspool))
6228                 return False;
6229                 
6230         if( !prs_uint16s(True, "queue", ps, depth, p1->queue, MAX_QUEUE_NAME))
6231                 return False;
6232         if( !prs_uint16s(True, "ipaddress", ps, depth, p1->ipaddress, MAX_IPADDR_STRING))
6233                 return False;
6234
6235         if( !prs_uint8s(False, "", ps, depth, padding, PORT_DATA_1_PAD))
6236                 return False;
6237                 
6238         if (!prs_uint32("port", ps, depth, &p1->port))
6239                 return False;
6240         if (!prs_uint32("snmpenabled", ps, depth, &p1->snmpenabled))
6241                 return False;
6242         if (!prs_uint32("snmpdevindex", ps, depth, &p1->snmpdevindex))
6243                 return False;
6244                 
6245         return True;
6246 }
6247
6248 /*******************************************************************
6249  ********************************************************************/  
6250
6251 bool convert_port_data_1( NT_PORT_DATA_1 *port1, RPC_BUFFER *buf ) 
6252 {
6253         SPOOL_PORT_DATA_1 spdata_1;
6254         
6255         ZERO_STRUCT( spdata_1 );
6256         
6257         if ( !smb_io_port_data_1( "port_data_1", buf, 0, &spdata_1 ) )
6258                 return False;
6259                 
6260         rpcstr_pull(port1->name, spdata_1.portname, sizeof(port1->name), -1, 0);
6261         rpcstr_pull(port1->queue, spdata_1.queue, sizeof(port1->queue), -1, 0);
6262         rpcstr_pull(port1->hostaddr, spdata_1.hostaddress, sizeof(port1->hostaddr), -1, 0);
6263         
6264         port1->port = spdata_1.port;
6265         
6266         switch ( spdata_1.protocol ) {
6267         case 1:
6268                 port1->protocol = PORT_PROTOCOL_DIRECT;
6269                 break;
6270         case 2:
6271                 port1->protocol = PORT_PROTOCOL_LPR;
6272                 break;
6273         default:
6274                 DEBUG(3,("convert_port_data_1: unknown protocol [%d]!\n", 
6275                         spdata_1.protocol));
6276                 return False;
6277         }
6278
6279         return True;
6280 }